2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST /* last tag */
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
110 ALC262_MODEL_LAST /* last tag */
120 ALC268_ACER_ASPIRE_ONE,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST /* last tag */
134 ALC269_ASUS_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
139 ALC269_MODEL_LAST /* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
220 ALC883_TARGA_2ch_DIG,
223 ALC888_ACER_ASPIRE_4930G,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
236 ALC883_FUJITSU_PI2515,
237 ALC888_FUJITSU_XA3530,
238 ALC883_3ST_6ch_INTEL,
246 /* styles of capture selection */
248 CAPT_MUX = 0, /* only mux based */
249 CAPT_MIX, /* only mixer based */
250 CAPT_1MUX_MIX, /* first mux and other mixers */
254 #define GPIO_MASK 0x03
257 /* codec parameterization */
258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
259 unsigned int num_mixers;
260 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
261 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
263 const struct hda_verb *init_verbs[5]; /* initialization verbs
267 unsigned int num_init_verbs;
269 char *stream_name_analog; /* analog PCM stream */
270 struct hda_pcm_stream *stream_analog_playback;
271 struct hda_pcm_stream *stream_analog_capture;
272 struct hda_pcm_stream *stream_analog_alt_playback;
273 struct hda_pcm_stream *stream_analog_alt_capture;
275 char *stream_name_digital; /* digital PCM stream */
276 struct hda_pcm_stream *stream_digital_playback;
277 struct hda_pcm_stream *stream_digital_capture;
280 struct hda_multi_out multiout; /* playback set-up
281 * max_channels, dacs must be set
282 * dig_out_nid and hp_nid are optional
284 hda_nid_t alt_dac_nid;
285 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
289 unsigned int num_adc_nids;
291 hda_nid_t *capsrc_nids;
292 hda_nid_t dig_in_nid; /* digital-in NID; optional */
293 int capture_style; /* capture style (CAPT_*) */
296 unsigned int num_mux_defs;
297 const struct hda_input_mux *input_mux;
298 unsigned int cur_mux[3];
301 const struct hda_channel_mode *channel_mode;
302 int num_channel_mode;
305 /* PCM information */
306 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
308 /* dynamic controls, init_verbs and input_mux */
309 struct auto_pin_cfg autocfg;
310 struct snd_array kctls;
311 struct hda_input_mux private_imux[3];
312 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
315 void (*init_hook)(struct hda_codec *codec);
316 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
318 /* for pin sensing */
319 unsigned int sense_updated: 1;
320 unsigned int jack_present: 1;
321 unsigned int master_sw: 1;
324 unsigned int no_analog :1; /* digital I/O only */
326 /* for virtual master */
327 hda_nid_t vmaster_nid;
328 #ifdef CONFIG_SND_HDA_POWER_SAVE
329 struct hda_loopback_check loopback;
334 unsigned int pll_coef_idx, pll_coef_bit;
338 * configuration template - to be copied to the spec instance
340 struct alc_config_preset {
341 struct snd_kcontrol_new *mixers[5]; /* should be identical size
344 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
345 const struct hda_verb *init_verbs[5];
346 unsigned int num_dacs;
348 hda_nid_t dig_out_nid; /* optional */
349 hda_nid_t hp_nid; /* optional */
350 hda_nid_t *slave_dig_outs;
351 unsigned int num_adc_nids;
353 hda_nid_t *capsrc_nids;
354 hda_nid_t dig_in_nid;
355 unsigned int num_channel_mode;
356 const struct hda_channel_mode *channel_mode;
358 unsigned int num_mux_defs;
359 const struct hda_input_mux *input_mux;
360 void (*unsol_event)(struct hda_codec *, unsigned int);
361 void (*init_hook)(struct hda_codec *);
362 #ifdef CONFIG_SND_HDA_POWER_SAVE
363 struct hda_amp_list *loopbacks;
371 static int alc_mux_enum_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 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
377 if (mux_idx >= spec->num_mux_defs)
379 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
382 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
383 struct snd_ctl_elem_value *ucontrol)
385 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
386 struct alc_spec *spec = codec->spec;
387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
389 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
393 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
396 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
397 struct alc_spec *spec = codec->spec;
398 const struct hda_input_mux *imux;
399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
400 unsigned int mux_idx;
401 hda_nid_t nid = spec->capsrc_nids ?
402 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
404 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
405 imux = &spec->input_mux[mux_idx];
407 if (spec->capture_style &&
408 !(spec->capture_style == CAPT_1MUX_MIX && !adc_idx)) {
409 /* Matrix-mixer style (e.g. ALC882) */
410 unsigned int *cur_val = &spec->cur_mux[adc_idx];
413 idx = ucontrol->value.enumerated.item[0];
414 if (idx >= imux->num_items)
415 idx = imux->num_items - 1;
418 for (i = 0; i < imux->num_items; i++) {
419 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
420 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
421 imux->items[i].index,
427 /* MUX style (e.g. ALC880) */
428 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
429 &spec->cur_mux[adc_idx]);
434 * channel mode setting
436 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_info *uinfo)
439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440 struct alc_spec *spec = codec->spec;
441 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
442 spec->num_channel_mode);
445 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
449 struct alc_spec *spec = codec->spec;
450 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
451 spec->num_channel_mode,
452 spec->multiout.max_channels);
455 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
456 struct snd_ctl_elem_value *ucontrol)
458 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
459 struct alc_spec *spec = codec->spec;
460 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
461 spec->num_channel_mode,
462 &spec->multiout.max_channels);
463 if (err >= 0 && spec->need_dac_fix)
464 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
469 * Control the mode of pin widget settings via the mixer. "pc" is used
470 * instead of "%" to avoid consequences of accidently treating the % as
471 * being part of a format specifier. Maximum allowed length of a value is
472 * 63 characters plus NULL terminator.
474 * Note: some retasking pin complexes seem to ignore requests for input
475 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
476 * are requested. Therefore order this list so that this behaviour will not
477 * cause problems when mixer clients move through the enum sequentially.
478 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
481 static char *alc_pin_mode_names[] = {
482 "Mic 50pc bias", "Mic 80pc bias",
483 "Line in", "Line out", "Headphone out",
485 static unsigned char alc_pin_mode_values[] = {
486 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
488 /* The control can present all 5 options, or it can limit the options based
489 * in the pin being assumed to be exclusively an input or an output pin. In
490 * addition, "input" pins may or may not process the mic bias option
491 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
492 * accept requests for bias as of chip versions up to March 2006) and/or
493 * wiring in the computer.
495 #define ALC_PIN_DIR_IN 0x00
496 #define ALC_PIN_DIR_OUT 0x01
497 #define ALC_PIN_DIR_INOUT 0x02
498 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
499 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
501 /* Info about the pin modes supported by the different pin direction modes.
502 * For each direction the minimum and maximum values are given.
504 static signed char alc_pin_mode_dir_info[5][2] = {
505 { 0, 2 }, /* ALC_PIN_DIR_IN */
506 { 3, 4 }, /* ALC_PIN_DIR_OUT */
507 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
508 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
509 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
511 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
512 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
513 #define alc_pin_mode_n_items(_dir) \
514 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
516 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_info *uinfo)
519 unsigned int item_num = uinfo->value.enumerated.item;
520 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
522 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
524 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
526 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
527 item_num = alc_pin_mode_min(dir);
528 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
532 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
537 hda_nid_t nid = kcontrol->private_value & 0xffff;
538 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
539 long *valp = ucontrol->value.integer.value;
540 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
541 AC_VERB_GET_PIN_WIDGET_CONTROL,
544 /* Find enumerated value for current pinctl setting */
545 i = alc_pin_mode_min(dir);
546 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
548 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
552 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 hda_nid_t nid = kcontrol->private_value & 0xffff;
558 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
559 long val = *ucontrol->value.integer.value;
560 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
561 AC_VERB_GET_PIN_WIDGET_CONTROL,
564 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
565 val = alc_pin_mode_min(dir);
567 change = pinctl != alc_pin_mode_values[val];
569 /* Set pin mode to that requested */
570 snd_hda_codec_write_cache(codec, nid, 0,
571 AC_VERB_SET_PIN_WIDGET_CONTROL,
572 alc_pin_mode_values[val]);
574 /* Also enable the retasking pin's input/output as required
575 * for the requested pin mode. Enum values of 2 or less are
578 * Dynamically switching the input/output buffers probably
579 * reduces noise slightly (particularly on input) so we'll
580 * do it. However, having both input and output buffers
581 * enabled simultaneously doesn't seem to be problematic if
582 * this turns out to be necessary in the future.
585 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
586 HDA_AMP_MUTE, HDA_AMP_MUTE);
587 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
590 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
591 HDA_AMP_MUTE, HDA_AMP_MUTE);
592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
599 #define ALC_PIN_MODE(xname, nid, dir) \
600 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
601 .info = alc_pin_mode_info, \
602 .get = alc_pin_mode_get, \
603 .put = alc_pin_mode_put, \
604 .private_value = nid | (dir<<16) }
606 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
607 * together using a mask with more than one bit set. This control is
608 * currently used only by the ALC260 test model. At this stage they are not
609 * needed for any "production" models.
611 #ifdef CONFIG_SND_DEBUG
612 #define alc_gpio_data_info snd_ctl_boolean_mono_info
614 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
615 struct snd_ctl_elem_value *ucontrol)
617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
618 hda_nid_t nid = kcontrol->private_value & 0xffff;
619 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
620 long *valp = ucontrol->value.integer.value;
621 unsigned int val = snd_hda_codec_read(codec, nid, 0,
622 AC_VERB_GET_GPIO_DATA, 0x00);
624 *valp = (val & mask) != 0;
627 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_value *ucontrol)
631 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
632 hda_nid_t nid = kcontrol->private_value & 0xffff;
633 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
634 long val = *ucontrol->value.integer.value;
635 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
636 AC_VERB_GET_GPIO_DATA,
639 /* Set/unset the masked GPIO bit(s) as needed */
640 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
645 snd_hda_codec_write_cache(codec, nid, 0,
646 AC_VERB_SET_GPIO_DATA, gpio_data);
650 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
651 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
652 .info = alc_gpio_data_info, \
653 .get = alc_gpio_data_get, \
654 .put = alc_gpio_data_put, \
655 .private_value = nid | (mask<<16) }
656 #endif /* CONFIG_SND_DEBUG */
658 /* A switch control to allow the enabling of the digital IO pins on the
659 * ALC260. This is incredibly simplistic; the intention of this control is
660 * to provide something in the test model allowing digital outputs to be
661 * identified if present. If models are found which can utilise these
662 * outputs a more complete mixer control can be devised for those models if
665 #ifdef CONFIG_SND_DEBUG
666 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
668 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_value *ucontrol)
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672 hda_nid_t nid = kcontrol->private_value & 0xffff;
673 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
674 long *valp = ucontrol->value.integer.value;
675 unsigned int val = snd_hda_codec_read(codec, nid, 0,
676 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
678 *valp = (val & mask) != 0;
681 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
682 struct snd_ctl_elem_value *ucontrol)
685 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
686 hda_nid_t nid = kcontrol->private_value & 0xffff;
687 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
688 long val = *ucontrol->value.integer.value;
689 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
690 AC_VERB_GET_DIGI_CONVERT_1,
693 /* Set/unset the masked control bit(s) as needed */
694 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
699 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
704 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
705 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
706 .info = alc_spdif_ctrl_info, \
707 .get = alc_spdif_ctrl_get, \
708 .put = alc_spdif_ctrl_put, \
709 .private_value = nid | (mask<<16) }
710 #endif /* CONFIG_SND_DEBUG */
712 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
713 * Again, this is only used in the ALC26x test models to help identify when
714 * the EAPD line must be asserted for features to work.
716 #ifdef CONFIG_SND_DEBUG
717 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
719 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
720 struct snd_ctl_elem_value *ucontrol)
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long *valp = ucontrol->value.integer.value;
726 unsigned int val = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
729 *valp = (val & mask) != 0;
733 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
734 struct snd_ctl_elem_value *ucontrol)
737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
738 hda_nid_t nid = kcontrol->private_value & 0xffff;
739 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
740 long val = *ucontrol->value.integer.value;
741 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
742 AC_VERB_GET_EAPD_BTLENABLE,
745 /* Set/unset the masked control bit(s) as needed */
746 change = (!val ? 0 : mask) != (ctrl_data & mask);
751 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
757 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
758 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
759 .info = alc_eapd_ctrl_info, \
760 .get = alc_eapd_ctrl_get, \
761 .put = alc_eapd_ctrl_put, \
762 .private_value = nid | (mask<<16) }
763 #endif /* CONFIG_SND_DEBUG */
766 * set up the input pin config (depending on the given auto-pin type)
768 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
771 unsigned int val = PIN_IN;
773 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
775 pincap = snd_hda_query_pin_caps(codec, nid);
776 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
777 if (pincap & AC_PINCAP_VREF_80)
779 else if (pincap & AC_PINCAP_VREF_50)
781 else if (pincap & AC_PINCAP_VREF_100)
783 else if (pincap & AC_PINCAP_VREF_GRD)
786 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
791 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
793 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
795 spec->mixers[spec->num_mixers++] = mix;
798 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
800 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
802 spec->init_verbs[spec->num_init_verbs++] = verb;
805 #ifdef CONFIG_PROC_FS
809 static void print_realtek_coef(struct snd_info_buffer *buffer,
810 struct hda_codec *codec, hda_nid_t nid)
816 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
817 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
818 coeff = snd_hda_codec_read(codec, nid, 0,
819 AC_VERB_GET_COEF_INDEX, 0);
820 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
823 #define print_realtek_coef NULL
827 * set up from the preset table
829 static void setup_preset(struct alc_spec *spec,
830 const struct alc_config_preset *preset)
834 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
835 add_mixer(spec, preset->mixers[i]);
836 spec->cap_mixer = preset->cap_mixer;
837 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
839 add_verb(spec, preset->init_verbs[i]);
841 spec->channel_mode = preset->channel_mode;
842 spec->num_channel_mode = preset->num_channel_mode;
843 spec->need_dac_fix = preset->need_dac_fix;
845 spec->multiout.max_channels = spec->channel_mode[0].channels;
847 spec->multiout.num_dacs = preset->num_dacs;
848 spec->multiout.dac_nids = preset->dac_nids;
849 spec->multiout.dig_out_nid = preset->dig_out_nid;
850 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
851 spec->multiout.hp_nid = preset->hp_nid;
853 spec->num_mux_defs = preset->num_mux_defs;
854 if (!spec->num_mux_defs)
855 spec->num_mux_defs = 1;
856 spec->input_mux = preset->input_mux;
858 spec->num_adc_nids = preset->num_adc_nids;
859 spec->adc_nids = preset->adc_nids;
860 spec->capsrc_nids = preset->capsrc_nids;
861 spec->dig_in_nid = preset->dig_in_nid;
863 spec->unsol_event = preset->unsol_event;
864 spec->init_hook = preset->init_hook;
865 #ifdef CONFIG_SND_HDA_POWER_SAVE
866 spec->loopback.amplist = preset->loopbacks;
870 /* Enable GPIO mask and set output */
871 static struct hda_verb alc_gpio1_init_verbs[] = {
872 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
873 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
874 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
878 static struct hda_verb alc_gpio2_init_verbs[] = {
879 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
880 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
881 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
885 static struct hda_verb alc_gpio3_init_verbs[] = {
886 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
887 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
888 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
893 * Fix hardware PLL issue
894 * On some codecs, the analog PLL gating control must be off while
895 * the default value is 1.
897 static void alc_fix_pll(struct hda_codec *codec)
899 struct alc_spec *spec = codec->spec;
904 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
906 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
907 AC_VERB_GET_PROC_COEF, 0);
908 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
910 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
911 val & ~(1 << spec->pll_coef_bit));
914 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
915 unsigned int coef_idx, unsigned int coef_bit)
917 struct alc_spec *spec = codec->spec;
919 spec->pll_coef_idx = coef_idx;
920 spec->pll_coef_bit = coef_bit;
924 static void alc_sku_automute(struct hda_codec *codec)
926 struct alc_spec *spec = codec->spec;
927 unsigned int present;
928 unsigned int hp_nid = spec->autocfg.hp_pins[0];
929 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
931 /* need to execute and sync at first */
932 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
933 present = snd_hda_codec_read(codec, hp_nid, 0,
934 AC_VERB_GET_PIN_SENSE, 0);
935 spec->jack_present = (present & 0x80000000) != 0;
936 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
937 spec->jack_present ? 0 : PIN_OUT);
940 #if 0 /* it's broken in some acses -- temporarily disabled */
941 static void alc_mic_automute(struct hda_codec *codec)
943 struct alc_spec *spec = codec->spec;
944 unsigned int present;
945 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
946 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
947 unsigned int mix_nid = spec->capsrc_nids[0];
948 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
950 capsrc_idx_mic = mic_nid - 0x18;
951 capsrc_idx_fmic = fmic_nid - 0x18;
952 present = snd_hda_codec_read(codec, mic_nid, 0,
953 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
954 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
955 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
956 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
957 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
958 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
959 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
962 #define alc_mic_automute(codec) do {} while(0) /* NOP */
963 #endif /* disabled */
965 /* unsolicited event for HP jack sensing */
966 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
968 if (codec->vendor_id == 0x10ec0880)
972 if (res == ALC880_HP_EVENT)
973 alc_sku_automute(codec);
975 if (res == ALC880_MIC_EVENT)
976 alc_mic_automute(codec);
979 static void alc_inithook(struct hda_codec *codec)
981 alc_sku_automute(codec);
982 alc_mic_automute(codec);
985 /* additional initialization for ALC888 variants */
986 static void alc888_coef_init(struct hda_codec *codec)
990 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
991 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
992 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
993 if ((tmp & 0xf0) == 0x20)
995 snd_hda_codec_read(codec, 0x20, 0,
996 AC_VERB_SET_PROC_COEF, 0x830);
999 snd_hda_codec_read(codec, 0x20, 0,
1000 AC_VERB_SET_PROC_COEF, 0x3030);
1003 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1004 * 31 ~ 16 : Manufacture ID
1006 * 7 ~ 0 : Assembly ID
1007 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1009 static void alc_subsystem_id(struct hda_codec *codec,
1010 unsigned int porta, unsigned int porte,
1013 unsigned int ass, tmp, i;
1015 struct alc_spec *spec = codec->spec;
1017 ass = codec->subsystem_id & 0xffff;
1018 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1022 * 31~30 : port conetcivity
1025 * 19~16 : Check sum (15:1)
1030 if (codec->vendor_id == 0x10ec0260)
1032 ass = snd_hda_codec_get_pincfg(codec, nid);
1033 if (!(ass & 1) && !(ass & 0x100000))
1035 if ((ass >> 30) != 1) /* no physical connection */
1040 for (i = 1; i < 16; i++) {
1044 if (((ass >> 16) & 0xf) != tmp)
1050 * 2 : 0 --> Desktop, 1 --> Laptop
1051 * 3~5 : External Amplifier control
1054 tmp = (ass & 0x38) >> 3; /* external Amp control */
1057 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1060 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1063 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1065 case 5: /* set EAPD output high */
1066 switch (codec->vendor_id) {
1068 snd_hda_codec_write(codec, 0x0f, 0,
1069 AC_VERB_SET_EAPD_BTLENABLE, 2);
1070 snd_hda_codec_write(codec, 0x10, 0,
1071 AC_VERB_SET_EAPD_BTLENABLE, 2);
1083 snd_hda_codec_write(codec, 0x14, 0,
1084 AC_VERB_SET_EAPD_BTLENABLE, 2);
1085 snd_hda_codec_write(codec, 0x15, 0,
1086 AC_VERB_SET_EAPD_BTLENABLE, 2);
1089 switch (codec->vendor_id) {
1091 snd_hda_codec_write(codec, 0x1a, 0,
1092 AC_VERB_SET_COEF_INDEX, 7);
1093 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1094 AC_VERB_GET_PROC_COEF, 0);
1095 snd_hda_codec_write(codec, 0x1a, 0,
1096 AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x1a, 0,
1098 AC_VERB_SET_PROC_COEF,
1108 snd_hda_codec_write(codec, 0x20, 0,
1109 AC_VERB_SET_COEF_INDEX, 7);
1110 tmp = snd_hda_codec_read(codec, 0x20, 0,
1111 AC_VERB_GET_PROC_COEF, 0);
1112 snd_hda_codec_write(codec, 0x20, 0,
1113 AC_VERB_SET_COEF_INDEX, 7);
1114 snd_hda_codec_write(codec, 0x20, 0,
1115 AC_VERB_SET_PROC_COEF,
1119 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1123 snd_hda_codec_write(codec, 0x20, 0,
1124 AC_VERB_SET_COEF_INDEX, 7);
1125 tmp = snd_hda_codec_read(codec, 0x20, 0,
1126 AC_VERB_GET_PROC_COEF, 0);
1127 snd_hda_codec_write(codec, 0x20, 0,
1128 AC_VERB_SET_COEF_INDEX, 7);
1129 snd_hda_codec_write(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF,
1138 /* is laptop or Desktop and enable the function "Mute internal speaker
1139 * when the external headphone out jack is plugged"
1141 if (!(ass & 0x8000))
1144 * 10~8 : Jack location
1145 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1147 * 15 : 1 --> enable the function "Mute internal speaker
1148 * when the external headphone out jack is plugged"
1150 if (!spec->autocfg.speaker_pins[0]) {
1151 if (spec->autocfg.line_out_pins[0])
1152 spec->autocfg.speaker_pins[0] =
1153 spec->autocfg.line_out_pins[0];
1158 if (!spec->autocfg.hp_pins[0]) {
1159 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1161 spec->autocfg.hp_pins[0] = porta;
1163 spec->autocfg.hp_pins[0] = porte;
1165 spec->autocfg.hp_pins[0] = portd;
1169 if (spec->autocfg.hp_pins[0])
1170 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1171 AC_VERB_SET_UNSOLICITED_ENABLE,
1172 AC_USRSP_EN | ALC880_HP_EVENT);
1174 #if 0 /* it's broken in some acses -- temporarily disabled */
1175 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1176 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1177 snd_hda_codec_write(codec,
1178 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1179 AC_VERB_SET_UNSOLICITED_ENABLE,
1180 AC_USRSP_EN | ALC880_MIC_EVENT);
1181 #endif /* disabled */
1183 spec->unsol_event = alc_sku_unsol_event;
1187 * Fix-up pin default configurations
1195 static void alc_fix_pincfg(struct hda_codec *codec,
1196 const struct snd_pci_quirk *quirk,
1197 const struct alc_pincfg **pinfix)
1199 const struct alc_pincfg *cfg;
1201 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1205 cfg = pinfix[quirk->value];
1206 for (; cfg->nid; cfg++)
1207 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1217 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1218 /* Mic-in jack as mic in */
1219 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1220 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1221 /* Line-in jack as Line in */
1222 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1223 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1224 /* Line-Out as Front */
1225 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1232 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1233 /* Mic-in jack as mic in */
1234 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1235 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1236 /* Line-in jack as Surround */
1237 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1238 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1239 /* Line-Out as Front */
1240 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1247 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1248 /* Mic-in jack as CLFE */
1249 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1250 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1251 /* Line-in jack as Surround */
1252 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1253 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1254 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1255 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1262 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1263 /* Mic-in jack as CLFE */
1264 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1265 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1266 /* Line-in jack as Surround */
1267 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1268 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1269 /* Line-Out as Side */
1270 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1274 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1275 { 2, alc888_4ST_ch2_intel_init },
1276 { 4, alc888_4ST_ch4_intel_init },
1277 { 6, alc888_4ST_ch6_intel_init },
1278 { 8, alc888_4ST_ch8_intel_init },
1282 * ALC888 Fujitsu Siemens Amillo xa3530
1285 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1286 /* Front Mic: set to PIN_IN (empty by default) */
1287 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1288 /* Connect Internal HP to Front */
1289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1291 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1292 /* Connect Bass HP to Front */
1293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1294 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1296 /* Connect Line-Out side jack (SPDIF) to Side */
1297 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1298 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1299 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1300 /* Connect Mic jack to CLFE */
1301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1303 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1304 /* Connect Line-in jack to Surround */
1305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1307 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1308 /* Connect HP out jack to Front */
1309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1310 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1311 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1312 /* Enable unsolicited event for HP jack and Line-out jack */
1313 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1314 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1318 static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1320 unsigned int present;
1322 /* Line out presence */
1323 present = snd_hda_codec_read(codec, 0x17, 0,
1324 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1325 /* HP out presence */
1326 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1327 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1328 bits = present ? HDA_AMP_MUTE : 0;
1329 /* Toggle internal speakers muting */
1330 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1331 HDA_AMP_MUTE, bits);
1332 /* Toggle internal bass muting */
1333 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1334 HDA_AMP_MUTE, bits);
1337 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1340 if (res >> 26 == ALC880_HP_EVENT)
1341 alc888_fujitsu_xa3530_automute(codec);
1346 * ALC888 Acer Aspire 4930G model
1349 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1350 /* Front Mic: set to PIN_IN (empty by default) */
1351 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1352 /* Unselect Front Mic by default in input mixer 3 */
1353 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1354 /* Enable unsolicited event for HP jack */
1355 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1356 /* Connect Internal HP to front */
1357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1358 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1359 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1360 /* Connect HP out to front */
1361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1362 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1363 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1367 static struct hda_input_mux alc888_2_capture_sources[2] = {
1368 /* Front mic only available on one ADC */
1375 { "Front Mic", 0xb },
1388 static struct snd_kcontrol_new alc888_base_mixer[] = {
1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1390 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1391 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1392 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1393 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1395 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1396 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1397 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1398 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1399 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1410 static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1412 unsigned int present;
1414 present = snd_hda_codec_read(codec, 0x15, 0,
1415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1416 bits = present ? HDA_AMP_MUTE : 0;
1417 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1418 HDA_AMP_MUTE, bits);
1421 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1424 if (res >> 26 == ALC880_HP_EVENT)
1425 alc888_acer_aspire_4930g_automute(codec);
1429 * ALC880 3-stack model
1431 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1432 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1433 * F-Mic = 0x1b, HP = 0x19
1436 static hda_nid_t alc880_dac_nids[4] = {
1437 /* front, rear, clfe, rear_surr */
1438 0x02, 0x05, 0x04, 0x03
1441 static hda_nid_t alc880_adc_nids[3] = {
1446 /* The datasheet says the node 0x07 is connected from inputs,
1447 * but it shows zero connection in the real implementation on some devices.
1448 * Note: this is a 915GAV bug, fixed on 915GLV
1450 static hda_nid_t alc880_adc_nids_alt[2] = {
1455 #define ALC880_DIGOUT_NID 0x06
1456 #define ALC880_DIGIN_NID 0x0a
1458 static struct hda_input_mux alc880_capture_source = {
1462 { "Front Mic", 0x3 },
1468 /* channel source setting (2/6 channel selection for 3-stack) */
1470 static struct hda_verb alc880_threestack_ch2_init[] = {
1471 /* set line-in to input, mute it */
1472 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1473 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1474 /* set mic-in to input vref 80%, mute it */
1475 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1476 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1481 static struct hda_verb alc880_threestack_ch6_init[] = {
1482 /* set line-in to output, unmute it */
1483 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1484 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1485 /* set mic-in to output, unmute it */
1486 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1487 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1491 static struct hda_channel_mode alc880_threestack_modes[2] = {
1492 { 2, alc880_threestack_ch2_init },
1493 { 6, alc880_threestack_ch6_init },
1496 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1497 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1498 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1499 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1500 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1501 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1502 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1503 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1504 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1505 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1506 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1511 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = "Channel Mode",
1517 .info = alc_ch_mode_info,
1518 .get = alc_ch_mode_get,
1519 .put = alc_ch_mode_put,
1524 /* capture mixer elements */
1525 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1526 struct snd_ctl_elem_info *uinfo)
1528 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1529 struct alc_spec *spec = codec->spec;
1532 mutex_lock(&codec->control_mutex);
1533 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1535 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1536 mutex_unlock(&codec->control_mutex);
1540 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1541 unsigned int size, unsigned int __user *tlv)
1543 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1544 struct alc_spec *spec = codec->spec;
1547 mutex_lock(&codec->control_mutex);
1548 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1550 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1551 mutex_unlock(&codec->control_mutex);
1555 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1556 struct snd_ctl_elem_value *ucontrol);
1558 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1559 struct snd_ctl_elem_value *ucontrol,
1562 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1563 struct alc_spec *spec = codec->spec;
1564 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1567 mutex_lock(&codec->control_mutex);
1568 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1570 err = func(kcontrol, ucontrol);
1571 mutex_unlock(&codec->control_mutex);
1575 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1576 struct snd_ctl_elem_value *ucontrol)
1578 return alc_cap_getput_caller(kcontrol, ucontrol,
1579 snd_hda_mixer_amp_volume_get);
1582 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1583 struct snd_ctl_elem_value *ucontrol)
1585 return alc_cap_getput_caller(kcontrol, ucontrol,
1586 snd_hda_mixer_amp_volume_put);
1589 /* capture mixer elements */
1590 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1592 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1593 struct snd_ctl_elem_value *ucontrol)
1595 return alc_cap_getput_caller(kcontrol, ucontrol,
1596 snd_hda_mixer_amp_switch_get);
1599 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1600 struct snd_ctl_elem_value *ucontrol)
1602 return alc_cap_getput_caller(kcontrol, ucontrol,
1603 snd_hda_mixer_amp_switch_put);
1606 #define _DEFINE_CAPMIX(num) \
1608 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1609 .name = "Capture Switch", \
1610 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1612 .info = alc_cap_sw_info, \
1613 .get = alc_cap_sw_get, \
1614 .put = alc_cap_sw_put, \
1617 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1618 .name = "Capture Volume", \
1619 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1620 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1621 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1623 .info = alc_cap_vol_info, \
1624 .get = alc_cap_vol_get, \
1625 .put = alc_cap_vol_put, \
1626 .tlv = { .c = alc_cap_vol_tlv }, \
1629 #define _DEFINE_CAPSRC(num) \
1631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1632 /* .name = "Capture Source", */ \
1633 .name = "Input Source", \
1635 .info = alc_mux_enum_info, \
1636 .get = alc_mux_enum_get, \
1637 .put = alc_mux_enum_put, \
1640 #define DEFINE_CAPMIX(num) \
1641 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1642 _DEFINE_CAPMIX(num), \
1643 _DEFINE_CAPSRC(num), \
1647 #define DEFINE_CAPMIX_NOSRC(num) \
1648 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1649 _DEFINE_CAPMIX(num), \
1653 /* up to three ADCs */
1657 DEFINE_CAPMIX_NOSRC(1);
1658 DEFINE_CAPMIX_NOSRC(2);
1659 DEFINE_CAPMIX_NOSRC(3);
1662 * ALC880 5-stack model
1664 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1666 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1667 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1670 /* additional mixers to alc880_three_stack_mixer */
1671 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1672 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1673 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1677 /* channel source setting (6/8 channel selection for 5-stack) */
1679 static struct hda_verb alc880_fivestack_ch6_init[] = {
1680 /* set line-in to input, mute it */
1681 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1682 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1687 static struct hda_verb alc880_fivestack_ch8_init[] = {
1688 /* set line-in to output, unmute it */
1689 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1690 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1694 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1695 { 6, alc880_fivestack_ch6_init },
1696 { 8, alc880_fivestack_ch8_init },
1701 * ALC880 6-stack model
1703 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1704 * Side = 0x05 (0x0f)
1705 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1706 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1709 static hda_nid_t alc880_6st_dac_nids[4] = {
1710 /* front, rear, clfe, rear_surr */
1711 0x02, 0x03, 0x04, 0x05
1714 static struct hda_input_mux alc880_6stack_capture_source = {
1718 { "Front Mic", 0x1 },
1724 /* fixed 8-channels */
1725 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1729 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1730 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1731 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1732 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1733 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1734 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1735 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1736 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1737 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1738 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1739 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1740 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1741 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1742 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1743 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1746 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1747 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "Channel Mode",
1751 .info = alc_ch_mode_info,
1752 .get = alc_ch_mode_get,
1753 .put = alc_ch_mode_put,
1762 * W810 has rear IO for:
1765 * Center/LFE (DAC 04)
1768 * The system also has a pair of internal speakers, and a headphone jack.
1769 * These are both connected to Line2 on the codec, hence to DAC 02.
1771 * There is a variable resistor to control the speaker or headphone
1772 * volume. This is a hardware-only device without a software API.
1774 * Plugging headphones in will disable the internal speakers. This is
1775 * implemented in hardware, not via the driver using jack sense. In
1776 * a similar fashion, plugging into the rear socket marked "front" will
1777 * disable both the speakers and headphones.
1779 * For input, there's a microphone jack, and an "audio in" jack.
1780 * These may not do anything useful with this driver yet, because I
1781 * haven't setup any initialization verbs for these yet...
1784 static hda_nid_t alc880_w810_dac_nids[3] = {
1785 /* front, rear/surround, clfe */
1789 /* fixed 6 channels */
1790 static struct hda_channel_mode alc880_w810_modes[1] = {
1794 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1795 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1796 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1797 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1798 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1799 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1800 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1801 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1802 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1803 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1812 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1813 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1817 static hda_nid_t alc880_z71v_dac_nids[1] = {
1820 #define ALC880_Z71V_HP_DAC 0x03
1822 /* fixed 2 channels */
1823 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1827 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1828 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1829 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1830 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1831 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1832 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1833 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1834 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1841 * ALC880 F1734 model
1843 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1844 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1847 static hda_nid_t alc880_f1734_dac_nids[1] = {
1850 #define ALC880_F1734_HP_DAC 0x02
1852 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1853 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1854 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1855 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1856 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1864 static struct hda_input_mux alc880_f1734_capture_source = {
1876 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1877 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1878 * Mic = 0x18, Line = 0x1a
1881 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1882 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1884 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1885 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1886 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1887 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1888 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1889 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1890 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1891 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1892 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1893 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1894 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1895 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1896 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1901 .name = "Channel Mode",
1902 .info = alc_ch_mode_info,
1903 .get = alc_ch_mode_get,
1904 .put = alc_ch_mode_put,
1910 * ALC880 ASUS W1V model
1912 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1913 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1914 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1917 /* additional mixers to alc880_asus_mixer */
1918 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1919 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1920 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1925 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1926 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1927 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1930 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1931 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1932 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1933 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1934 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1939 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1940 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1941 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1943 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1944 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1945 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1946 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1947 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1948 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1949 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1950 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1951 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1954 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1955 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1958 .name = "Channel Mode",
1959 .info = alc_ch_mode_info,
1960 .get = alc_ch_mode_get,
1961 .put = alc_ch_mode_put,
1966 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1968 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1970 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1974 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1975 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1976 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1980 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1982 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1983 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1984 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1991 * virtual master controls
1995 * slave controls for virtual master
1997 static const char *alc_slave_vols[] = {
1998 "Front Playback Volume",
1999 "Surround Playback Volume",
2000 "Center Playback Volume",
2001 "LFE Playback Volume",
2002 "Side Playback Volume",
2003 "Headphone Playback Volume",
2004 "Speaker Playback Volume",
2005 "Mono Playback Volume",
2006 "Line-Out Playback Volume",
2007 "PCM Playback Volume",
2011 static const char *alc_slave_sws[] = {
2012 "Front Playback Switch",
2013 "Surround Playback Switch",
2014 "Center Playback Switch",
2015 "LFE Playback Switch",
2016 "Side Playback Switch",
2017 "Headphone Playback Switch",
2018 "Speaker Playback Switch",
2019 "Mono Playback Switch",
2020 "IEC958 Playback Switch",
2025 * build control elements
2028 static void alc_free_kctls(struct hda_codec *codec);
2030 /* additional beep mixers; the actual parameters are overwritten at build */
2031 static struct snd_kcontrol_new alc_beep_mixer[] = {
2032 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2033 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2037 static int alc_build_controls(struct hda_codec *codec)
2039 struct alc_spec *spec = codec->spec;
2043 for (i = 0; i < spec->num_mixers; i++) {
2044 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2048 if (spec->cap_mixer) {
2049 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2053 if (spec->multiout.dig_out_nid) {
2054 err = snd_hda_create_spdif_out_ctls(codec,
2055 spec->multiout.dig_out_nid);
2058 if (!spec->no_analog) {
2059 err = snd_hda_create_spdif_share_sw(codec,
2063 spec->multiout.share_spdif = 1;
2066 if (spec->dig_in_nid) {
2067 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2072 /* create beep controls if needed */
2073 if (spec->beep_amp) {
2074 struct snd_kcontrol_new *knew;
2075 for (knew = alc_beep_mixer; knew->name; knew++) {
2076 struct snd_kcontrol *kctl;
2077 kctl = snd_ctl_new1(knew, codec);
2080 kctl->private_value = spec->beep_amp;
2081 err = snd_hda_ctl_add(codec, kctl);
2087 /* if we have no master control, let's create it */
2088 if (!spec->no_analog &&
2089 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2090 unsigned int vmaster_tlv[4];
2091 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2092 HDA_OUTPUT, vmaster_tlv);
2093 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2094 vmaster_tlv, alc_slave_vols);
2098 if (!spec->no_analog &&
2099 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2100 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2101 NULL, alc_slave_sws);
2106 alc_free_kctls(codec); /* no longer needed */
2112 * initialize the codec volumes, etc
2116 * generic initialization of ADC, input mixers and output mixers
2118 static struct hda_verb alc880_volume_init_verbs[] = {
2120 * Unmute ADC0-2 and set the default input to mic-in
2122 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2123 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2124 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2125 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2126 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2129 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2131 * Note: PASD motherboards uses the Line In 2 as the input for front
2134 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2140 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2141 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2144 * Set up output mixers (0x0c - 0x0f)
2146 /* set vol=0 to output mixers */
2147 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2148 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2149 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2150 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2151 /* set up input amps for analog loopback */
2152 /* Amp Indices: DAC = 0, mixer = 1 */
2153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2156 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2158 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2159 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2166 * 3-stack pin configuration:
2167 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2169 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2171 * preset connection lists of input pins
2172 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2174 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2175 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2176 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2179 * Set pin mode and muting
2181 /* set front pin widgets 0x14 for output */
2182 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2183 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2184 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2185 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2186 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2187 /* Mic2 (as headphone out) for HP output */
2188 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2189 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2190 /* Line In pin widget for input */
2191 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2192 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2193 /* Line2 (as front mic) pin widget for input and vref at 80% */
2194 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2195 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2196 /* CD pin widget for input */
2197 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2203 * 5-stack pin configuration:
2204 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2205 * line-in/side = 0x1a, f-mic = 0x1b
2207 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2209 * preset connection lists of input pins
2210 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2212 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2213 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2216 * Set pin mode and muting
2218 /* set pin widgets 0x14-0x17 for output */
2219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2223 /* unmute pins for output (no gain on this amp) */
2224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2230 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232 /* Mic2 (as headphone out) for HP output */
2233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2235 /* Line In pin widget for input */
2236 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2238 /* Line2 (as front mic) pin widget for input and vref at 80% */
2239 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2240 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2241 /* CD pin widget for input */
2242 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2248 * W810 pin configuration:
2249 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2251 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2252 /* hphone/speaker input selector: front DAC */
2253 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2255 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2260 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2263 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2269 * Z71V pin configuration:
2270 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2272 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2273 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2274 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2278 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2279 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2281 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2287 * 6-stack pin configuration:
2288 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2289 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2291 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2292 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2296 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2299 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2301 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2304 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2305 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2306 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2310 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2311 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2317 * Uniwill pin configuration:
2318 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2321 static struct hda_verb alc880_uniwill_init_verbs[] = {
2322 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2324 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2325 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2327 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2330 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2331 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2334 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2335 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2336 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2337 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2339 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2340 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2341 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2343 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2345 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2346 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2347 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2349 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2350 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2357 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2359 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2360 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2362 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2363 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2366 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2367 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2377 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2378 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2382 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2383 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2388 static struct hda_verb alc880_beep_init_verbs[] = {
2389 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2393 /* toggle speaker-output according to the hp-jack state */
2394 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2396 unsigned int present;
2399 present = snd_hda_codec_read(codec, 0x14, 0,
2400 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2401 bits = present ? HDA_AMP_MUTE : 0;
2402 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2403 HDA_AMP_MUTE, bits);
2404 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2405 HDA_AMP_MUTE, bits);
2408 /* auto-toggle front mic */
2409 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2411 unsigned int present;
2414 present = snd_hda_codec_read(codec, 0x18, 0,
2415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2416 bits = present ? HDA_AMP_MUTE : 0;
2417 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2420 static void alc880_uniwill_automute(struct hda_codec *codec)
2422 alc880_uniwill_hp_automute(codec);
2423 alc880_uniwill_mic_automute(codec);
2426 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2429 /* Looks like the unsol event is incompatible with the standard
2430 * definition. 4bit tag is placed at 28 bit!
2432 switch (res >> 28) {
2433 case ALC880_HP_EVENT:
2434 alc880_uniwill_hp_automute(codec);
2436 case ALC880_MIC_EVENT:
2437 alc880_uniwill_mic_automute(codec);
2442 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2444 unsigned int present;
2447 present = snd_hda_codec_read(codec, 0x14, 0,
2448 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2449 bits = present ? HDA_AMP_MUTE : 0;
2450 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2453 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2455 unsigned int present;
2457 present = snd_hda_codec_read(codec, 0x21, 0,
2458 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2459 present &= HDA_AMP_VOLMASK;
2460 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2461 HDA_AMP_VOLMASK, present);
2462 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2463 HDA_AMP_VOLMASK, present);
2466 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2469 /* Looks like the unsol event is incompatible with the standard
2470 * definition. 4bit tag is placed at 28 bit!
2472 if ((res >> 28) == ALC880_HP_EVENT)
2473 alc880_uniwill_p53_hp_automute(codec);
2474 if ((res >> 28) == ALC880_DCVOL_EVENT)
2475 alc880_uniwill_p53_dcvol_automute(codec);
2479 * F1734 pin configuration:
2480 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2482 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2483 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2484 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2485 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2486 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2487 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2495 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2496 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2498 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2499 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2501 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2504 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2505 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2511 * ASUS pin configuration:
2512 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2514 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2515 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2516 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2517 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2518 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2521 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2524 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2526 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2529 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2530 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2531 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2532 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2533 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2535 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2537 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2542 /* Enable GPIO mask and set output */
2543 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2544 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2546 /* Clevo m520g init */
2547 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2548 /* headphone output */
2549 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2552 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2554 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2555 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2558 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2559 /* Mic1 (rear panel) */
2560 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2561 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2562 /* Mic2 (front panel) */
2563 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2564 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2566 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2567 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2568 /* change to EAPD mode */
2569 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2570 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2575 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2576 /* change to EAPD mode */
2577 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2578 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2580 /* Headphone output */
2581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2584 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2586 /* Line In pin widget for input */
2587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2588 /* CD pin widget for input */
2589 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2590 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2591 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2593 /* change to EAPD mode */
2594 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2595 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2601 * LG m1 express dual
2604 * Rear Line-In/Out (blue): 0x14
2605 * Build-in Mic-In: 0x15
2607 * HP-Out (green): 0x1b
2608 * Mic-In/Out (red): 0x19
2612 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2613 static hda_nid_t alc880_lg_dac_nids[3] = {
2617 /* seems analog CD is not working */
2618 static struct hda_input_mux alc880_lg_capture_source = {
2623 { "Internal Mic", 0x6 },
2627 /* 2,4,6 channel modes */
2628 static struct hda_verb alc880_lg_ch2_init[] = {
2629 /* set line-in and mic-in to input */
2630 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2631 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2635 static struct hda_verb alc880_lg_ch4_init[] = {
2636 /* set line-in to out and mic-in to input */
2637 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2638 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2642 static struct hda_verb alc880_lg_ch6_init[] = {
2643 /* set line-in and mic-in to output */
2644 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2645 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2649 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2650 { 2, alc880_lg_ch2_init },
2651 { 4, alc880_lg_ch4_init },
2652 { 6, alc880_lg_ch6_init },
2655 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2657 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2658 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2659 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2660 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2661 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2662 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2663 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2665 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2666 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2667 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2668 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2669 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2672 .name = "Channel Mode",
2673 .info = alc_ch_mode_info,
2674 .get = alc_ch_mode_get,
2675 .put = alc_ch_mode_put,
2680 static struct hda_verb alc880_lg_init_verbs[] = {
2681 /* set capture source to mic-in */
2682 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2683 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2685 /* mute all amp mixer inputs */
2686 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2687 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2688 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2689 /* line-in to input */
2690 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2696 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2697 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2698 /* mic-in to input */
2699 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2700 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2701 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2703 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2707 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2711 /* toggle speaker-output according to the hp-jack state */
2712 static void alc880_lg_automute(struct hda_codec *codec)
2714 unsigned int present;
2717 present = snd_hda_codec_read(codec, 0x1b, 0,
2718 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2719 bits = present ? HDA_AMP_MUTE : 0;
2720 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2721 HDA_AMP_MUTE, bits);
2724 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2726 /* Looks like the unsol event is incompatible with the standard
2727 * definition. 4bit tag is placed at 28 bit!
2729 if ((res >> 28) == 0x01)
2730 alc880_lg_automute(codec);
2739 * Built-in Mic-In: 0x19
2745 static struct hda_input_mux alc880_lg_lw_capture_source = {
2749 { "Internal Mic", 0x1 },
2754 #define alc880_lg_lw_modes alc880_threestack_modes
2756 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2757 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2760 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2761 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2762 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2763 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2764 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2765 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2766 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2769 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2770 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2772 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2773 .name = "Channel Mode",
2774 .info = alc_ch_mode_info,
2775 .get = alc_ch_mode_get,
2776 .put = alc_ch_mode_put,
2781 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2782 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2783 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2784 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2786 /* set capture source to mic-in */
2787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2790 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2797 /* mic-in to input */
2798 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2799 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2802 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2804 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2808 /* toggle speaker-output according to the hp-jack state */
2809 static void alc880_lg_lw_automute(struct hda_codec *codec)
2811 unsigned int present;
2814 present = snd_hda_codec_read(codec, 0x1b, 0,
2815 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2816 bits = present ? HDA_AMP_MUTE : 0;
2817 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2818 HDA_AMP_MUTE, bits);
2821 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2823 /* Looks like the unsol event is incompatible with the standard
2824 * definition. 4bit tag is placed at 28 bit!
2826 if ((res >> 28) == 0x01)
2827 alc880_lg_lw_automute(codec);
2830 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2831 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2832 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2835 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2836 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2840 static struct hda_input_mux alc880_medion_rim_capture_source = {
2844 { "Internal Mic", 0x1 },
2848 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2849 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2851 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2854 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2855 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2857 /* Mic2 (as headphone out) for HP output */
2858 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2859 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2860 /* Internal Speaker */
2861 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2862 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2864 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2865 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2867 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2871 /* toggle speaker-output according to the hp-jack state */
2872 static void alc880_medion_rim_automute(struct hda_codec *codec)
2874 unsigned int present;
2877 present = snd_hda_codec_read(codec, 0x14, 0,
2878 AC_VERB_GET_PIN_SENSE, 0)
2879 & AC_PINSENSE_PRESENCE;
2880 bits = present ? HDA_AMP_MUTE : 0;
2881 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2882 HDA_AMP_MUTE, bits);
2884 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2886 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2889 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2892 /* Looks like the unsol event is incompatible with the standard
2893 * definition. 4bit tag is placed at 28 bit!
2895 if ((res >> 28) == ALC880_HP_EVENT)
2896 alc880_medion_rim_automute(codec);
2899 #ifdef CONFIG_SND_HDA_POWER_SAVE
2900 static struct hda_amp_list alc880_loopbacks[] = {
2901 { 0x0b, HDA_INPUT, 0 },
2902 { 0x0b, HDA_INPUT, 1 },
2903 { 0x0b, HDA_INPUT, 2 },
2904 { 0x0b, HDA_INPUT, 3 },
2905 { 0x0b, HDA_INPUT, 4 },
2909 static struct hda_amp_list alc880_lg_loopbacks[] = {
2910 { 0x0b, HDA_INPUT, 1 },
2911 { 0x0b, HDA_INPUT, 6 },
2912 { 0x0b, HDA_INPUT, 7 },
2921 static int alc_init(struct hda_codec *codec)
2923 struct alc_spec *spec = codec->spec;
2927 if (codec->vendor_id == 0x10ec0888)
2928 alc888_coef_init(codec);
2930 for (i = 0; i < spec->num_init_verbs; i++)
2931 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2933 if (spec->init_hook)
2934 spec->init_hook(codec);
2939 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2941 struct alc_spec *spec = codec->spec;
2943 if (spec->unsol_event)
2944 spec->unsol_event(codec, res);
2947 #ifdef CONFIG_SND_HDA_POWER_SAVE
2948 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2950 struct alc_spec *spec = codec->spec;
2951 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2956 * Analog playback callbacks
2958 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2959 struct hda_codec *codec,
2960 struct snd_pcm_substream *substream)
2962 struct alc_spec *spec = codec->spec;
2963 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2967 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2968 struct hda_codec *codec,
2969 unsigned int stream_tag,
2970 unsigned int format,
2971 struct snd_pcm_substream *substream)
2973 struct alc_spec *spec = codec->spec;
2974 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2975 stream_tag, format, substream);
2978 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2979 struct hda_codec *codec,
2980 struct snd_pcm_substream *substream)
2982 struct alc_spec *spec = codec->spec;
2983 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2989 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2990 struct hda_codec *codec,
2991 struct snd_pcm_substream *substream)
2993 struct alc_spec *spec = codec->spec;
2994 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2997 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2998 struct hda_codec *codec,
2999 unsigned int stream_tag,
3000 unsigned int format,
3001 struct snd_pcm_substream *substream)
3003 struct alc_spec *spec = codec->spec;
3004 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3005 stream_tag, format, substream);
3008 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3009 struct hda_codec *codec,
3010 struct snd_pcm_substream *substream)
3012 struct alc_spec *spec = codec->spec;
3013 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3016 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3017 struct hda_codec *codec,
3018 struct snd_pcm_substream *substream)
3020 struct alc_spec *spec = codec->spec;
3021 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3027 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3028 struct hda_codec *codec,
3029 unsigned int stream_tag,
3030 unsigned int format,
3031 struct snd_pcm_substream *substream)
3033 struct alc_spec *spec = codec->spec;
3035 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3036 stream_tag, 0, format);
3040 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3041 struct hda_codec *codec,
3042 struct snd_pcm_substream *substream)
3044 struct alc_spec *spec = codec->spec;
3046 snd_hda_codec_cleanup_stream(codec,
3047 spec->adc_nids[substream->number + 1]);
3054 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3058 /* NID is set in alc_build_pcms */
3060 .open = alc880_playback_pcm_open,
3061 .prepare = alc880_playback_pcm_prepare,
3062 .cleanup = alc880_playback_pcm_cleanup
3066 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3070 /* NID is set in alc_build_pcms */
3073 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3077 /* NID is set in alc_build_pcms */
3080 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3081 .substreams = 2, /* can be overridden */
3084 /* NID is set in alc_build_pcms */
3086 .prepare = alc880_alt_capture_pcm_prepare,
3087 .cleanup = alc880_alt_capture_pcm_cleanup
3091 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3095 /* NID is set in alc_build_pcms */
3097 .open = alc880_dig_playback_pcm_open,
3098 .close = alc880_dig_playback_pcm_close,
3099 .prepare = alc880_dig_playback_pcm_prepare,
3100 .cleanup = alc880_dig_playback_pcm_cleanup
3104 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3108 /* NID is set in alc_build_pcms */
3111 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3112 static struct hda_pcm_stream alc_pcm_null_stream = {
3118 static int alc_build_pcms(struct hda_codec *codec)
3120 struct alc_spec *spec = codec->spec;
3121 struct hda_pcm *info = spec->pcm_rec;
3124 codec->num_pcms = 1;
3125 codec->pcm_info = info;
3127 if (spec->no_analog)
3130 info->name = spec->stream_name_analog;
3131 if (spec->stream_analog_playback) {
3132 if (snd_BUG_ON(!spec->multiout.dac_nids))
3134 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3135 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3137 if (spec->stream_analog_capture) {
3138 if (snd_BUG_ON(!spec->adc_nids))
3140 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3141 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3144 if (spec->channel_mode) {
3145 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3146 for (i = 0; i < spec->num_channel_mode; i++) {
3147 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3148 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3154 /* SPDIF for stream index #1 */
3155 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3156 codec->num_pcms = 2;
3157 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3158 info = spec->pcm_rec + 1;
3159 info->name = spec->stream_name_digital;
3160 if (spec->dig_out_type)
3161 info->pcm_type = spec->dig_out_type;
3163 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3164 if (spec->multiout.dig_out_nid &&
3165 spec->stream_digital_playback) {
3166 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3167 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3169 if (spec->dig_in_nid &&
3170 spec->stream_digital_capture) {
3171 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3172 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3174 /* FIXME: do we need this for all Realtek codec models? */
3175 codec->spdif_status_reset = 1;
3178 if (spec->no_analog)
3181 /* If the use of more than one ADC is requested for the current
3182 * model, configure a second analog capture-only PCM.
3184 /* Additional Analaog capture for index #2 */
3185 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3186 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3187 codec->num_pcms = 3;
3188 info = spec->pcm_rec + 2;
3189 info->name = spec->stream_name_analog;
3190 if (spec->alt_dac_nid) {
3191 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3192 *spec->stream_analog_alt_playback;
3193 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3196 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3197 alc_pcm_null_stream;
3198 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3200 if (spec->num_adc_nids > 1) {
3201 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3202 *spec->stream_analog_alt_capture;
3203 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3205 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3206 spec->num_adc_nids - 1;
3208 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3209 alc_pcm_null_stream;
3210 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3217 static void alc_free_kctls(struct hda_codec *codec)
3219 struct alc_spec *spec = codec->spec;
3221 if (spec->kctls.list) {
3222 struct snd_kcontrol_new *kctl = spec->kctls.list;
3224 for (i = 0; i < spec->kctls.used; i++)
3225 kfree(kctl[i].name);
3227 snd_array_free(&spec->kctls);
3230 static void alc_free(struct hda_codec *codec)
3232 struct alc_spec *spec = codec->spec;
3237 alc_free_kctls(codec);
3239 snd_hda_detach_beep_device(codec);
3242 #ifdef SND_HDA_NEEDS_RESUME
3243 static int alc_resume(struct hda_codec *codec)
3245 codec->patch_ops.init(codec);
3246 snd_hda_codec_resume_amp(codec);
3247 snd_hda_codec_resume_cache(codec);
3254 static struct hda_codec_ops alc_patch_ops = {
3255 .build_controls = alc_build_controls,
3256 .build_pcms = alc_build_pcms,
3259 .unsol_event = alc_unsol_event,
3260 #ifdef SND_HDA_NEEDS_RESUME
3261 .resume = alc_resume,
3263 #ifdef CONFIG_SND_HDA_POWER_SAVE
3264 .check_power_status = alc_check_power_status,
3270 * Test configuration for debugging
3272 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3275 #ifdef CONFIG_SND_DEBUG
3276 static hda_nid_t alc880_test_dac_nids[4] = {
3277 0x02, 0x03, 0x04, 0x05
3280 static struct hda_input_mux alc880_test_capture_source = {
3289 { "Surround", 0x6 },
3293 static struct hda_channel_mode alc880_test_modes[4] = {
3300 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3301 struct snd_ctl_elem_info *uinfo)
3303 static char *texts[] = {
3304 "N/A", "Line Out", "HP Out",
3305 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3307 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3309 uinfo->value.enumerated.items = 8;
3310 if (uinfo->value.enumerated.item >= 8)
3311 uinfo->value.enumerated.item = 7;
3312 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3316 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3317 struct snd_ctl_elem_value *ucontrol)
3319 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3320 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3321 unsigned int pin_ctl, item = 0;
3323 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3324 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3325 if (pin_ctl & AC_PINCTL_OUT_EN) {
3326 if (pin_ctl & AC_PINCTL_HP_EN)
3330 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3331 switch (pin_ctl & AC_PINCTL_VREFEN) {
3332 case AC_PINCTL_VREF_HIZ: item = 3; break;
3333 case AC_PINCTL_VREF_50: item = 4; break;
3334 case AC_PINCTL_VREF_GRD: item = 5; break;
3335 case AC_PINCTL_VREF_80: item = 6; break;
3336 case AC_PINCTL_VREF_100: item = 7; break;
3339 ucontrol->value.enumerated.item[0] = item;
3343 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3344 struct snd_ctl_elem_value *ucontrol)
3346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3347 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3348 static unsigned int ctls[] = {
3349 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3350 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3351 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3352 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3353 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3354 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3356 unsigned int old_ctl, new_ctl;
3358 old_ctl = snd_hda_codec_read(codec, nid, 0,
3359 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3360 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3361 if (old_ctl != new_ctl) {
3363 snd_hda_codec_write_cache(codec, nid, 0,
3364 AC_VERB_SET_PIN_WIDGET_CONTROL,
3366 val = ucontrol->value.enumerated.item[0] >= 3 ?
3368 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3375 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3376 struct snd_ctl_elem_info *uinfo)
3378 static char *texts[] = {
3379 "Front", "Surround", "CLFE", "Side"
3381 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3383 uinfo->value.enumerated.items = 4;
3384 if (uinfo->value.enumerated.item >= 4)
3385 uinfo->value.enumerated.item = 3;
3386 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3390 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3391 struct snd_ctl_elem_value *ucontrol)
3393 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3394 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3397 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3398 ucontrol->value.enumerated.item[0] = sel & 3;
3402 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3403 struct snd_ctl_elem_value *ucontrol)
3405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3406 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3409 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3410 if (ucontrol->value.enumerated.item[0] != sel) {
3411 sel = ucontrol->value.enumerated.item[0] & 3;
3412 snd_hda_codec_write_cache(codec, nid, 0,
3413 AC_VERB_SET_CONNECT_SEL, sel);
3419 #define PIN_CTL_TEST(xname,nid) { \
3420 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3422 .info = alc_test_pin_ctl_info, \
3423 .get = alc_test_pin_ctl_get, \
3424 .put = alc_test_pin_ctl_put, \
3425 .private_value = nid \
3428 #define PIN_SRC_TEST(xname,nid) { \
3429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3431 .info = alc_test_pin_src_info, \
3432 .get = alc_test_pin_src_get, \
3433 .put = alc_test_pin_src_put, \
3434 .private_value = nid \
3437 static struct snd_kcontrol_new alc880_test_mixer[] = {
3438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3439 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3440 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3441 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3442 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3443 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3444 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3445 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3446 PIN_CTL_TEST("Front Pin Mode", 0x14),
3447 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3448 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3449 PIN_CTL_TEST("Side Pin Mode", 0x17),
3450 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3451 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3452 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3453 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3454 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3455 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3456 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3457 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3458 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3459 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3460 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3461 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3462 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3463 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3464 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3465 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3466 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3467 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3469 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3470 .name = "Channel Mode",
3471 .info = alc_ch_mode_info,
3472 .get = alc_ch_mode_get,
3473 .put = alc_ch_mode_put,
3478 static struct hda_verb alc880_test_init_verbs[] = {
3479 /* Unmute inputs of 0x0c - 0x0f */
3480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3484 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3485 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3487 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3488 /* Vol output for 0x0c-0x0f */
3489 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3492 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3493 /* Set output pins 0x14-0x17 */
3494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3497 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3498 /* Unmute output pins 0x14-0x17 */
3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3503 /* Set input pins 0x18-0x1c */
3504 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3505 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3506 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3507 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3509 /* Mute input pins 0x18-0x1b */
3510 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3513 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3516 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3517 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3518 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3519 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3520 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3521 /* Analog input/passthru */
3522 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3523 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3534 static const char *alc880_models[ALC880_MODEL_LAST] = {
3535 [ALC880_3ST] = "3stack",
3536 [ALC880_TCL_S700] = "tcl",
3537 [ALC880_3ST_DIG] = "3stack-digout",
3538 [ALC880_CLEVO] = "clevo",
3539 [ALC880_5ST] = "5stack",
3540 [ALC880_5ST_DIG] = "5stack-digout",
3541 [ALC880_W810] = "w810",
3542 [ALC880_Z71V] = "z71v",
3543 [ALC880_6ST] = "6stack",
3544 [ALC880_6ST_DIG] = "6stack-digout",
3545 [ALC880_ASUS] = "asus",
3546 [ALC880_ASUS_W1V] = "asus-w1v",
3547 [ALC880_ASUS_DIG] = "asus-dig",
3548 [ALC880_ASUS_DIG2] = "asus-dig2",
3549 [ALC880_UNIWILL_DIG] = "uniwill",
3550 [ALC880_UNIWILL_P53] = "uniwill-p53",
3551 [ALC880_FUJITSU] = "fujitsu",
3552 [ALC880_F1734] = "F1734",
3554 [ALC880_LG_LW] = "lg-lw",
3555 [ALC880_MEDION_RIM] = "medion",
3556 #ifdef CONFIG_SND_DEBUG
3557 [ALC880_TEST] = "test",
3559 [ALC880_AUTO] = "auto",
3562 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3563 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3564 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3565 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3566 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3567 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3568 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3569 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3570 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3571 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3572 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3573 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3574 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3575 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3576 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3577 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3578 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3579 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3580 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3581 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3582 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3583 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3584 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3585 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3586 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3587 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3588 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3589 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3590 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3591 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3592 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3593 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3594 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3595 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3596 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3597 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3598 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3599 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3600 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3601 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3602 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3603 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3604 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3605 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3606 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3607 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3608 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3609 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3610 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3611 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3612 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3613 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3614 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3615 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3616 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3617 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3618 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3619 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3620 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3621 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3622 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3623 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3624 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3625 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3626 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3627 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3628 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3629 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3630 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3632 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3633 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3634 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3639 * ALC880 codec presets
3641 static struct alc_config_preset alc880_presets[] = {
3643 .mixers = { alc880_three_stack_mixer },
3644 .init_verbs = { alc880_volume_init_verbs,
3645 alc880_pin_3stack_init_verbs },
3646 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3647 .dac_nids = alc880_dac_nids,
3648 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3649 .channel_mode = alc880_threestack_modes,
3651 .input_mux = &alc880_capture_source,
3653 [ALC880_3ST_DIG] = {
3654 .mixers = { alc880_three_stack_mixer },
3655 .init_verbs = { alc880_volume_init_verbs,
3656 alc880_pin_3stack_init_verbs },
3657 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3658 .dac_nids = alc880_dac_nids,
3659 .dig_out_nid = ALC880_DIGOUT_NID,
3660 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3661 .channel_mode = alc880_threestack_modes,
3663 .input_mux = &alc880_capture_source,
3665 [ALC880_TCL_S700] = {
3666 .mixers = { alc880_tcl_s700_mixer },
3667 .init_verbs = { alc880_volume_init_verbs,
3668 alc880_pin_tcl_S700_init_verbs,
3669 alc880_gpio2_init_verbs },
3670 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3671 .dac_nids = alc880_dac_nids,
3672 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3673 .num_adc_nids = 1, /* single ADC */
3675 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3676 .channel_mode = alc880_2_jack_modes,
3677 .input_mux = &alc880_capture_source,
3680 .mixers = { alc880_three_stack_mixer,
3681 alc880_five_stack_mixer},
3682 .init_verbs = { alc880_volume_init_verbs,
3683 alc880_pin_5stack_init_verbs },
3684 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3685 .dac_nids = alc880_dac_nids,
3686 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3687 .channel_mode = alc880_fivestack_modes,
3688 .input_mux = &alc880_capture_source,
3690 [ALC880_5ST_DIG] = {
3691 .mixers = { alc880_three_stack_mixer,
3692 alc880_five_stack_mixer },
3693 .init_verbs = { alc880_volume_init_verbs,
3694 alc880_pin_5stack_init_verbs },
3695 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3696 .dac_nids = alc880_dac_nids,
3697 .dig_out_nid = ALC880_DIGOUT_NID,
3698 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3699 .channel_mode = alc880_fivestack_modes,
3700 .input_mux = &alc880_capture_source,
3703 .mixers = { alc880_six_stack_mixer },
3704 .init_verbs = { alc880_volume_init_verbs,
3705 alc880_pin_6stack_init_verbs },
3706 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3707 .dac_nids = alc880_6st_dac_nids,
3708 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3709 .channel_mode = alc880_sixstack_modes,
3710 .input_mux = &alc880_6stack_capture_source,
3712 [ALC880_6ST_DIG] = {
3713 .mixers = { alc880_six_stack_mixer },
3714 .init_verbs = { alc880_volume_init_verbs,
3715 alc880_pin_6stack_init_verbs },
3716 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3717 .dac_nids = alc880_6st_dac_nids,
3718 .dig_out_nid = ALC880_DIGOUT_NID,
3719 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3720 .channel_mode = alc880_sixstack_modes,
3721 .input_mux = &alc880_6stack_capture_source,
3724 .mixers = { alc880_w810_base_mixer },
3725 .init_verbs = { alc880_volume_init_verbs,
3726 alc880_pin_w810_init_verbs,
3727 alc880_gpio2_init_verbs },
3728 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3729 .dac_nids = alc880_w810_dac_nids,
3730 .dig_out_nid = ALC880_DIGOUT_NID,
3731 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3732 .channel_mode = alc880_w810_modes,
3733 .input_mux = &alc880_capture_source,
3736 .mixers = { alc880_z71v_mixer },
3737 .init_verbs = { alc880_volume_init_verbs,
3738 alc880_pin_z71v_init_verbs },
3739 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3740 .dac_nids = alc880_z71v_dac_nids,
3741 .dig_out_nid = ALC880_DIGOUT_NID,
3743 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3744 .channel_mode = alc880_2_jack_modes,
3745 .input_mux = &alc880_capture_source,
3748 .mixers = { alc880_f1734_mixer },
3749 .init_verbs = { alc880_volume_init_verbs,
3750 alc880_pin_f1734_init_verbs },
3751 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3752 .dac_nids = alc880_f1734_dac_nids,
3754 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3755 .channel_mode = alc880_2_jack_modes,
3756 .input_mux = &alc880_f1734_capture_source,
3757 .unsol_event = alc880_uniwill_p53_unsol_event,
3758 .init_hook = alc880_uniwill_p53_hp_automute,
3761 .mixers = { alc880_asus_mixer },
3762 .init_verbs = { alc880_volume_init_verbs,
3763 alc880_pin_asus_init_verbs,
3764 alc880_gpio1_init_verbs },
3765 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3766 .dac_nids = alc880_asus_dac_nids,
3767 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3768 .channel_mode = alc880_asus_modes,
3770 .input_mux = &alc880_capture_source,
3772 [ALC880_ASUS_DIG] = {
3773 .mixers = { alc880_asus_mixer },
3774 .init_verbs = { alc880_volume_init_verbs,
3775 alc880_pin_asus_init_verbs,
3776 alc880_gpio1_init_verbs },
3777 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3778 .dac_nids = alc880_asus_dac_nids,
3779 .dig_out_nid = ALC880_DIGOUT_NID,
3780 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3781 .channel_mode = alc880_asus_modes,
3783 .input_mux = &alc880_capture_source,
3785 [ALC880_ASUS_DIG2] = {
3786 .mixers = { alc880_asus_mixer },
3787 .init_verbs = { alc880_volume_init_verbs,
3788 alc880_pin_asus_init_verbs,
3789 alc880_gpio2_init_verbs }, /* use GPIO2 */
3790 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3791 .dac_nids = alc880_asus_dac_nids,
3792 .dig_out_nid = ALC880_DIGOUT_NID,
3793 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3794 .channel_mode = alc880_asus_modes,
3796 .input_mux = &alc880_capture_source,
3798 [ALC880_ASUS_W1V] = {
3799 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3800 .init_verbs = { alc880_volume_init_verbs,
3801 alc880_pin_asus_init_verbs,
3802 alc880_gpio1_init_verbs },
3803 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3804 .dac_nids = alc880_asus_dac_nids,
3805 .dig_out_nid = ALC880_DIGOUT_NID,
3806 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3807 .channel_mode = alc880_asus_modes,
3809 .input_mux = &alc880_capture_source,
3811 [ALC880_UNIWILL_DIG] = {
3812 .mixers = { alc880_asus_mixer },
3813 .init_verbs = { alc880_volume_init_verbs,
3814 alc880_pin_asus_init_verbs },
3815 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3816 .dac_nids = alc880_asus_dac_nids,
3817 .dig_out_nid = ALC880_DIGOUT_NID,
3818 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3819 .channel_mode = alc880_asus_modes,
3821 .input_mux = &alc880_capture_source,
3823 [ALC880_UNIWILL] = {
3824 .mixers = { alc880_uniwill_mixer },
3825 .init_verbs = { alc880_volume_init_verbs,
3826 alc880_uniwill_init_verbs },
3827 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3828 .dac_nids = alc880_asus_dac_nids,
3829 .dig_out_nid = ALC880_DIGOUT_NID,
3830 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3831 .channel_mode = alc880_threestack_modes,
3833 .input_mux = &alc880_capture_source,
3834 .unsol_event = alc880_uniwill_unsol_event,
3835 .init_hook = alc880_uniwill_automute,
3837 [ALC880_UNIWILL_P53] = {
3838 .mixers = { alc880_uniwill_p53_mixer },
3839 .init_verbs = { alc880_volume_init_verbs,
3840 alc880_uniwill_p53_init_verbs },
3841 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3842 .dac_nids = alc880_asus_dac_nids,
3843 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3844 .channel_mode = alc880_threestack_modes,
3845 .input_mux = &alc880_capture_source,
3846 .unsol_event = alc880_uniwill_p53_unsol_event,
3847 .init_hook = alc880_uniwill_p53_hp_automute,
3849 [ALC880_FUJITSU] = {
3850 .mixers = { alc880_fujitsu_mixer },
3851 .init_verbs = { alc880_volume_init_verbs,
3852 alc880_uniwill_p53_init_verbs,
3853 alc880_beep_init_verbs },
3854 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3855 .dac_nids = alc880_dac_nids,
3856 .dig_out_nid = ALC880_DIGOUT_NID,
3857 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3858 .channel_mode = alc880_2_jack_modes,
3859 .input_mux = &alc880_capture_source,
3860 .unsol_event = alc880_uniwill_p53_unsol_event,
3861 .init_hook = alc880_uniwill_p53_hp_automute,
3864 .mixers = { alc880_three_stack_mixer },
3865 .init_verbs = { alc880_volume_init_verbs,
3866 alc880_pin_clevo_init_verbs },
3867 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3868 .dac_nids = alc880_dac_nids,
3870 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3871 .channel_mode = alc880_threestack_modes,
3873 .input_mux = &alc880_capture_source,
3876 .mixers = { alc880_lg_mixer },
3877 .init_verbs = { alc880_volume_init_verbs,
3878 alc880_lg_init_verbs },
3879 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3880 .dac_nids = alc880_lg_dac_nids,
3881 .dig_out_nid = ALC880_DIGOUT_NID,
3882 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3883 .channel_mode = alc880_lg_ch_modes,
3885 .input_mux = &alc880_lg_capture_source,
3886 .unsol_event = alc880_lg_unsol_event,
3887 .init_hook = alc880_lg_automute,
3888 #ifdef CONFIG_SND_HDA_POWER_SAVE
3889 .loopbacks = alc880_lg_loopbacks,
3893 .mixers = { alc880_lg_lw_mixer },
3894 .init_verbs = { alc880_volume_init_verbs,
3895 alc880_lg_lw_init_verbs },
3896 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3897 .dac_nids = alc880_dac_nids,
3898 .dig_out_nid = ALC880_DIGOUT_NID,
3899 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3900 .channel_mode = alc880_lg_lw_modes,
3901 .input_mux = &alc880_lg_lw_capture_source,
3902 .unsol_event = alc880_lg_lw_unsol_event,
3903 .init_hook = alc880_lg_lw_automute,
3905 [ALC880_MEDION_RIM] = {
3906 .mixers = { alc880_medion_rim_mixer },
3907 .init_verbs = { alc880_volume_init_verbs,
3908 alc880_medion_rim_init_verbs,
3909 alc_gpio2_init_verbs },
3910 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3911 .dac_nids = alc880_dac_nids,
3912 .dig_out_nid = ALC880_DIGOUT_NID,
3913 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3914 .channel_mode = alc880_2_jack_modes,
3915 .input_mux = &alc880_medion_rim_capture_source,
3916 .unsol_event = alc880_medion_rim_unsol_event,
3917 .init_hook = alc880_medion_rim_automute,
3919 #ifdef CONFIG_SND_DEBUG
3921 .mixers = { alc880_test_mixer },
3922 .init_verbs = { alc880_test_init_verbs },
3923 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3924 .dac_nids = alc880_test_dac_nids,
3925 .dig_out_nid = ALC880_DIGOUT_NID,
3926 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3927 .channel_mode = alc880_test_modes,
3928 .input_mux = &alc880_test_capture_source,
3934 * Automatic parse of I/O pins from the BIOS configuration
3939 ALC_CTL_WIDGET_MUTE,
3942 static struct snd_kcontrol_new alc880_control_templates[] = {
3943 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3944 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3945 HDA_BIND_MUTE(NULL, 0, 0, 0),
3948 /* add dynamic controls */
3949 static int add_control(struct alc_spec *spec, int type, const char *name,
3952 struct snd_kcontrol_new *knew;
3954 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3955 knew = snd_array_new(&spec->kctls);
3958 *knew = alc880_control_templates[type];
3959 knew->name = kstrdup(name, GFP_KERNEL);
3962 knew->private_value = val;
3966 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3967 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3968 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3969 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3970 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3971 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3972 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3973 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3974 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3975 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3976 #define ALC880_PIN_CD_NID 0x1c
3978 /* fill in the dac_nids table from the parsed pin configuration */
3979 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3980 const struct auto_pin_cfg *cfg)
3986 memset(assigned, 0, sizeof(assigned));
3987 spec->multiout.dac_nids = spec->private_dac_nids;
3989 /* check the pins hardwired to audio widget */
3990 for (i = 0; i < cfg->line_outs; i++) {
3991 nid = cfg->line_out_pins[i];
3992 if (alc880_is_fixed_pin(nid)) {
3993 int idx = alc880_fixed_pin_idx(nid);
3994 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3998 /* left pins can be connect to any audio widget */
3999 for (i = 0; i < cfg->line_outs; i++) {
4000 nid = cfg->line_out_pins[i];
4001 if (alc880_is_fixed_pin(nid))
4003 /* search for an empty channel */
4004 for (j = 0; j < cfg->line_outs; j++) {
4006 spec->multiout.dac_nids[i] =
4007 alc880_idx_to_dac(j);
4013 spec->multiout.num_dacs = cfg->line_outs;
4017 /* add playback controls from the parsed DAC table */
4018 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4019 const struct auto_pin_cfg *cfg)
4022 static const char *chname[4] = {
4023 "Front", "Surround", NULL /*CLFE*/, "Side"
4028 for (i = 0; i < cfg->line_outs; i++) {
4029 if (!spec->multiout.dac_nids[i])
4031 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4034 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4035 "Center Playback Volume",
4036 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4040 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4041 "LFE Playback Volume",
4042 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4046 err = add_control(spec, ALC_CTL_BIND_MUTE,
4047 "Center Playback Switch",
4048 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4052 err = add_control(spec, ALC_CTL_BIND_MUTE,
4053 "LFE Playback Switch",
4054 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4059 sprintf(name, "%s Playback Volume", chname[i]);
4060 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4061 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4065 sprintf(name, "%s Playback Switch", chname[i]);
4066 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4067 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4076 /* add playback controls for speaker and HP outputs */
4077 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4087 if (alc880_is_fixed_pin(pin)) {
4088 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4089 /* specify the DAC as the extra output */
4090 if (!spec->multiout.hp_nid)
4091 spec->multiout.hp_nid = nid;
4093 spec->multiout.extra_out_nid[0] = nid;
4094 /* control HP volume/switch on the output mixer amp */
4095 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4096 sprintf(name, "%s Playback Volume", pfx);
4097 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4098 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4101 sprintf(name, "%s Playback Switch", pfx);
4102 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4103 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4106 } else if (alc880_is_multi_pin(pin)) {
4107 /* set manual connection */
4108 /* we have only a switch on HP-out PIN */
4109 sprintf(name, "%s Playback Switch", pfx);
4110 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4111 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4118 /* create input playback/capture controls for the given pin */
4119 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4120 const char *ctlname,
4121 int idx, hda_nid_t mix_nid)
4126 sprintf(name, "%s Playback Volume", ctlname);
4127 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4128 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4131 sprintf(name, "%s Playback Switch", ctlname);
4132 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4133 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4139 /* create playback/capture controls for input pins */
4140 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4141 const struct auto_pin_cfg *cfg)
4143 struct hda_input_mux *imux = &spec->private_imux[0];
4146 for (i = 0; i < AUTO_PIN_LAST; i++) {
4147 if (alc880_is_input_pin(cfg->input_pins[i])) {
4148 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4149 err = new_analog_input(spec, cfg->input_pins[i],
4150 auto_pin_cfg_labels[i],
4154 imux->items[imux->num_items].label =
4155 auto_pin_cfg_labels[i];
4156 imux->items[imux->num_items].index =
4157 alc880_input_pin_idx(cfg->input_pins[i]);
4164 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4165 unsigned int pin_type)
4167 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4170 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4174 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4175 hda_nid_t nid, int pin_type,
4178 alc_set_pin_output(codec, nid, pin_type);
4179 /* need the manual connection? */
4180 if (alc880_is_multi_pin(nid)) {
4181 struct alc_spec *spec = codec->spec;
4182 int idx = alc880_multi_pin_idx(nid);
4183 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4184 AC_VERB_SET_CONNECT_SEL,
4185 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4189 static int get_pin_type(int line_out_type)
4191 if (line_out_type == AUTO_PIN_HP_OUT)
4197 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4199 struct alc_spec *spec = codec->spec;
4202 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4203 for (i = 0; i < spec->autocfg.line_outs; i++) {
4204 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4205 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4206 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4210 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4212 struct alc_spec *spec = codec->spec;
4215 pin = spec->autocfg.speaker_pins[0];
4216 if (pin) /* connect to front */
4217 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4218 pin = spec->autocfg.hp_pins[0];
4219 if (pin) /* connect to front */
4220 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4223 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4225 struct alc_spec *spec = codec->spec;
4228 for (i = 0; i < AUTO_PIN_LAST; i++) {
4229 hda_nid_t nid = spec->autocfg.input_pins[i];
4230 if (alc880_is_input_pin(nid)) {
4231 alc_set_input_pin(codec, nid, i);
4232 if (nid != ALC880_PIN_CD_NID &&
4233 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4234 snd_hda_codec_write(codec, nid, 0,
4235 AC_VERB_SET_AMP_GAIN_MUTE,
4241 /* parse the BIOS configuration and set up the alc_spec */
4242 /* return 1 if successful, 0 if the proper config is not found,
4243 * or a negative error code
4245 static int alc880_parse_auto_config(struct hda_codec *codec)
4247 struct alc_spec *spec = codec->spec;
4249 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4251 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4255 if (!spec->autocfg.line_outs)
4256 return 0; /* can't find valid BIOS pin config */
4258 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4261 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4264 err = alc880_auto_create_extra_out(spec,
4265 spec->autocfg.speaker_pins[0],
4269 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4273 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4277 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4279 /* check multiple SPDIF-out (for recent codecs) */
4280 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4282 err = snd_hda_get_connections(codec,
4283 spec->autocfg.dig_out_pins[i],
4288 spec->multiout.dig_out_nid = dig_nid;
4290 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4291 spec->slave_dig_outs[i - 1] = dig_nid;
4292 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4296 if (spec->autocfg.dig_in_pin)
4297 spec->dig_in_nid = ALC880_DIGIN_NID;
4299 if (spec->kctls.list)
4300 add_mixer(spec, spec->kctls.list);
4302 add_verb(spec, alc880_volume_init_verbs);
4304 spec->num_mux_defs = 1;
4305 spec->input_mux = &spec->private_imux[0];
4310 /* additional initialization for auto-configuration model */
4311 static void alc880_auto_init(struct hda_codec *codec)
4313 struct alc_spec *spec = codec->spec;
4314 alc880_auto_init_multi_out(codec);
4315 alc880_auto_init_extra_out(codec);
4316 alc880_auto_init_analog_input(codec);
4317 if (spec->unsol_event)
4318 alc_inithook(codec);
4321 static void set_capture_mixer(struct alc_spec *spec)
4323 static struct snd_kcontrol_new *caps[2][3] = {
4324 { alc_capture_mixer_nosrc1,
4325 alc_capture_mixer_nosrc2,
4326 alc_capture_mixer_nosrc3 },
4327 { alc_capture_mixer1,
4329 alc_capture_mixer3 },
4331 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4333 if (spec->input_mux && spec->input_mux->num_items > 1)
4337 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4341 #define set_beep_amp(spec, nid, idx, dir) \
4342 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4345 * OK, here we have finally the patch for ALC880
4348 static int patch_alc880(struct hda_codec *codec)
4350 struct alc_spec *spec;
4354 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4360 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4363 if (board_config < 0) {
4364 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4365 "trying auto-probe from BIOS...\n");
4366 board_config = ALC880_AUTO;
4369 if (board_config == ALC880_AUTO) {
4370 /* automatic parse from the BIOS config */
4371 err = alc880_parse_auto_config(codec);
4377 "hda_codec: Cannot set up configuration "
4378 "from BIOS. Using 3-stack mode...\n");
4379 board_config = ALC880_3ST;
4383 err = snd_hda_attach_beep_device(codec, 0x1);
4389 if (board_config != ALC880_AUTO)
4390 setup_preset(spec, &alc880_presets[board_config]);
4392 spec->stream_name_analog = "ALC880 Analog";
4393 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4394 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4395 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4397 spec->stream_name_digital = "ALC880 Digital";
4398 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4399 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4401 if (!spec->adc_nids && spec->input_mux) {
4402 /* check whether NID 0x07 is valid */
4403 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4405 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4406 if (wcap != AC_WID_AUD_IN) {
4407 spec->adc_nids = alc880_adc_nids_alt;
4408 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4410 spec->adc_nids = alc880_adc_nids;
4411 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4414 set_capture_mixer(spec);
4415 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4417 spec->vmaster_nid = 0x0c;
4419 codec->patch_ops = alc_patch_ops;
4420 if (board_config == ALC880_AUTO)
4421 spec->init_hook = alc880_auto_init;
4422 #ifdef CONFIG_SND_HDA_POWER_SAVE
4423 if (!spec->loopback.amplist)
4424 spec->loopback.amplist = alc880_loopbacks;
4426 codec->proc_widget_hook = print_realtek_coef;
4436 static hda_nid_t alc260_dac_nids[1] = {
4441 static hda_nid_t alc260_adc_nids[1] = {
4446 static hda_nid_t alc260_adc_nids_alt[1] = {
4451 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4452 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4454 static hda_nid_t alc260_dual_adc_nids[2] = {
4459 #define ALC260_DIGOUT_NID 0x03
4460 #define ALC260_DIGIN_NID 0x06
4462 static struct hda_input_mux alc260_capture_source = {
4466 { "Front Mic", 0x1 },
4472 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4473 * headphone jack and the internal CD lines since these are the only pins at
4474 * which audio can appear. For flexibility, also allow the option of
4475 * recording the mixer output on the second ADC (ADC0 doesn't have a
4476 * connection to the mixer output).
4478 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4482 { "Mic/Line", 0x0 },
4484 { "Headphone", 0x2 },
4490 { "Mic/Line", 0x0 },
4492 { "Headphone", 0x2 },
4499 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4500 * the Fujitsu S702x, but jacks are marked differently.
4502 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4509 { "Headphone", 0x5 },
4518 { "Headphone", 0x6 },
4524 /* Maxdata Favorit 100XS */
4525 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4529 { "Line/Mic", 0x0 },
4536 { "Line/Mic", 0x0 },
4544 * This is just place-holder, so there's something for alc_build_pcms to look
4545 * at when it calculates the maximum number of channels. ALC260 has no mixer
4546 * element which allows changing the channel mode, so the verb list is
4549 static struct hda_channel_mode alc260_modes[1] = {
4554 /* Mixer combinations
4556 * basic: base_output + input + pc_beep + capture
4557 * HP: base_output + input + capture_alt
4558 * HP_3013: hp_3013 + input + capture
4559 * fujitsu: fujitsu + capture
4560 * acer: acer + capture
4563 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4564 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4565 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4567 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4569 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4573 static struct snd_kcontrol_new alc260_input_mixer[] = {
4574 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4575 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4576 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4577 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4579 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4585 /* update HP, line and mono out pins according to the master switch */
4586 static void alc260_hp_master_update(struct hda_codec *codec,
4587 hda_nid_t hp, hda_nid_t line,
4590 struct alc_spec *spec = codec->spec;
4591 unsigned int val = spec->master_sw ? PIN_HP : 0;
4592 /* change HP and line-out pins */
4593 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4595 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4597 /* mono (speaker) depending on the HP jack sense */
4598 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4599 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4603 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4604 struct snd_ctl_elem_value *ucontrol)
4606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4607 struct alc_spec *spec = codec->spec;
4608 *ucontrol->value.integer.value = spec->master_sw;
4612 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4613 struct snd_ctl_elem_value *ucontrol)
4615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4616 struct alc_spec *spec = codec->spec;
4617 int val = !!*ucontrol->value.integer.value;
4618 hda_nid_t hp, line, mono;
4620 if (val == spec->master_sw)
4622 spec->master_sw = val;
4623 hp = (kcontrol->private_value >> 16) & 0xff;
4624 line = (kcontrol->private_value >> 8) & 0xff;
4625 mono = kcontrol->private_value & 0xff;
4626 alc260_hp_master_update(codec, hp, line, mono);
4630 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4633 .name = "Master Playback Switch",
4634 .info = snd_ctl_boolean_mono_info,
4635 .get = alc260_hp_master_sw_get,
4636 .put = alc260_hp_master_sw_put,
4637 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4639 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4640 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4641 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4642 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4643 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4645 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4649 static struct hda_verb alc260_hp_unsol_verbs[] = {
4650 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4654 static void alc260_hp_automute(struct hda_codec *codec)
4656 struct alc_spec *spec = codec->spec;
4657 unsigned int present;
4659 present = snd_hda_codec_read(codec, 0x10, 0,
4660 AC_VERB_GET_PIN_SENSE, 0);
4661 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4662 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4665 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4667 if ((res >> 26) == ALC880_HP_EVENT)
4668 alc260_hp_automute(codec);
4671 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4674 .name = "Master Playback Switch",
4675 .info = snd_ctl_boolean_mono_info,
4676 .get = alc260_hp_master_sw_get,
4677 .put = alc260_hp_master_sw_put,
4678 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4680 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4681 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4682 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4683 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4686 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4687 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4691 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4692 .ops = &snd_hda_bind_vol,
4694 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4695 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4696 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4701 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4702 .ops = &snd_hda_bind_sw,
4704 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4705 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4710 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4711 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4712 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4713 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4718 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4719 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4723 static void alc260_hp_3013_automute(struct hda_codec *codec)
4725 struct alc_spec *spec = codec->spec;
4726 unsigned int present;
4728 present = snd_hda_codec_read(codec, 0x15, 0,
4729 AC_VERB_GET_PIN_SENSE, 0);
4730 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4731 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4734 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4737 if ((res >> 26) == ALC880_HP_EVENT)
4738 alc260_hp_3013_automute(codec);
4741 static void alc260_hp_3012_automute(struct hda_codec *codec)
4743 unsigned int present, bits;
4745 present = snd_hda_codec_read(codec, 0x10, 0,
4746 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4748 bits = present ? 0 : PIN_OUT;
4749 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4751 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4753 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4757 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4760 if ((res >> 26) == ALC880_HP_EVENT)
4761 alc260_hp_3012_automute(codec);
4764 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4765 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4767 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4768 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4769 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4770 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4771 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4772 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4773 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4774 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4775 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4776 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4777 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4781 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4782 * versions of the ALC260 don't act on requests to enable mic bias from NID
4783 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4784 * datasheet doesn't mention this restriction. At this stage it's not clear
4785 * whether this behaviour is intentional or is a hardware bug in chip
4786 * revisions available in early 2006. Therefore for now allow the
4787 * "Headphone Jack Mode" control to span all choices, but if it turns out
4788 * that the lack of mic bias for this NID is intentional we could change the
4789 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4791 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4792 * don't appear to make the mic bias available from the "line" jack, even
4793 * though the NID used for this jack (0x14) can supply it. The theory is
4794 * that perhaps Acer have included blocking capacitors between the ALC260
4795 * and the output jack. If this turns out to be the case for all such
4796 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4797 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4799 * The C20x Tablet series have a mono internal speaker which is controlled
4800 * via the chip's Mono sum widget and pin complex, so include the necessary
4801 * controls for such models. On models without a "mono speaker" the control
4802 * won't do anything.
4804 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4805 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4806 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4807 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4808 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4810 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4812 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4813 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4815 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4816 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4817 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4818 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4819 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4823 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4825 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
4826 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4827 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4828 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4829 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4830 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4831 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4835 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4836 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4838 static struct snd_kcontrol_new alc260_will_mixer[] = {
4839 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4840 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4842 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4843 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4844 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4845 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4846 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4847 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4848 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4852 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4853 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4855 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4856 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4857 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4859 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4860 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4861 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4862 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4863 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4864 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4865 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4870 * initialization verbs
4872 static struct hda_verb alc260_init_verbs[] = {
4873 /* Line In pin widget for input */
4874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4875 /* CD pin widget for input */
4876 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4877 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4878 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4879 /* Mic2 (front panel) pin widget for input and vref at 80% */
4880 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4881 /* LINE-2 is used for line-out in rear */
4882 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4883 /* select line-out */
4884 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4886 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4888 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4890 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4891 /* mute capture amp left and right */
4892 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4893 /* set connection select to line in (default select for this ADC) */
4894 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4895 /* mute capture amp left and right */
4896 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4897 /* set connection select to line in (default select for this ADC) */
4898 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4899 /* set vol=0 Line-Out mixer amp left and right */
4900 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4901 /* unmute pin widget amp left and right (no gain on this amp) */
4902 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4903 /* set vol=0 HP mixer amp left and right */
4904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4905 /* unmute pin widget amp left and right (no gain on this amp) */
4906 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4907 /* set vol=0 Mono mixer amp left and right */
4908 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4909 /* unmute pin widget amp left and right (no gain on this amp) */
4910 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4911 /* unmute LINE-2 out pin */
4912 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4913 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4916 /* mute analog inputs */
4917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4918 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4919 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4921 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4922 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4923 /* mute Front out path */
4924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4925 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4926 /* mute Headphone out path */
4927 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4929 /* mute Mono out path */
4930 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4931 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4935 #if 0 /* should be identical with alc260_init_verbs? */
4936 static struct hda_verb alc260_hp_init_verbs[] = {
4937 /* Headphone and output */
4938 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4940 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4941 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4942 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4943 /* Mic2 (front panel) pin widget for input and vref at 80% */
4944 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4945 /* Line In pin widget for input */
4946 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4947 /* Line-2 pin widget for output */
4948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4949 /* CD pin widget for input */
4950 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4951 /* unmute amp left and right */
4952 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4953 /* set connection select to line in (default select for this ADC) */
4954 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4955 /* unmute Line-Out mixer amp left and right (volume = 0) */
4956 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4957 /* mute pin widget amp left and right (no gain on this amp) */
4958 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4959 /* unmute HP mixer amp left and right (volume = 0) */
4960 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4961 /* mute pin widget amp left and right (no gain on this amp) */
4962 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4963 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4966 /* mute analog inputs */
4967 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4968 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4969 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4972 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4973 /* Unmute Front out path */
4974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4975 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4976 /* Unmute Headphone out path */
4977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4978 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4979 /* Unmute Mono out path */
4980 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4981 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4986 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4987 /* Line out and output */
4988 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4990 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4991 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4992 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4993 /* Mic2 (front panel) pin widget for input and vref at 80% */
4994 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4995 /* Line In pin widget for input */
4996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4997 /* Headphone pin widget for output */
4998 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4999 /* CD pin widget for input */
5000 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5001 /* unmute amp left and right */
5002 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5003 /* set connection select to line in (default select for this ADC) */
5004 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5005 /* unmute Line-Out mixer amp left and right (volume = 0) */
5006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5007 /* mute pin widget amp left and right (no gain on this amp) */
5008 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5009 /* unmute HP mixer amp left and right (volume = 0) */
5010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5011 /* mute pin widget amp left and right (no gain on this amp) */
5012 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5013 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5016 /* mute analog inputs */
5017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5019 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5021 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5022 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5023 /* Unmute Front out path */
5024 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5025 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5026 /* Unmute Headphone out path */
5027 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5028 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5029 /* Unmute Mono out path */
5030 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5031 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5035 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5036 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5037 * audio = 0x16, internal speaker = 0x10.
5039 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5040 /* Disable all GPIOs */
5041 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5042 /* Internal speaker is connected to headphone pin */
5043 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5044 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5045 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5046 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5047 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5048 /* Ensure all other unused pins are disabled and muted. */
5049 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5051 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5052 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5053 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5054 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5055 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5056 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5058 /* Disable digital (SPDIF) pins */
5059 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5060 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5062 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5063 * when acting as an output.
5065 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5067 /* Start with output sum widgets muted and their output gains at min */
5068 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5073 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5075 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5076 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5078 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5079 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5080 /* Unmute Line1 pin widget output buffer since it starts as an output.
5081 * If the pin mode is changed by the user the pin mode control will
5082 * take care of enabling the pin's input/output buffers as needed.
5083 * Therefore there's no need to enable the input buffer at this
5086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5087 /* Unmute input buffer of pin widget used for Line-in (no equiv
5090 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5092 /* Mute capture amp left and right */
5093 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5094 /* Set ADC connection select to match default mixer setting - line
5097 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5099 /* Do the same for the second ADC: mute capture input amp and
5100 * set ADC connection to line in (on mic1 pin)
5102 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5105 /* Mute all inputs to mixer widget (even unconnected ones) */
5106 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5108 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5109 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5110 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5118 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5119 * similar laptops (adapted from Fujitsu init verbs).
5121 static struct hda_verb alc260_acer_init_verbs[] = {
5122 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5123 * the headphone jack. Turn this on and rely on the standard mute
5124 * methods whenever the user wants to turn these outputs off.
5126 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5127 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5128 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5129 /* Internal speaker/Headphone jack is connected to Line-out pin */
5130 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5131 /* Internal microphone/Mic jack is connected to Mic1 pin */
5132 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5133 /* Line In jack is connected to Line1 pin */
5134 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5135 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5136 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5137 /* Ensure all other unused pins are disabled and muted. */
5138 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5139 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5140 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5141 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5142 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5143 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5144 /* Disable digital (SPDIF) pins */
5145 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5146 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5148 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5149 * bus when acting as outputs.
5151 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5152 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5154 /* Start with output sum widgets muted and their output gains at min */
5155 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5158 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5160 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5161 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5163 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5165 /* Unmute Line-out pin widget amp left and right
5166 * (no equiv mixer ctrl)
5168 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5169 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5170 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5171 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5172 * inputs. If the pin mode is changed by the user the pin mode control
5173 * will take care of enabling the pin's input/output buffers as needed.
5174 * Therefore there's no need to enable the input buffer at this
5177 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5178 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5180 /* Mute capture amp left and right */
5181 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5182 /* Set ADC connection select to match default mixer setting - mic
5185 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5187 /* Do similar with the second ADC: mute capture input amp and
5188 * set ADC connection to mic to match ALSA's default state.
5190 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5191 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5193 /* Mute all inputs to mixer widget (even unconnected ones) */
5194 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5196 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5197 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5206 /* Initialisation sequence for Maxdata Favorit 100XS
5207 * (adapted from Acer init verbs).
5209 static struct hda_verb alc260_favorit100_init_verbs[] = {
5210 /* GPIO 0 enables the output jack.
5211 * Turn this on and rely on the standard mute
5212 * methods whenever the user wants to turn these outputs off.
5214 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5215 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5216 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5217 /* Line/Mic input jack is connected to Mic1 pin */
5218 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5219 /* Ensure all other unused pins are disabled and muted. */
5220 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5221 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5222 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5223 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5224 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5225 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5226 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5227 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5229 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5230 /* Disable digital (SPDIF) pins */
5231 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5232 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5234 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5235 * bus when acting as outputs.
5237 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5238 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5240 /* Start with output sum widgets muted and their output gains at min */
5241 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5243 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5247 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5248 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5249 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5251 /* Unmute Line-out pin widget amp left and right
5252 * (no equiv mixer ctrl)
5254 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5255 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5256 * inputs. If the pin mode is changed by the user the pin mode control
5257 * will take care of enabling the pin's input/output buffers as needed.
5258 * Therefore there's no need to enable the input buffer at this
5261 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5263 /* Mute capture amp left and right */
5264 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5265 /* Set ADC connection select to match default mixer setting - mic
5268 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5270 /* Do similar with the second ADC: mute capture input amp and
5271 * set ADC connection to mic to match ALSA's default state.
5273 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5274 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5276 /* Mute all inputs to mixer widget (even unconnected ones) */
5277 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5280 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5283 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5289 static struct hda_verb alc260_will_verbs[] = {
5290 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5291 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5292 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5293 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5294 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5295 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5299 static struct hda_verb alc260_replacer_672v_verbs[] = {
5300 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5301 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5302 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5304 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5305 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5306 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5308 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5312 /* toggle speaker-output according to the hp-jack state */
5313 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5315 unsigned int present;
5317 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5318 present = snd_hda_codec_read(codec, 0x0f, 0,
5319 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5321 snd_hda_codec_write_cache(codec, 0x01, 0,
5322 AC_VERB_SET_GPIO_DATA, 1);
5323 snd_hda_codec_write_cache(codec, 0x0f, 0,
5324 AC_VERB_SET_PIN_WIDGET_CONTROL,
5327 snd_hda_codec_write_cache(codec, 0x01, 0,
5328 AC_VERB_SET_GPIO_DATA, 0);
5329 snd_hda_codec_write_cache(codec, 0x0f, 0,
5330 AC_VERB_SET_PIN_WIDGET_CONTROL,
5335 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5338 if ((res >> 26) == ALC880_HP_EVENT)
5339 alc260_replacer_672v_automute(codec);
5342 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5343 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5345 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5346 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5347 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5349 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5350 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5351 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5356 /* Test configuration for debugging, modelled after the ALC880 test
5359 #ifdef CONFIG_SND_DEBUG
5360 static hda_nid_t alc260_test_dac_nids[1] = {
5363 static hda_nid_t alc260_test_adc_nids[2] = {
5366 /* For testing the ALC260, each input MUX needs its own definition since
5367 * the signal assignments are different. This assumes that the first ADC
5370 static struct hda_input_mux alc260_test_capture_sources[2] = {
5374 { "MIC1 pin", 0x0 },
5375 { "MIC2 pin", 0x1 },
5376 { "LINE1 pin", 0x2 },
5377 { "LINE2 pin", 0x3 },
5379 { "LINE-OUT pin", 0x5 },
5380 { "HP-OUT pin", 0x6 },
5386 { "MIC1 pin", 0x0 },
5387 { "MIC2 pin", 0x1 },
5388 { "LINE1 pin", 0x2 },
5389 { "LINE2 pin", 0x3 },
5392 { "LINE-OUT pin", 0x6 },
5393 { "HP-OUT pin", 0x7 },
5397 static struct snd_kcontrol_new alc260_test_mixer[] = {
5398 /* Output driver widgets */
5399 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5400 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5401 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5402 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5403 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5404 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5406 /* Modes for retasking pin widgets
5407 * Note: the ALC260 doesn't seem to act on requests to enable mic
5408 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5409 * mention this restriction. At this stage it's not clear whether
5410 * this behaviour is intentional or is a hardware bug in chip
5411 * revisions available at least up until early 2006. Therefore for
5412 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5413 * choices, but if it turns out that the lack of mic bias for these
5414 * NIDs is intentional we could change their modes from
5415 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5417 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5418 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5419 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5420 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5421 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5422 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5424 /* Loopback mixer controls */
5425 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5426 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5427 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5428 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5429 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5430 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5431 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5432 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5433 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5434 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5435 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5436 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5437 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5438 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5440 /* Controls for GPIO pins, assuming they are configured as outputs */
5441 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5442 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5443 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5444 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5446 /* Switches to allow the digital IO pins to be enabled. The datasheet
5447 * is ambigious as to which NID is which; testing on laptops which
5448 * make this output available should provide clarification.
5450 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5451 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5453 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5454 * this output to turn on an external amplifier.
5456 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5457 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5461 static struct hda_verb alc260_test_init_verbs[] = {
5462 /* Enable all GPIOs as outputs with an initial value of 0 */
5463 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5464 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5465 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5467 /* Enable retasking pins as output, initially without power amp */
5468 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5469 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5471 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5472 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5475 /* Disable digital (SPDIF) pins initially, but users can enable
5476 * them via a mixer switch. In the case of SPDIF-out, this initverb
5477 * payload also sets the generation to 0, output to be in "consumer"
5478 * PCM format, copyright asserted, no pre-emphasis and no validity
5481 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5482 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5484 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5485 * OUT1 sum bus when acting as an output.
5487 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5488 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5489 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5490 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5492 /* Start with output sum widgets muted and their output gains at min */
5493 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5494 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5497 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5498 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5499 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5500 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5501 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5503 /* Unmute retasking pin widget output buffers since the default
5504 * state appears to be output. As the pin mode is changed by the
5505 * user the pin mode control will take care of enabling the pin's
5506 * input/output buffers as needed.
5508 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5511 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5512 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5513 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5514 /* Also unmute the mono-out pin widget */
5515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5517 /* Mute capture amp left and right */
5518 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5519 /* Set ADC connection select to match default mixer setting (mic1
5522 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5524 /* Do the same for the second ADC: mute capture input amp and
5525 * set ADC connection to mic1 pin
5527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5528 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5530 /* Mute all inputs to mixer widget (even unconnected ones) */
5531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5533 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5534 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5535 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5544 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5545 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5547 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5548 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5551 * for BIOS auto-configuration
5554 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5555 const char *pfx, int *vol_bits)
5558 unsigned long vol_val, sw_val;
5562 if (nid >= 0x0f && nid < 0x11) {
5563 nid_vol = nid - 0x7;
5564 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5565 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5566 } else if (nid == 0x11) {
5567 nid_vol = nid - 0x7;
5568 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5569 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5570 } else if (nid >= 0x12 && nid <= 0x15) {
5572 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5573 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5577 if (!(*vol_bits & (1 << nid_vol))) {
5578 /* first control for the volume widget */
5579 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5580 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5583 *vol_bits |= (1 << nid_vol);
5585 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5586 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5592 /* add playback controls from the parsed DAC table */
5593 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5594 const struct auto_pin_cfg *cfg)
5600 spec->multiout.num_dacs = 1;
5601 spec->multiout.dac_nids = spec->private_dac_nids;
5602 spec->multiout.dac_nids[0] = 0x02;
5604 nid = cfg->line_out_pins[0];
5606 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5611 nid = cfg->speaker_pins[0];
5613 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5618 nid = cfg->hp_pins[0];
5620 err = alc260_add_playback_controls(spec, nid, "Headphone",
5628 /* create playback/capture controls for input pins */
5629 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5630 const struct auto_pin_cfg *cfg)
5632 struct hda_input_mux *imux = &spec->private_imux[0];
5635 for (i = 0; i < AUTO_PIN_LAST; i++) {
5636 if (cfg->input_pins[i] >= 0x12) {
5637 idx = cfg->input_pins[i] - 0x12;
5638 err = new_analog_input(spec, cfg->input_pins[i],
5639 auto_pin_cfg_labels[i], idx,
5643 imux->items[imux->num_items].label =
5644 auto_pin_cfg_labels[i];
5645 imux->items[imux->num_items].index = idx;
5648 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5649 idx = cfg->input_pins[i] - 0x09;
5650 err = new_analog_input(spec, cfg->input_pins[i],
5651 auto_pin_cfg_labels[i], idx,
5655 imux->items[imux->num_items].label =
5656 auto_pin_cfg_labels[i];
5657 imux->items[imux->num_items].index = idx;
5664 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5665 hda_nid_t nid, int pin_type,
5668 alc_set_pin_output(codec, nid, pin_type);
5669 /* need the manual connection? */
5671 int idx = nid - 0x12;
5672 snd_hda_codec_write(codec, idx + 0x0b, 0,
5673 AC_VERB_SET_CONNECT_SEL, sel_idx);
5677 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5679 struct alc_spec *spec = codec->spec;
5682 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5683 nid = spec->autocfg.line_out_pins[0];
5685 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5686 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5689 nid = spec->autocfg.speaker_pins[0];
5691 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5693 nid = spec->autocfg.hp_pins[0];
5695 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5698 #define ALC260_PIN_CD_NID 0x16
5699 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5701 struct alc_spec *spec = codec->spec;
5704 for (i = 0; i < AUTO_PIN_LAST; i++) {
5705 hda_nid_t nid = spec->autocfg.input_pins[i];
5707 alc_set_input_pin(codec, nid, i);
5708 if (nid != ALC260_PIN_CD_NID &&
5709 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5710 snd_hda_codec_write(codec, nid, 0,
5711 AC_VERB_SET_AMP_GAIN_MUTE,
5718 * generic initialization of ADC, input mixers and output mixers
5720 static struct hda_verb alc260_volume_init_verbs[] = {
5722 * Unmute ADC0-1 and set the default input to mic-in
5724 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5725 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5726 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5727 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5729 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5731 * Note: PASD motherboards uses the Line In 2 as the input for
5732 * front panel mic (mic 2)
5734 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5735 /* mute analog inputs */
5736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5743 * Set up output mixers (0x08 - 0x0a)
5745 /* set vol=0 to output mixers */
5746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5747 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5748 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5749 /* set up input amps for analog loopback */
5750 /* Amp Indices: DAC = 0, mixer = 1 */
5751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5755 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5756 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5761 static int alc260_parse_auto_config(struct hda_codec *codec)
5763 struct alc_spec *spec = codec->spec;
5765 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5767 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5771 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5774 if (!spec->kctls.list)
5775 return 0; /* can't find valid BIOS pin config */
5776 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5780 spec->multiout.max_channels = 2;
5782 if (spec->autocfg.dig_outs)
5783 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5784 if (spec->kctls.list)
5785 add_mixer(spec, spec->kctls.list);
5787 add_verb(spec, alc260_volume_init_verbs);
5789 spec->num_mux_defs = 1;
5790 spec->input_mux = &spec->private_imux[0];
5795 /* additional initialization for auto-configuration model */
5796 static void alc260_auto_init(struct hda_codec *codec)
5798 struct alc_spec *spec = codec->spec;
5799 alc260_auto_init_multi_out(codec);
5800 alc260_auto_init_analog_input(codec);
5801 if (spec->unsol_event)
5802 alc_inithook(codec);
5805 #ifdef CONFIG_SND_HDA_POWER_SAVE
5806 static struct hda_amp_list alc260_loopbacks[] = {
5807 { 0x07, HDA_INPUT, 0 },
5808 { 0x07, HDA_INPUT, 1 },
5809 { 0x07, HDA_INPUT, 2 },
5810 { 0x07, HDA_INPUT, 3 },
5811 { 0x07, HDA_INPUT, 4 },
5817 * ALC260 configurations
5819 static const char *alc260_models[ALC260_MODEL_LAST] = {
5820 [ALC260_BASIC] = "basic",
5822 [ALC260_HP_3013] = "hp-3013",
5823 [ALC260_HP_DC7600] = "hp-dc7600",
5824 [ALC260_FUJITSU_S702X] = "fujitsu",
5825 [ALC260_ACER] = "acer",
5826 [ALC260_WILL] = "will",
5827 [ALC260_REPLACER_672V] = "replacer",
5828 [ALC260_FAVORIT100] = "favorit100",
5829 #ifdef CONFIG_SND_DEBUG
5830 [ALC260_TEST] = "test",
5832 [ALC260_AUTO] = "auto",
5835 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5836 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5837 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5838 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
5839 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5840 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5841 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5842 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5843 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5844 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5845 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5846 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5847 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5848 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5849 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5850 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5851 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5852 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5853 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5854 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5858 static struct alc_config_preset alc260_presets[] = {
5860 .mixers = { alc260_base_output_mixer,
5861 alc260_input_mixer },
5862 .init_verbs = { alc260_init_verbs },
5863 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5864 .dac_nids = alc260_dac_nids,
5865 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5866 .adc_nids = alc260_adc_nids,
5867 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5868 .channel_mode = alc260_modes,
5869 .input_mux = &alc260_capture_source,
5872 .mixers = { alc260_hp_output_mixer,
5873 alc260_input_mixer },
5874 .init_verbs = { alc260_init_verbs,
5875 alc260_hp_unsol_verbs },
5876 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5877 .dac_nids = alc260_dac_nids,
5878 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5879 .adc_nids = alc260_adc_nids_alt,
5880 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5881 .channel_mode = alc260_modes,
5882 .input_mux = &alc260_capture_source,
5883 .unsol_event = alc260_hp_unsol_event,
5884 .init_hook = alc260_hp_automute,
5886 [ALC260_HP_DC7600] = {
5887 .mixers = { alc260_hp_dc7600_mixer,
5888 alc260_input_mixer },
5889 .init_verbs = { alc260_init_verbs,
5890 alc260_hp_dc7600_verbs },
5891 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5892 .dac_nids = alc260_dac_nids,
5893 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5894 .adc_nids = alc260_adc_nids_alt,
5895 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5896 .channel_mode = alc260_modes,
5897 .input_mux = &alc260_capture_source,
5898 .unsol_event = alc260_hp_3012_unsol_event,
5899 .init_hook = alc260_hp_3012_automute,
5901 [ALC260_HP_3013] = {
5902 .mixers = { alc260_hp_3013_mixer,
5903 alc260_input_mixer },
5904 .init_verbs = { alc260_hp_3013_init_verbs,
5905 alc260_hp_3013_unsol_verbs },
5906 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5907 .dac_nids = alc260_dac_nids,
5908 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5909 .adc_nids = alc260_adc_nids_alt,
5910 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5911 .channel_mode = alc260_modes,
5912 .input_mux = &alc260_capture_source,
5913 .unsol_event = alc260_hp_3013_unsol_event,
5914 .init_hook = alc260_hp_3013_automute,
5916 [ALC260_FUJITSU_S702X] = {
5917 .mixers = { alc260_fujitsu_mixer },
5918 .init_verbs = { alc260_fujitsu_init_verbs },
5919 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5920 .dac_nids = alc260_dac_nids,
5921 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5922 .adc_nids = alc260_dual_adc_nids,
5923 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5924 .channel_mode = alc260_modes,
5925 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5926 .input_mux = alc260_fujitsu_capture_sources,
5929 .mixers = { alc260_acer_mixer },
5930 .init_verbs = { alc260_acer_init_verbs },
5931 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5932 .dac_nids = alc260_dac_nids,
5933 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5934 .adc_nids = alc260_dual_adc_nids,
5935 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5936 .channel_mode = alc260_modes,
5937 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5938 .input_mux = alc260_acer_capture_sources,
5940 [ALC260_FAVORIT100] = {
5941 .mixers = { alc260_favorit100_mixer },
5942 .init_verbs = { alc260_favorit100_init_verbs },
5943 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5944 .dac_nids = alc260_dac_nids,
5945 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5946 .adc_nids = alc260_dual_adc_nids,
5947 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5948 .channel_mode = alc260_modes,
5949 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
5950 .input_mux = alc260_favorit100_capture_sources,
5953 .mixers = { alc260_will_mixer },
5954 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5955 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5956 .dac_nids = alc260_dac_nids,
5957 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5958 .adc_nids = alc260_adc_nids,
5959 .dig_out_nid = ALC260_DIGOUT_NID,
5960 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5961 .channel_mode = alc260_modes,
5962 .input_mux = &alc260_capture_source,
5964 [ALC260_REPLACER_672V] = {
5965 .mixers = { alc260_replacer_672v_mixer },
5966 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5967 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5968 .dac_nids = alc260_dac_nids,
5969 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5970 .adc_nids = alc260_adc_nids,
5971 .dig_out_nid = ALC260_DIGOUT_NID,
5972 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5973 .channel_mode = alc260_modes,
5974 .input_mux = &alc260_capture_source,
5975 .unsol_event = alc260_replacer_672v_unsol_event,
5976 .init_hook = alc260_replacer_672v_automute,
5978 #ifdef CONFIG_SND_DEBUG
5980 .mixers = { alc260_test_mixer },
5981 .init_verbs = { alc260_test_init_verbs },
5982 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5983 .dac_nids = alc260_test_dac_nids,
5984 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5985 .adc_nids = alc260_test_adc_nids,
5986 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5987 .channel_mode = alc260_modes,
5988 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5989 .input_mux = alc260_test_capture_sources,
5994 static int patch_alc260(struct hda_codec *codec)
5996 struct alc_spec *spec;
5997 int err, board_config;
5999 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6005 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6008 if (board_config < 0) {
6009 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
6010 "trying auto-probe from BIOS...\n");
6011 board_config = ALC260_AUTO;
6014 if (board_config == ALC260_AUTO) {
6015 /* automatic parse from the BIOS config */
6016 err = alc260_parse_auto_config(codec);
6022 "hda_codec: Cannot set up configuration "
6023 "from BIOS. Using base mode...\n");
6024 board_config = ALC260_BASIC;
6028 err = snd_hda_attach_beep_device(codec, 0x1);
6034 if (board_config != ALC260_AUTO)
6035 setup_preset(spec, &alc260_presets[board_config]);
6037 spec->stream_name_analog = "ALC260 Analog";
6038 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6039 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6041 spec->stream_name_digital = "ALC260 Digital";
6042 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6043 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6045 if (!spec->adc_nids && spec->input_mux) {
6046 /* check whether NID 0x04 is valid */
6047 unsigned int wcap = get_wcaps(codec, 0x04);
6048 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6050 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6051 spec->adc_nids = alc260_adc_nids_alt;
6052 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6054 spec->adc_nids = alc260_adc_nids;
6055 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6058 set_capture_mixer(spec);
6059 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6061 spec->vmaster_nid = 0x08;
6063 codec->patch_ops = alc_patch_ops;
6064 if (board_config == ALC260_AUTO)
6065 spec->init_hook = alc260_auto_init;
6066 #ifdef CONFIG_SND_HDA_POWER_SAVE
6067 if (!spec->loopback.amplist)
6068 spec->loopback.amplist = alc260_loopbacks;
6070 codec->proc_widget_hook = print_realtek_coef;
6079 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6080 * configuration. Each pin widget can choose any input DACs and a mixer.
6081 * Each ADC is connected from a mixer of all inputs. This makes possible
6082 * 6-channel independent captures.
6084 * In addition, an independent DAC for the multi-playback (not used in this
6087 #define ALC882_DIGOUT_NID 0x06
6088 #define ALC882_DIGIN_NID 0x0a
6090 static struct hda_channel_mode alc882_ch_modes[1] = {
6094 static hda_nid_t alc882_dac_nids[4] = {
6095 /* front, rear, clfe, rear_surr */
6096 0x02, 0x03, 0x04, 0x05
6099 /* identical with ALC880 */
6100 #define alc882_adc_nids alc880_adc_nids
6101 #define alc882_adc_nids_alt alc880_adc_nids_alt
6103 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6104 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6107 /* FIXME: should be a matrix-type input source selection */
6109 static struct hda_input_mux alc882_capture_source = {
6113 { "Front Mic", 0x1 },
6121 static struct hda_verb alc882_3ST_ch2_init[] = {
6122 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6123 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6124 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6125 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6132 static struct hda_verb alc882_3ST_ch6_init[] = {
6133 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6134 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6135 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6136 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6137 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6138 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6142 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6143 { 2, alc882_3ST_ch2_init },
6144 { 6, alc882_3ST_ch6_init },
6150 static struct hda_verb alc882_sixstack_ch6_init[] = {
6151 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6152 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6153 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6154 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6161 static struct hda_verb alc882_sixstack_ch8_init[] = {
6162 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6163 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6164 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6165 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6169 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6170 { 6, alc882_sixstack_ch6_init },
6171 { 8, alc882_sixstack_ch8_init },
6175 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6181 static struct hda_verb alc885_mbp_ch2_init[] = {
6182 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6183 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6184 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6191 static struct hda_verb alc885_mbp_ch6_init[] = {
6192 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6193 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6194 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6195 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6200 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6201 { 2, alc885_mbp_ch2_init },
6202 { 6, alc885_mbp_ch6_init },
6206 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6207 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6209 static struct snd_kcontrol_new alc882_base_mixer[] = {
6210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6218 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6219 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6220 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6221 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6222 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6226 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6227 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6229 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6230 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6234 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6236 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6237 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6238 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6239 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6240 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6241 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6242 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6243 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6244 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6247 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6249 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6255 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6260 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6261 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6262 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6264 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6265 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6268 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6269 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6270 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6271 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6272 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6273 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6277 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6278 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6280 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6282 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6289 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6290 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6292 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6293 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6297 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6298 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6299 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6300 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6306 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6311 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6314 .name = "Channel Mode",
6315 .info = alc_ch_mode_info,
6316 .get = alc_ch_mode_get,
6317 .put = alc_ch_mode_put,
6322 static struct hda_verb alc882_init_verbs[] = {
6323 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6330 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6332 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6340 /* Front Pin: output 0 (0x0c) */
6341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6342 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6343 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6344 /* Rear Pin: output 1 (0x0d) */
6345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6346 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6347 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6348 /* CLFE Pin: output 2 (0x0e) */
6349 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6350 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6351 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6352 /* Side Pin: output 3 (0x0f) */
6353 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6354 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6355 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6356 /* Mic (rear) pin: input vref at 80% */
6357 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6359 /* Front Mic pin: input vref at 80% */
6360 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6361 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6362 /* Line In pin: input */
6363 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6364 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6365 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6366 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6367 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6368 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6369 /* CD pin widget for input */
6370 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6372 /* FIXME: use matrix-type input source selection */
6373 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6374 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6389 /* ADC1: mute amp left and right */
6390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6392 /* ADC2: mute amp left and right */
6393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6395 /* ADC3: mute amp left and right */
6396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6402 static struct hda_verb alc882_eapd_verbs[] = {
6403 /* change to EAPD mode */
6404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6410 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6412 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6413 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6416 /* FIXME: this looks suspicious...
6417 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6418 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6423 static struct hda_verb alc882_macpro_init_verbs[] = {
6424 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6428 /* Front Pin: output 0 (0x0c) */
6429 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6432 /* Front Mic pin: input vref at 80% */
6433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6435 /* Speaker: output */
6436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6438 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6439 /* Headphone output (output 0 - 0x0c) */
6440 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6441 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6442 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6444 /* FIXME: use matrix-type input source selection */
6445 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6446 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6452 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6453 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6454 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6455 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6457 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6460 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6461 /* ADC1: mute amp left and right */
6462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6463 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6464 /* ADC2: mute amp left and right */
6465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6466 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6467 /* ADC3: mute amp left and right */
6468 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6469 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6474 /* Macbook Pro rev3 */
6475 static struct hda_verb alc885_mbp3_init_verbs[] = {
6476 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6478 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6481 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6482 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6483 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6484 /* Front Pin: output 0 (0x0c) */
6485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6487 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6488 /* HP Pin: output 0 (0x0d) */
6489 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6492 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6493 /* Mic (rear) pin: input vref at 80% */
6494 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6495 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6496 /* Front Mic pin: input vref at 80% */
6497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6498 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6499 /* Line In pin: use output 1 when in LineOut mode */
6500 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6501 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6502 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6504 /* FIXME: use matrix-type input source selection */
6505 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6506 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6510 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6517 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6521 /* ADC1: mute amp left and right */
6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6524 /* ADC2: mute amp left and right */
6525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6527 /* ADC3: mute amp left and right */
6528 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6529 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6534 /* iMac 24 mixer. */
6535 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6536 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6537 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6541 /* iMac 24 init verbs. */
6542 static struct hda_verb alc885_imac24_init_verbs[] = {
6543 /* Internal speakers: output 0 (0x0c) */
6544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6545 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6546 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6547 /* Internal speakers: output 0 (0x0c) */
6548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6549 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6550 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6551 /* Headphone: output 0 (0x0c) */
6552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6555 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6556 /* Front Mic: input vref at 80% */
6557 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6558 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6562 /* Toggle speaker-output according to the hp-jack state */
6563 static void alc885_imac24_automute(struct hda_codec *codec)
6565 unsigned int present;
6567 present = snd_hda_codec_read(codec, 0x14, 0,
6568 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6569 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6570 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6571 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6572 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6575 /* Processes unsolicited events. */
6576 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6579 /* Headphone insertion or removal. */
6580 if ((res >> 26) == ALC880_HP_EVENT)
6581 alc885_imac24_automute(codec);
6584 static void alc885_mbp3_automute(struct hda_codec *codec)
6586 unsigned int present;
6588 present = snd_hda_codec_read(codec, 0x15, 0,
6589 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6590 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6591 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6592 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6593 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6596 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6599 /* Headphone insertion or removal. */
6600 if ((res >> 26) == ALC880_HP_EVENT)
6601 alc885_mbp3_automute(codec);
6605 static struct hda_verb alc882_targa_verbs[] = {
6606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6610 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6612 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6613 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6614 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6616 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6617 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6618 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6619 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6623 /* toggle speaker-output according to the hp-jack state */
6624 static void alc882_targa_automute(struct hda_codec *codec)
6626 unsigned int present;
6628 present = snd_hda_codec_read(codec, 0x14, 0,
6629 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6630 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6631 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6632 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6636 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6638 /* Looks like the unsol event is incompatible with the standard
6639 * definition. 4bit tag is placed at 26 bit!
6641 if (((res >> 26) == ALC880_HP_EVENT)) {
6642 alc882_targa_automute(codec);
6646 static struct hda_verb alc882_asus_a7j_verbs[] = {
6647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6651 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6652 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6654 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6655 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6656 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6658 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6659 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6660 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6664 static struct hda_verb alc882_asus_a7m_verbs[] = {
6665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6670 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6674 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6676 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6677 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6678 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6682 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6684 unsigned int gpiostate, gpiomask, gpiodir;
6686 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6687 AC_VERB_GET_GPIO_DATA, 0);
6690 gpiostate |= (1 << pin);
6692 gpiostate &= ~(1 << pin);
6694 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6695 AC_VERB_GET_GPIO_MASK, 0);
6696 gpiomask |= (1 << pin);
6698 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6699 AC_VERB_GET_GPIO_DIRECTION, 0);
6700 gpiodir |= (1 << pin);
6703 snd_hda_codec_write(codec, codec->afg, 0,
6704 AC_VERB_SET_GPIO_MASK, gpiomask);
6705 snd_hda_codec_write(codec, codec->afg, 0,
6706 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6710 snd_hda_codec_write(codec, codec->afg, 0,
6711 AC_VERB_SET_GPIO_DATA, gpiostate);
6714 /* set up GPIO at initialization */
6715 static void alc885_macpro_init_hook(struct hda_codec *codec)
6717 alc882_gpio_mute(codec, 0, 0);
6718 alc882_gpio_mute(codec, 1, 0);
6721 /* set up GPIO and update auto-muting at initialization */
6722 static void alc885_imac24_init_hook(struct hda_codec *codec)
6724 alc885_macpro_init_hook(codec);
6725 alc885_imac24_automute(codec);
6729 * generic initialization of ADC, input mixers and output mixers
6731 static struct hda_verb alc882_auto_init_verbs[] = {
6733 * Unmute ADC0-2 and set the default input to mic-in
6735 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6737 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6739 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6742 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6744 * Note: PASD motherboards uses the Line In 2 as the input for
6745 * front panel mic (mic 2)
6747 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6755 * Set up output mixers (0x0c - 0x0f)
6757 /* set vol=0 to output mixers */
6758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6761 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6762 /* set up input amps for analog loopback */
6763 /* Amp Indices: DAC = 0, mixer = 1 */
6764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6766 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6767 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6768 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6769 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6770 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6771 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6772 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6773 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6775 /* FIXME: use matrix-type input source selection */
6776 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6777 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6780 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6781 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6785 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6786 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6796 #ifdef CONFIG_SND_HDA_POWER_SAVE
6797 #define alc882_loopbacks alc880_loopbacks
6800 /* pcm configuration: identiacal with ALC880 */
6801 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6802 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6803 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6804 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6807 * configuration and preset
6809 static const char *alc882_models[ALC882_MODEL_LAST] = {
6810 [ALC882_3ST_DIG] = "3stack-dig",
6811 [ALC882_6ST_DIG] = "6stack-dig",
6812 [ALC882_ARIMA] = "arima",
6813 [ALC882_W2JC] = "w2jc",
6814 [ALC882_TARGA] = "targa",
6815 [ALC882_ASUS_A7J] = "asus-a7j",
6816 [ALC882_ASUS_A7M] = "asus-a7m",
6817 [ALC885_MACPRO] = "macpro",
6818 [ALC885_MBP3] = "mbp3",
6819 [ALC885_IMAC24] = "imac24",
6820 [ALC882_AUTO] = "auto",
6823 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6824 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6825 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6826 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6827 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6828 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6829 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6830 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6831 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6832 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6833 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6834 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6835 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6839 static struct alc_config_preset alc882_presets[] = {
6840 [ALC882_3ST_DIG] = {
6841 .mixers = { alc882_base_mixer },
6842 .init_verbs = { alc882_init_verbs },
6843 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6844 .dac_nids = alc882_dac_nids,
6845 .dig_out_nid = ALC882_DIGOUT_NID,
6846 .dig_in_nid = ALC882_DIGIN_NID,
6847 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6848 .channel_mode = alc882_ch_modes,
6850 .input_mux = &alc882_capture_source,
6852 [ALC882_6ST_DIG] = {
6853 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6854 .init_verbs = { alc882_init_verbs },
6855 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6856 .dac_nids = alc882_dac_nids,
6857 .dig_out_nid = ALC882_DIGOUT_NID,
6858 .dig_in_nid = ALC882_DIGIN_NID,
6859 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6860 .channel_mode = alc882_sixstack_modes,
6861 .input_mux = &alc882_capture_source,
6864 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6865 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6866 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6867 .dac_nids = alc882_dac_nids,
6868 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6869 .channel_mode = alc882_sixstack_modes,
6870 .input_mux = &alc882_capture_source,
6873 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6874 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6875 alc880_gpio1_init_verbs },
6876 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6877 .dac_nids = alc882_dac_nids,
6878 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6879 .channel_mode = alc880_threestack_modes,
6881 .input_mux = &alc882_capture_source,
6882 .dig_out_nid = ALC882_DIGOUT_NID,
6885 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6886 .init_verbs = { alc885_mbp3_init_verbs,
6887 alc880_gpio1_init_verbs },
6888 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6889 .dac_nids = alc882_dac_nids,
6890 .channel_mode = alc885_mbp_6ch_modes,
6891 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6892 .input_mux = &alc882_capture_source,
6893 .dig_out_nid = ALC882_DIGOUT_NID,
6894 .dig_in_nid = ALC882_DIGIN_NID,
6895 .unsol_event = alc885_mbp3_unsol_event,
6896 .init_hook = alc885_mbp3_automute,
6899 .mixers = { alc882_macpro_mixer },
6900 .init_verbs = { alc882_macpro_init_verbs },
6901 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6902 .dac_nids = alc882_dac_nids,
6903 .dig_out_nid = ALC882_DIGOUT_NID,
6904 .dig_in_nid = ALC882_DIGIN_NID,
6905 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6906 .channel_mode = alc882_ch_modes,
6907 .input_mux = &alc882_capture_source,
6908 .init_hook = alc885_macpro_init_hook,
6911 .mixers = { alc885_imac24_mixer },
6912 .init_verbs = { alc885_imac24_init_verbs },
6913 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6914 .dac_nids = alc882_dac_nids,
6915 .dig_out_nid = ALC882_DIGOUT_NID,
6916 .dig_in_nid = ALC882_DIGIN_NID,
6917 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6918 .channel_mode = alc882_ch_modes,
6919 .input_mux = &alc882_capture_source,
6920 .unsol_event = alc885_imac24_unsol_event,
6921 .init_hook = alc885_imac24_init_hook,
6924 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6925 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6926 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6927 .dac_nids = alc882_dac_nids,
6928 .dig_out_nid = ALC882_DIGOUT_NID,
6929 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6930 .adc_nids = alc882_adc_nids,
6931 .capsrc_nids = alc882_capsrc_nids,
6932 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6933 .channel_mode = alc882_3ST_6ch_modes,
6935 .input_mux = &alc882_capture_source,
6936 .unsol_event = alc882_targa_unsol_event,
6937 .init_hook = alc882_targa_automute,
6939 [ALC882_ASUS_A7J] = {
6940 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6941 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6942 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6943 .dac_nids = alc882_dac_nids,
6944 .dig_out_nid = ALC882_DIGOUT_NID,
6945 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6946 .adc_nids = alc882_adc_nids,
6947 .capsrc_nids = alc882_capsrc_nids,
6948 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6949 .channel_mode = alc882_3ST_6ch_modes,
6951 .input_mux = &alc882_capture_source,
6953 [ALC882_ASUS_A7M] = {
6954 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6955 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6956 alc880_gpio1_init_verbs,
6957 alc882_asus_a7m_verbs },
6958 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6959 .dac_nids = alc882_dac_nids,
6960 .dig_out_nid = ALC882_DIGOUT_NID,
6961 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6962 .channel_mode = alc880_threestack_modes,
6964 .input_mux = &alc882_capture_source,
6973 PINFIX_ABIT_AW9D_MAX
6976 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6977 { 0x15, 0x01080104 }, /* side */
6978 { 0x16, 0x01011012 }, /* rear */
6979 { 0x17, 0x01016011 }, /* clfe */
6983 static const struct alc_pincfg *alc882_pin_fixes[] = {
6984 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6987 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6988 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6993 * BIOS auto configuration
6995 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6996 hda_nid_t nid, int pin_type,
7000 struct alc_spec *spec = codec->spec;
7003 alc_set_pin_output(codec, nid, pin_type);
7004 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7007 idx = spec->multiout.dac_nids[dac_idx] - 2;
7008 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7012 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7014 struct alc_spec *spec = codec->spec;
7017 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7018 for (i = 0; i <= HDA_SIDE; i++) {
7019 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7022 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7027 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7029 struct alc_spec *spec = codec->spec;
7032 pin = spec->autocfg.hp_pins[0];
7033 if (pin) /* connect to front */
7035 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7036 pin = spec->autocfg.speaker_pins[0];
7038 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7041 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7042 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7044 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7046 struct alc_spec *spec = codec->spec;
7049 for (i = 0; i < AUTO_PIN_LAST; i++) {
7050 hda_nid_t nid = spec->autocfg.input_pins[i];
7053 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7054 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7055 snd_hda_codec_write(codec, nid, 0,
7056 AC_VERB_SET_AMP_GAIN_MUTE,
7061 static void alc882_auto_init_input_src(struct hda_codec *codec)
7063 struct alc_spec *spec = codec->spec;
7066 for (c = 0; c < spec->num_adc_nids; c++) {
7067 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7068 hda_nid_t nid = spec->capsrc_nids[c];
7069 unsigned int mux_idx;
7070 const struct hda_input_mux *imux;
7071 int conns, mute, idx, item;
7073 conns = snd_hda_get_connections(codec, nid, conn_list,
7074 ARRAY_SIZE(conn_list));
7077 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7078 imux = &spec->input_mux[mux_idx];
7079 for (idx = 0; idx < conns; idx++) {
7080 /* if the current connection is the selected one,
7081 * unmute it as default - otherwise mute it
7083 mute = AMP_IN_MUTE(idx);
7084 for (item = 0; item < imux->num_items; item++) {
7085 if (imux->items[item].index == idx) {
7086 if (spec->cur_mux[c] == item)
7087 mute = AMP_IN_UNMUTE(idx);
7091 /* check if we have a selector or mixer
7092 * we could check for the widget type instead, but
7093 * just check for Amp-In presence (in case of mixer
7094 * without amp-in there is something wrong, this
7095 * function shouldn't be used or capsrc nid is wrong)
7097 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7098 snd_hda_codec_write(codec, nid, 0,
7099 AC_VERB_SET_AMP_GAIN_MUTE,
7101 else if (mute != AMP_IN_MUTE(idx))
7102 snd_hda_codec_write(codec, nid, 0,
7103 AC_VERB_SET_CONNECT_SEL,
7109 /* add mic boosts if needed */
7110 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7112 struct alc_spec *spec = codec->spec;
7116 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7117 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7118 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7120 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7124 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7125 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7126 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7128 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7135 /* almost identical with ALC880 parser... */
7136 static int alc882_parse_auto_config(struct hda_codec *codec)
7138 struct alc_spec *spec = codec->spec;
7139 int err = alc880_parse_auto_config(codec);
7144 return 0; /* no config found */
7146 err = alc_auto_add_mic_boost(codec);
7150 /* hack - override the init verbs */
7151 spec->init_verbs[0] = alc882_auto_init_verbs;
7153 return 1; /* config found */
7156 /* additional initialization for auto-configuration model */
7157 static void alc882_auto_init(struct hda_codec *codec)
7159 struct alc_spec *spec = codec->spec;
7160 alc882_auto_init_multi_out(codec);
7161 alc882_auto_init_hp_out(codec);
7162 alc882_auto_init_analog_input(codec);
7163 alc882_auto_init_input_src(codec);
7164 if (spec->unsol_event)
7165 alc_inithook(codec);
7168 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7170 static int patch_alc882(struct hda_codec *codec)
7172 struct alc_spec *spec;
7173 int err, board_config;
7175 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7181 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7185 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7186 /* Pick up systems that don't supply PCI SSID */
7187 switch (codec->subsystem_id) {
7188 case 0x106b0c00: /* Mac Pro */
7189 board_config = ALC885_MACPRO;
7191 case 0x106b1000: /* iMac 24 */
7192 case 0x106b2800: /* AppleTV */
7193 case 0x106b3e00: /* iMac 24 Aluminium */
7194 board_config = ALC885_IMAC24;
7196 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7197 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7198 case 0x106b00a4: /* MacbookPro4,1 */
7199 case 0x106b2c00: /* Macbook Pro rev3 */
7200 case 0x106b3600: /* Macbook 3.1 */
7201 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7202 board_config = ALC885_MBP3;
7205 /* ALC889A is handled better as ALC888-compatible */
7206 if (codec->revision_id == 0x100101 ||
7207 codec->revision_id == 0x100103) {
7209 return patch_alc883(codec);
7211 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
7212 "trying auto-probe from BIOS...\n");
7213 board_config = ALC882_AUTO;
7217 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7219 if (board_config == ALC882_AUTO) {
7220 /* automatic parse from the BIOS config */
7221 err = alc882_parse_auto_config(codec);
7227 "hda_codec: Cannot set up configuration "
7228 "from BIOS. Using base mode...\n");
7229 board_config = ALC882_3ST_DIG;
7233 err = snd_hda_attach_beep_device(codec, 0x1);
7239 if (board_config != ALC882_AUTO)
7240 setup_preset(spec, &alc882_presets[board_config]);
7242 if (codec->vendor_id == 0x10ec0885) {
7243 spec->stream_name_analog = "ALC885 Analog";
7244 spec->stream_name_digital = "ALC885 Digital";
7246 spec->stream_name_analog = "ALC882 Analog";
7247 spec->stream_name_digital = "ALC882 Digital";
7250 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7251 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7252 /* FIXME: setup DAC5 */
7253 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7254 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7256 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7257 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7259 spec->capture_style = CAPT_MIX; /* matrix-style capture */
7260 if (!spec->adc_nids && spec->input_mux) {
7261 /* check whether NID 0x07 is valid */
7262 unsigned int wcap = get_wcaps(codec, 0x07);
7264 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7265 if (wcap != AC_WID_AUD_IN) {
7266 spec->adc_nids = alc882_adc_nids_alt;
7267 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7268 spec->capsrc_nids = alc882_capsrc_nids_alt;
7270 spec->adc_nids = alc882_adc_nids;
7271 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7272 spec->capsrc_nids = alc882_capsrc_nids;
7275 set_capture_mixer(spec);
7276 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7278 spec->vmaster_nid = 0x0c;
7280 codec->patch_ops = alc_patch_ops;
7281 if (board_config == ALC882_AUTO)
7282 spec->init_hook = alc882_auto_init;
7283 #ifdef CONFIG_SND_HDA_POWER_SAVE
7284 if (!spec->loopback.amplist)
7285 spec->loopback.amplist = alc882_loopbacks;
7287 codec->proc_widget_hook = print_realtek_coef;
7295 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7296 * configuration. Each pin widget can choose any input DACs and a mixer.
7297 * Each ADC is connected from a mixer of all inputs. This makes possible
7298 * 6-channel independent captures.
7300 * In addition, an independent DAC for the multi-playback (not used in this
7303 #define ALC883_DIGOUT_NID 0x06
7304 #define ALC883_DIGIN_NID 0x0a
7306 #define ALC1200_DIGOUT_NID 0x10
7308 static hda_nid_t alc883_dac_nids[4] = {
7309 /* front, rear, clfe, rear_surr */
7310 0x02, 0x03, 0x04, 0x05
7313 static hda_nid_t alc883_adc_nids[2] = {
7318 static hda_nid_t alc883_adc_nids_alt[1] = {
7323 static hda_nid_t alc883_adc_nids_rev[2] = {
7328 #define alc889_adc_nids alc880_adc_nids
7330 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7332 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7334 #define alc889_capsrc_nids alc882_capsrc_nids
7337 /* FIXME: should be a matrix-type input source selection */
7339 static struct hda_input_mux alc883_capture_source = {
7343 { "Front Mic", 0x1 },
7349 static struct hda_input_mux alc883_3stack_6ch_intel = {
7353 { "Front Mic", 0x0 },
7359 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7367 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7377 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7385 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7389 { "Front Mic", 0x1 },
7394 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7405 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7412 static struct hda_verb alc883_3ST_ch2_init[] = {
7413 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7414 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7423 static struct hda_verb alc883_3ST_ch4_init[] = {
7424 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7425 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7426 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7427 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7428 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7435 static struct hda_verb alc883_3ST_ch6_init[] = {
7436 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7437 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7438 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7439 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7440 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7441 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7445 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7446 { 2, alc883_3ST_ch2_init },
7447 { 4, alc883_3ST_ch4_init },
7448 { 6, alc883_3ST_ch6_init },
7454 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7455 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7456 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7457 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7458 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7465 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7466 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7467 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7468 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7469 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7470 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7477 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7478 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7479 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7480 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7481 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7482 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7483 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7487 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7488 { 2, alc883_3ST_ch2_intel_init },
7489 { 4, alc883_3ST_ch4_intel_init },
7490 { 6, alc883_3ST_ch6_intel_init },
7496 static struct hda_verb alc883_sixstack_ch6_init[] = {
7497 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7498 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7499 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7500 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7507 static struct hda_verb alc883_sixstack_ch8_init[] = {
7508 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7509 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7510 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7511 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7515 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7516 { 6, alc883_sixstack_ch6_init },
7517 { 8, alc883_sixstack_ch8_init },
7520 static struct hda_verb alc883_medion_eapd_verbs[] = {
7521 /* eanable EAPD on medion laptop */
7522 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7523 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7527 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7528 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7531 static struct snd_kcontrol_new alc883_base_mixer[] = {
7532 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7533 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7535 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7536 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7537 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7538 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7539 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7540 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7541 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7544 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7546 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7551 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7552 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7556 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7557 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7558 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7559 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7560 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7561 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7562 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7564 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7565 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7566 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7568 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7569 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7573 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7575 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7577 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7580 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7581 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7582 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7583 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7587 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7588 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7589 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7590 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7591 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7592 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7594 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7597 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7601 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7602 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7603 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7605 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7606 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7607 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7608 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7611 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7613 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7618 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7619 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7620 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7621 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7622 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7623 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7624 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7625 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7626 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7628 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7629 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7630 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7631 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7633 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7634 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7635 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7636 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7637 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7641 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7642 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7643 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7644 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7645 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7646 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7648 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7649 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7650 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7652 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7653 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7659 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7660 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7661 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7665 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7666 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7667 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7668 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7669 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7670 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7671 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7672 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7673 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7675 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7676 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7677 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7678 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7680 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7682 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7683 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7688 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7690 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7691 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7692 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7693 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7694 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7695 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7696 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7697 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7703 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7708 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7710 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7711 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7712 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7713 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7715 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7717 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7718 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7719 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7723 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7724 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7725 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7726 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7727 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7729 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7730 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7735 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7736 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7737 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7738 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7739 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7740 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7743 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7744 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7748 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7749 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7750 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7751 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7752 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7753 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7754 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7755 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7761 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7762 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7763 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7765 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7766 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7768 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7769 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7773 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7774 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7776 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7777 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7778 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7779 0x0d, 1, 0x0, HDA_OUTPUT),
7780 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7781 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7782 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7783 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7784 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7785 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7786 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7787 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7788 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7789 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7790 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7792 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7794 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7795 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7796 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7800 static struct hda_bind_ctls alc883_bind_cap_vol = {
7801 .ops = &snd_hda_bind_vol,
7803 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7804 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7809 static struct hda_bind_ctls alc883_bind_cap_switch = {
7810 .ops = &snd_hda_bind_sw,
7812 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7813 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7818 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7819 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7820 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7821 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7822 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7823 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7824 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7825 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7826 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7830 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7831 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7832 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7835 /* .name = "Capture Source", */
7836 .name = "Input Source",
7838 .info = alc_mux_enum_info,
7839 .get = alc_mux_enum_get,
7840 .put = alc_mux_enum_put,
7845 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7848 .name = "Channel Mode",
7849 .info = alc_ch_mode_info,
7850 .get = alc_ch_mode_get,
7851 .put = alc_ch_mode_put,
7856 static struct hda_verb alc883_init_verbs[] = {
7857 /* ADC1: mute amp left and right */
7858 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7859 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7860 /* ADC2: mute amp left and right */
7861 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7862 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7863 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7864 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7865 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7866 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7869 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7874 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7876 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7877 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7878 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7880 /* mute analog input loopbacks */
7881 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7887 /* Front Pin: output 0 (0x0c) */
7888 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7889 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7890 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7891 /* Rear Pin: output 1 (0x0d) */
7892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7893 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7895 /* CLFE Pin: output 2 (0x0e) */
7896 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7897 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7898 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7899 /* Side Pin: output 3 (0x0f) */
7900 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7901 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7902 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7903 /* Mic (rear) pin: input vref at 80% */
7904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7906 /* Front Mic pin: input vref at 80% */
7907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7909 /* Line In pin: input */
7910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7912 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7914 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7915 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7916 /* CD pin widget for input */
7917 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7919 /* FIXME: use matrix-type input source selection */
7920 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7934 /* toggle speaker-output according to the hp-jack state */
7935 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7937 unsigned int present;
7939 present = snd_hda_codec_read(codec, 0x15, 0,
7940 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7941 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7942 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7943 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7944 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7947 /* auto-toggle front mic */
7949 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7951 unsigned int present;
7954 present = snd_hda_codec_read(codec, 0x18, 0,
7955 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7956 bits = present ? HDA_AMP_MUTE : 0;
7957 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7961 static void alc883_mitac_automute(struct hda_codec *codec)
7963 alc883_mitac_hp_automute(codec);
7964 /* alc883_mitac_mic_automute(codec); */
7967 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7970 switch (res >> 26) {
7971 case ALC880_HP_EVENT:
7972 alc883_mitac_hp_automute(codec);
7974 case ALC880_MIC_EVENT:
7975 /* alc883_mitac_mic_automute(codec); */
7980 static struct hda_verb alc883_mitac_verbs[] = {
7982 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7983 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7985 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7986 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7988 /* enable unsolicited event */
7989 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7990 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7995 static struct hda_verb alc883_clevo_m720_verbs[] = {
7997 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7998 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8000 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8003 /* enable unsolicited event */
8004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8005 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8010 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8013 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8015 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8016 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8018 /* enable unsolicited event */
8019 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8024 static struct hda_verb alc883_tagra_verbs[] = {
8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8029 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8031 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8032 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8033 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8035 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8036 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
8037 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
8038 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
8043 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8050 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8052 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8053 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8058 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8059 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8063 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8067 static struct hda_verb alc883_haier_w66_verbs[] = {
8068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8073 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8074 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8076 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8080 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8081 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8082 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8083 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8084 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8085 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8086 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8087 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8092 static struct hda_verb alc888_6st_dell_verbs[] = {
8093 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8097 static void alc888_3st_hp_front_automute(struct hda_codec *codec)
8099 unsigned int present, bits;
8101 present = snd_hda_codec_read(codec, 0x1b, 0,
8102 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8103 bits = present ? HDA_AMP_MUTE : 0;
8104 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8105 HDA_AMP_MUTE, bits);
8106 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8107 HDA_AMP_MUTE, bits);
8108 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
8109 HDA_AMP_MUTE, bits);
8112 static void alc888_3st_hp_unsol_event(struct hda_codec *codec,
8115 switch (res >> 26) {
8116 case ALC880_HP_EVENT:
8117 alc888_3st_hp_front_automute(codec);
8122 static struct hda_verb alc888_3st_hp_verbs[] = {
8123 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8124 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8125 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8126 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8133 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8134 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8135 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8136 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8137 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8144 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8145 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8146 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8147 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8148 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8149 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8156 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8157 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8158 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8159 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8161 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8162 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8166 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8167 { 2, alc888_3st_hp_2ch_init },
8168 { 4, alc888_3st_hp_4ch_init },
8169 { 6, alc888_3st_hp_6ch_init },
8172 /* toggle front-jack and RCA according to the hp-jack state */
8173 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8175 unsigned int present;
8177 present = snd_hda_codec_read(codec, 0x1b, 0,
8178 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8179 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8180 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8181 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8182 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8185 /* toggle RCA according to the front-jack state */
8186 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8188 unsigned int present;
8190 present = snd_hda_codec_read(codec, 0x14, 0,
8191 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8192 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8193 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8196 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8199 if ((res >> 26) == ALC880_HP_EVENT)
8200 alc888_lenovo_ms7195_front_automute(codec);
8201 if ((res >> 26) == ALC880_FRONT_EVENT)
8202 alc888_lenovo_ms7195_rca_automute(codec);
8205 static struct hda_verb alc883_medion_md2_verbs[] = {
8206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8209 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8211 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8215 /* toggle speaker-output according to the hp-jack state */
8216 static void alc883_medion_md2_automute(struct hda_codec *codec)
8218 unsigned int present;
8220 present = snd_hda_codec_read(codec, 0x14, 0,
8221 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8222 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8223 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8226 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
8229 if ((res >> 26) == ALC880_HP_EVENT)
8230 alc883_medion_md2_automute(codec);
8233 /* toggle speaker-output according to the hp-jack state */
8234 static void alc883_tagra_automute(struct hda_codec *codec)
8236 unsigned int present;
8239 present = snd_hda_codec_read(codec, 0x14, 0,
8240 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8241 bits = present ? HDA_AMP_MUTE : 0;
8242 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8243 HDA_AMP_MUTE, bits);
8244 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8248 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
8250 if ((res >> 26) == ALC880_HP_EVENT)
8251 alc883_tagra_automute(codec);
8254 /* toggle speaker-output according to the hp-jack state */
8255 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
8257 unsigned int present;
8260 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
8261 & AC_PINSENSE_PRESENCE;
8262 bits = present ? HDA_AMP_MUTE : 0;
8263 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8264 HDA_AMP_MUTE, bits);
8267 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8269 unsigned int present;
8271 present = snd_hda_codec_read(codec, 0x18, 0,
8272 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8273 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8274 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8277 static void alc883_clevo_m720_automute(struct hda_codec *codec)
8279 alc883_clevo_m720_hp_automute(codec);
8280 alc883_clevo_m720_mic_automute(codec);
8283 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8286 switch (res >> 26) {
8287 case ALC880_HP_EVENT:
8288 alc883_clevo_m720_hp_automute(codec);
8290 case ALC880_MIC_EVENT:
8291 alc883_clevo_m720_mic_automute(codec);
8296 /* toggle speaker-output according to the hp-jack state */
8297 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8299 unsigned int present;
8302 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8303 & AC_PINSENSE_PRESENCE;
8304 bits = present ? HDA_AMP_MUTE : 0;
8305 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8306 HDA_AMP_MUTE, bits);
8309 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8312 if ((res >> 26) == ALC880_HP_EVENT)
8313 alc883_2ch_fujitsu_pi2515_automute(codec);
8316 static void alc883_haier_w66_automute(struct hda_codec *codec)
8318 unsigned int present;
8321 present = snd_hda_codec_read(codec, 0x1b, 0,
8322 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8323 bits = present ? 0x80 : 0;
8324 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8328 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8331 if ((res >> 26) == ALC880_HP_EVENT)
8332 alc883_haier_w66_automute(codec);
8335 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8337 unsigned int present;
8340 present = snd_hda_codec_read(codec, 0x14, 0,
8341 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8342 bits = present ? HDA_AMP_MUTE : 0;
8343 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8344 HDA_AMP_MUTE, bits);
8347 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8349 unsigned int present;
8352 present = snd_hda_codec_read(codec, 0x1b, 0,
8353 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8354 bits = present ? HDA_AMP_MUTE : 0;
8355 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8356 HDA_AMP_MUTE, bits);
8357 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8358 HDA_AMP_MUTE, bits);
8361 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8364 if ((res >> 26) == ALC880_HP_EVENT)
8365 alc883_lenovo_101e_all_automute(codec);
8366 if ((res >> 26) == ALC880_FRONT_EVENT)
8367 alc883_lenovo_101e_ispeaker_automute(codec);
8370 /* toggle speaker-output according to the hp-jack state */
8371 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8373 unsigned int present;
8375 present = snd_hda_codec_read(codec, 0x14, 0,
8376 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8377 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8378 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8379 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8380 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8383 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8386 if ((res >> 26) == ALC880_HP_EVENT)
8387 alc883_acer_aspire_automute(codec);
8390 static struct hda_verb alc883_acer_eapd_verbs[] = {
8391 /* HP Pin: output 0 (0x0c) */
8392 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8393 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8394 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8395 /* Front Pin: output 0 (0x0c) */
8396 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8398 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8399 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8400 /* eanable EAPD on medion laptop */
8401 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8402 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8403 /* enable unsolicited event */
8404 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8408 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8410 unsigned int present;
8412 present = snd_hda_codec_read(codec, 0x1b, 0,
8413 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8414 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8415 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8416 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8417 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8418 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8419 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8420 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8421 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8424 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8427 switch (res >> 26) {
8428 case ALC880_HP_EVENT:
8429 /* printk(KERN_DEBUG "hp_event\n"); */
8430 alc888_6st_dell_front_automute(codec);
8435 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8438 unsigned int present;
8440 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8441 present = snd_hda_codec_read(codec, 0x1b, 0,
8442 AC_VERB_GET_PIN_SENSE, 0);
8443 present = (present & 0x80000000) != 0;
8445 /* mute internal speaker */
8446 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8447 HDA_AMP_MUTE, HDA_AMP_MUTE);
8448 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8449 HDA_AMP_MUTE, HDA_AMP_MUTE);
8450 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8451 HDA_AMP_MUTE, HDA_AMP_MUTE);
8452 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8453 HDA_AMP_MUTE, HDA_AMP_MUTE);
8454 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8455 HDA_AMP_MUTE, HDA_AMP_MUTE);
8457 /* unmute internal speaker if necessary */
8458 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8459 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8460 HDA_AMP_MUTE, mute);
8461 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8462 HDA_AMP_MUTE, mute);
8463 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8464 HDA_AMP_MUTE, mute);
8465 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8466 HDA_AMP_MUTE, mute);
8467 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8468 HDA_AMP_MUTE, mute);
8472 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8475 if ((res >> 26) == ALC880_HP_EVENT)
8476 alc888_lenovo_sky_front_automute(codec);
8480 * generic initialization of ADC, input mixers and output mixers
8482 static struct hda_verb alc883_auto_init_verbs[] = {
8484 * Unmute ADC0-2 and set the default input to mic-in
8486 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8487 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8488 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8491 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8493 * Note: PASD motherboards uses the Line In 2 as the input for
8494 * front panel mic (mic 2)
8496 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8504 * Set up output mixers (0x0c - 0x0f)
8506 /* set vol=0 to output mixers */
8507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8511 /* set up input amps for analog loopback */
8512 /* Amp Indices: DAC = 0, mixer = 1 */
8513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8514 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8521 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8524 /* FIXME: use matrix-type input source selection */
8525 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8530 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8531 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8534 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8536 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8537 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8542 static struct hda_verb alc888_asus_m90v_verbs[] = {
8543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8546 /* enable unsolicited event */
8547 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8548 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8552 static void alc883_nb_mic_automute(struct hda_codec *codec)
8554 unsigned int present;
8556 present = snd_hda_codec_read(codec, 0x18, 0,
8557 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8558 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8559 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8560 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8561 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8564 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8566 unsigned int present;
8569 present = snd_hda_codec_read(codec, 0x1b, 0,
8570 AC_VERB_GET_PIN_SENSE, 0)
8571 & AC_PINSENSE_PRESENCE;
8572 bits = present ? 0 : PIN_OUT;
8573 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8575 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8577 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8581 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8584 switch (res >> 26) {
8585 case ALC880_HP_EVENT:
8586 alc883_M90V_speaker_automute(codec);
8588 case ALC880_MIC_EVENT:
8589 alc883_nb_mic_automute(codec);
8594 static void alc883_mode2_inithook(struct hda_codec *codec)
8596 alc883_M90V_speaker_automute(codec);
8597 alc883_nb_mic_automute(codec);
8600 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8602 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8603 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8606 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8607 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8608 /* enable unsolicited event */
8609 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8613 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8615 unsigned int present;
8618 present = snd_hda_codec_read(codec, 0x14, 0,
8619 AC_VERB_GET_PIN_SENSE, 0)
8620 & AC_PINSENSE_PRESENCE;
8621 bits = present ? 0 : PIN_OUT;
8622 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8626 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8629 switch (res >> 26) {
8630 case ALC880_HP_EVENT:
8631 alc883_eee1601_speaker_automute(codec);
8636 static void alc883_eee1601_inithook(struct hda_codec *codec)
8638 alc883_eee1601_speaker_automute(codec);
8641 #ifdef CONFIG_SND_HDA_POWER_SAVE
8642 #define alc883_loopbacks alc880_loopbacks
8645 /* pcm configuration: identiacal with ALC880 */
8646 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8647 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8648 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8649 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8650 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8653 * configuration and preset
8655 static const char *alc883_models[ALC883_MODEL_LAST] = {
8656 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8657 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8658 [ALC883_3ST_6ch] = "3stack-6ch",
8659 [ALC883_6ST_DIG] = "6stack-dig",
8660 [ALC883_TARGA_DIG] = "targa-dig",
8661 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8662 [ALC883_ACER] = "acer",
8663 [ALC883_ACER_ASPIRE] = "acer-aspire",
8664 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8665 [ALC883_MEDION] = "medion",
8666 [ALC883_MEDION_MD2] = "medion-md2",
8667 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8668 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8669 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8670 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8671 [ALC888_LENOVO_SKY] = "lenovo-sky",
8672 [ALC883_HAIER_W66] = "haier-w66",
8673 [ALC888_3ST_HP] = "3stack-hp",
8674 [ALC888_6ST_DELL] = "6stack-dell",
8675 [ALC883_MITAC] = "mitac",
8676 [ALC883_CLEVO_M720] = "clevo-m720",
8677 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8678 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8679 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8680 [ALC1200_ASUS_P5Q] = "asus-p5q",
8681 [ALC883_AUTO] = "auto",
8684 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8685 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8686 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8687 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8688 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8689 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8690 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8691 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8692 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8693 ALC888_ACER_ASPIRE_4930G),
8694 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8695 ALC888_ACER_ASPIRE_4930G),
8696 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
8697 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
8698 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8699 ALC888_ACER_ASPIRE_4930G),
8700 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8701 ALC888_ACER_ASPIRE_4930G),
8703 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER),
8704 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8705 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8706 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8707 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8708 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8709 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8710 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8711 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8712 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8713 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8714 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8715 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8716 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8717 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8718 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8719 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8720 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8721 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8722 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8723 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8724 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8725 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8726 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8727 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8728 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8729 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8730 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8731 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8732 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8733 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8734 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8735 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8736 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8737 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8738 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8739 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8740 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8741 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8742 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8743 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8744 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8745 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8746 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8747 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8748 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8749 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8750 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8751 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8752 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8753 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8754 ALC883_FUJITSU_PI2515),
8755 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8756 ALC888_FUJITSU_XA3530),
8757 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8758 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8759 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8760 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8761 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8762 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8763 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8764 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8765 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8766 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8767 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8768 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8769 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8770 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8774 static hda_nid_t alc883_slave_dig_outs[] = {
8775 ALC1200_DIGOUT_NID, 0,
8778 static hda_nid_t alc1200_slave_dig_outs[] = {
8779 ALC883_DIGOUT_NID, 0,
8782 static struct alc_config_preset alc883_presets[] = {
8783 [ALC883_3ST_2ch_DIG] = {
8784 .mixers = { alc883_3ST_2ch_mixer },
8785 .init_verbs = { alc883_init_verbs },
8786 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8787 .dac_nids = alc883_dac_nids,
8788 .dig_out_nid = ALC883_DIGOUT_NID,
8789 .dig_in_nid = ALC883_DIGIN_NID,
8790 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8791 .channel_mode = alc883_3ST_2ch_modes,
8792 .input_mux = &alc883_capture_source,
8794 [ALC883_3ST_6ch_DIG] = {
8795 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8796 .init_verbs = { alc883_init_verbs },
8797 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8798 .dac_nids = alc883_dac_nids,
8799 .dig_out_nid = ALC883_DIGOUT_NID,
8800 .dig_in_nid = ALC883_DIGIN_NID,
8801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8802 .channel_mode = alc883_3ST_6ch_modes,
8804 .input_mux = &alc883_capture_source,
8806 [ALC883_3ST_6ch] = {
8807 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8808 .init_verbs = { alc883_init_verbs },
8809 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8810 .dac_nids = alc883_dac_nids,
8811 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8812 .channel_mode = alc883_3ST_6ch_modes,
8814 .input_mux = &alc883_capture_source,
8816 [ALC883_3ST_6ch_INTEL] = {
8817 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8818 .init_verbs = { alc883_init_verbs },
8819 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8820 .dac_nids = alc883_dac_nids,
8821 .dig_out_nid = ALC883_DIGOUT_NID,
8822 .dig_in_nid = ALC883_DIGIN_NID,
8823 .slave_dig_outs = alc883_slave_dig_outs,
8824 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8825 .channel_mode = alc883_3ST_6ch_intel_modes,
8827 .input_mux = &alc883_3stack_6ch_intel,
8829 [ALC883_6ST_DIG] = {
8830 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8831 .init_verbs = { alc883_init_verbs },
8832 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8833 .dac_nids = alc883_dac_nids,
8834 .dig_out_nid = ALC883_DIGOUT_NID,
8835 .dig_in_nid = ALC883_DIGIN_NID,
8836 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8837 .channel_mode = alc883_sixstack_modes,
8838 .input_mux = &alc883_capture_source,
8840 [ALC883_TARGA_DIG] = {
8841 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8842 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8843 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8844 .dac_nids = alc883_dac_nids,
8845 .dig_out_nid = ALC883_DIGOUT_NID,
8846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8847 .channel_mode = alc883_3ST_6ch_modes,
8849 .input_mux = &alc883_capture_source,
8850 .unsol_event = alc883_tagra_unsol_event,
8851 .init_hook = alc883_tagra_automute,
8853 [ALC883_TARGA_2ch_DIG] = {
8854 .mixers = { alc883_tagra_2ch_mixer},
8855 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8856 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8857 .dac_nids = alc883_dac_nids,
8858 .adc_nids = alc883_adc_nids_alt,
8859 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8860 .dig_out_nid = ALC883_DIGOUT_NID,
8861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8862 .channel_mode = alc883_3ST_2ch_modes,
8863 .input_mux = &alc883_capture_source,
8864 .unsol_event = alc883_tagra_unsol_event,
8865 .init_hook = alc883_tagra_automute,
8868 .mixers = { alc883_base_mixer },
8869 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8870 * and the headphone jack. Turn this on and rely on the
8871 * standard mute methods whenever the user wants to turn
8872 * these outputs off.
8874 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8875 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8876 .dac_nids = alc883_dac_nids,
8877 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8878 .channel_mode = alc883_3ST_2ch_modes,
8879 .input_mux = &alc883_capture_source,
8881 [ALC883_ACER_ASPIRE] = {
8882 .mixers = { alc883_acer_aspire_mixer },
8883 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8884 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8885 .dac_nids = alc883_dac_nids,
8886 .dig_out_nid = ALC883_DIGOUT_NID,
8887 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8888 .channel_mode = alc883_3ST_2ch_modes,
8889 .input_mux = &alc883_capture_source,
8890 .unsol_event = alc883_acer_aspire_unsol_event,
8891 .init_hook = alc883_acer_aspire_automute,
8893 [ALC888_ACER_ASPIRE_4930G] = {
8894 .mixers = { alc888_base_mixer,
8895 alc883_chmode_mixer },
8896 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8897 alc888_acer_aspire_4930g_verbs },
8898 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8899 .dac_nids = alc883_dac_nids,
8900 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8901 .adc_nids = alc883_adc_nids_rev,
8902 .capsrc_nids = alc883_capsrc_nids_rev,
8903 .dig_out_nid = ALC883_DIGOUT_NID,
8904 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8905 .channel_mode = alc883_3ST_6ch_modes,
8908 ARRAY_SIZE(alc888_2_capture_sources),
8909 .input_mux = alc888_2_capture_sources,
8910 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8911 .init_hook = alc888_acer_aspire_4930g_automute,
8914 .mixers = { alc883_fivestack_mixer,
8915 alc883_chmode_mixer },
8916 .init_verbs = { alc883_init_verbs,
8917 alc883_medion_eapd_verbs },
8918 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8919 .dac_nids = alc883_dac_nids,
8920 .adc_nids = alc883_adc_nids_alt,
8921 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8922 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8923 .channel_mode = alc883_sixstack_modes,
8924 .input_mux = &alc883_capture_source,
8926 [ALC883_MEDION_MD2] = {
8927 .mixers = { alc883_medion_md2_mixer},
8928 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8929 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8930 .dac_nids = alc883_dac_nids,
8931 .dig_out_nid = ALC883_DIGOUT_NID,
8932 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8933 .channel_mode = alc883_3ST_2ch_modes,
8934 .input_mux = &alc883_capture_source,
8935 .unsol_event = alc883_medion_md2_unsol_event,
8936 .init_hook = alc883_medion_md2_automute,
8938 [ALC883_LAPTOP_EAPD] = {
8939 .mixers = { alc883_base_mixer },
8940 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8941 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8942 .dac_nids = alc883_dac_nids,
8943 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8944 .channel_mode = alc883_3ST_2ch_modes,
8945 .input_mux = &alc883_capture_source,
8947 [ALC883_CLEVO_M720] = {
8948 .mixers = { alc883_clevo_m720_mixer },
8949 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8950 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8951 .dac_nids = alc883_dac_nids,
8952 .dig_out_nid = ALC883_DIGOUT_NID,
8953 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8954 .channel_mode = alc883_3ST_2ch_modes,
8955 .input_mux = &alc883_capture_source,
8956 .unsol_event = alc883_clevo_m720_unsol_event,
8957 .init_hook = alc883_clevo_m720_automute,
8959 [ALC883_LENOVO_101E_2ch] = {
8960 .mixers = { alc883_lenovo_101e_2ch_mixer},
8961 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8962 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8963 .dac_nids = alc883_dac_nids,
8964 .adc_nids = alc883_adc_nids_alt,
8965 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8966 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8967 .channel_mode = alc883_3ST_2ch_modes,
8968 .input_mux = &alc883_lenovo_101e_capture_source,
8969 .unsol_event = alc883_lenovo_101e_unsol_event,
8970 .init_hook = alc883_lenovo_101e_all_automute,
8972 [ALC883_LENOVO_NB0763] = {
8973 .mixers = { alc883_lenovo_nb0763_mixer },
8974 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8975 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8976 .dac_nids = alc883_dac_nids,
8977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8978 .channel_mode = alc883_3ST_2ch_modes,
8980 .input_mux = &alc883_lenovo_nb0763_capture_source,
8981 .unsol_event = alc883_medion_md2_unsol_event,
8982 .init_hook = alc883_medion_md2_automute,
8984 [ALC888_LENOVO_MS7195_DIG] = {
8985 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8986 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8987 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8988 .dac_nids = alc883_dac_nids,
8989 .dig_out_nid = ALC883_DIGOUT_NID,
8990 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8991 .channel_mode = alc883_3ST_6ch_modes,
8993 .input_mux = &alc883_capture_source,
8994 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8995 .init_hook = alc888_lenovo_ms7195_front_automute,
8997 [ALC883_HAIER_W66] = {
8998 .mixers = { alc883_tagra_2ch_mixer},
8999 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9000 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9001 .dac_nids = alc883_dac_nids,
9002 .dig_out_nid = ALC883_DIGOUT_NID,
9003 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9004 .channel_mode = alc883_3ST_2ch_modes,
9005 .input_mux = &alc883_capture_source,
9006 .unsol_event = alc883_haier_w66_unsol_event,
9007 .init_hook = alc883_haier_w66_automute,
9010 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9011 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9013 .dac_nids = alc883_dac_nids,
9014 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9015 .channel_mode = alc888_3st_hp_modes,
9017 .input_mux = &alc883_capture_source,
9018 .unsol_event = alc888_3st_hp_unsol_event,
9019 .init_hook = alc888_3st_hp_front_automute,
9021 [ALC888_6ST_DELL] = {
9022 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9023 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9024 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9025 .dac_nids = alc883_dac_nids,
9026 .dig_out_nid = ALC883_DIGOUT_NID,
9027 .dig_in_nid = ALC883_DIGIN_NID,
9028 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9029 .channel_mode = alc883_sixstack_modes,
9030 .input_mux = &alc883_capture_source,
9031 .unsol_event = alc888_6st_dell_unsol_event,
9032 .init_hook = alc888_6st_dell_front_automute,
9035 .mixers = { alc883_mitac_mixer },
9036 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9037 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9038 .dac_nids = alc883_dac_nids,
9039 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9040 .channel_mode = alc883_3ST_2ch_modes,
9041 .input_mux = &alc883_capture_source,
9042 .unsol_event = alc883_mitac_unsol_event,
9043 .init_hook = alc883_mitac_automute,
9045 [ALC883_FUJITSU_PI2515] = {
9046 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9047 .init_verbs = { alc883_init_verbs,
9048 alc883_2ch_fujitsu_pi2515_verbs},
9049 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9050 .dac_nids = alc883_dac_nids,
9051 .dig_out_nid = ALC883_DIGOUT_NID,
9052 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9053 .channel_mode = alc883_3ST_2ch_modes,
9054 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9055 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
9056 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
9058 [ALC888_FUJITSU_XA3530] = {
9059 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9060 .init_verbs = { alc883_init_verbs,
9061 alc888_fujitsu_xa3530_verbs },
9062 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9063 .dac_nids = alc883_dac_nids,
9064 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9065 .adc_nids = alc883_adc_nids_rev,
9066 .capsrc_nids = alc883_capsrc_nids_rev,
9067 .dig_out_nid = ALC883_DIGOUT_NID,
9068 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9069 .channel_mode = alc888_4ST_8ch_intel_modes,
9071 ARRAY_SIZE(alc888_2_capture_sources),
9072 .input_mux = alc888_2_capture_sources,
9073 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
9074 .init_hook = alc888_fujitsu_xa3530_automute,
9076 [ALC888_LENOVO_SKY] = {
9077 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9078 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9079 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9080 .dac_nids = alc883_dac_nids,
9081 .dig_out_nid = ALC883_DIGOUT_NID,
9082 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9083 .channel_mode = alc883_sixstack_modes,
9085 .input_mux = &alc883_lenovo_sky_capture_source,
9086 .unsol_event = alc883_lenovo_sky_unsol_event,
9087 .init_hook = alc888_lenovo_sky_front_automute,
9089 [ALC888_ASUS_M90V] = {
9090 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9091 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9092 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9093 .dac_nids = alc883_dac_nids,
9094 .dig_out_nid = ALC883_DIGOUT_NID,
9095 .dig_in_nid = ALC883_DIGIN_NID,
9096 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9097 .channel_mode = alc883_3ST_6ch_modes,
9099 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9100 .unsol_event = alc883_mode2_unsol_event,
9101 .init_hook = alc883_mode2_inithook,
9103 [ALC888_ASUS_EEE1601] = {
9104 .mixers = { alc883_asus_eee1601_mixer },
9105 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9106 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9107 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9108 .dac_nids = alc883_dac_nids,
9109 .dig_out_nid = ALC883_DIGOUT_NID,
9110 .dig_in_nid = ALC883_DIGIN_NID,
9111 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9112 .channel_mode = alc883_3ST_2ch_modes,
9114 .input_mux = &alc883_asus_eee1601_capture_source,
9115 .unsol_event = alc883_eee1601_unsol_event,
9116 .init_hook = alc883_eee1601_inithook,
9118 [ALC1200_ASUS_P5Q] = {
9119 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9120 .init_verbs = { alc883_init_verbs },
9121 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9122 .dac_nids = alc883_dac_nids,
9123 .dig_out_nid = ALC1200_DIGOUT_NID,
9124 .dig_in_nid = ALC883_DIGIN_NID,
9125 .slave_dig_outs = alc1200_slave_dig_outs,
9126 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9127 .channel_mode = alc883_sixstack_modes,
9128 .input_mux = &alc883_capture_source,
9134 * BIOS auto configuration
9136 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9137 hda_nid_t nid, int pin_type,
9141 struct alc_spec *spec = codec->spec;
9144 alc_set_pin_output(codec, nid, pin_type);
9145 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9148 idx = spec->multiout.dac_nids[dac_idx] - 2;
9149 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9153 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9155 struct alc_spec *spec = codec->spec;
9158 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9159 for (i = 0; i <= HDA_SIDE; i++) {
9160 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9161 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9163 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9168 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9170 struct alc_spec *spec = codec->spec;
9173 pin = spec->autocfg.hp_pins[0];
9174 if (pin) /* connect to front */
9176 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9177 pin = spec->autocfg.speaker_pins[0];
9179 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9182 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9183 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9185 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9187 struct alc_spec *spec = codec->spec;
9190 for (i = 0; i < AUTO_PIN_LAST; i++) {
9191 hda_nid_t nid = spec->autocfg.input_pins[i];
9192 if (alc883_is_input_pin(nid)) {
9193 alc_set_input_pin(codec, nid, i);
9194 if (nid != ALC883_PIN_CD_NID &&
9195 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9196 snd_hda_codec_write(codec, nid, 0,
9197 AC_VERB_SET_AMP_GAIN_MUTE,
9203 #define alc883_auto_init_input_src alc882_auto_init_input_src
9205 /* almost identical with ALC880 parser... */
9206 static int alc883_parse_auto_config(struct hda_codec *codec)
9208 struct alc_spec *spec = codec->spec;
9209 int err = alc880_parse_auto_config(codec);
9210 struct auto_pin_cfg *cfg = &spec->autocfg;
9216 return 0; /* no config found */
9218 err = alc_auto_add_mic_boost(codec);
9222 /* hack - override the init verbs */
9223 spec->init_verbs[0] = alc883_auto_init_verbs;
9225 /* setup input_mux for ALC889 */
9226 if (codec->vendor_id == 0x10ec0889) {
9227 /* digital-mic input pin is excluded in alc880_auto_create..()
9228 * because it's under 0x18
9230 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9231 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9232 struct hda_input_mux *imux = &spec->private_imux[0];
9233 for (i = 1; i < 3; i++)
9234 memcpy(&spec->private_imux[i],
9235 &spec->private_imux[0],
9236 sizeof(spec->private_imux[0]));
9237 imux->items[imux->num_items].label = "Int DMic";
9238 imux->items[imux->num_items].index = 0x0b;
9240 spec->num_mux_defs = 3;
9241 spec->input_mux = spec->private_imux;
9245 return 1; /* config found */
9248 /* additional initialization for auto-configuration model */
9249 static void alc883_auto_init(struct hda_codec *codec)
9251 struct alc_spec *spec = codec->spec;
9252 alc883_auto_init_multi_out(codec);
9253 alc883_auto_init_hp_out(codec);
9254 alc883_auto_init_analog_input(codec);
9255 alc883_auto_init_input_src(codec);
9256 if (spec->unsol_event)
9257 alc_inithook(codec);
9260 static int patch_alc883(struct hda_codec *codec)
9262 struct alc_spec *spec;
9263 int err, board_config;
9265 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9271 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9273 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9276 if (board_config < 0) {
9277 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
9278 "trying auto-probe from BIOS...\n");
9279 board_config = ALC883_AUTO;
9282 if (board_config == ALC883_AUTO) {
9283 /* automatic parse from the BIOS config */
9284 err = alc883_parse_auto_config(codec);
9290 "hda_codec: Cannot set up configuration "
9291 "from BIOS. Using base mode...\n");
9292 board_config = ALC883_3ST_2ch_DIG;
9296 err = snd_hda_attach_beep_device(codec, 0x1);
9302 if (board_config != ALC883_AUTO)
9303 setup_preset(spec, &alc883_presets[board_config]);
9305 switch (codec->vendor_id) {
9307 if (codec->revision_id == 0x100101) {
9308 spec->stream_name_analog = "ALC1200 Analog";
9309 spec->stream_name_digital = "ALC1200 Digital";
9311 spec->stream_name_analog = "ALC888 Analog";
9312 spec->stream_name_digital = "ALC888 Digital";
9314 if (!spec->num_adc_nids) {
9315 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9316 spec->adc_nids = alc883_adc_nids;
9318 if (!spec->capsrc_nids)
9319 spec->capsrc_nids = alc883_capsrc_nids;
9320 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9323 spec->stream_name_analog = "ALC889 Analog";
9324 spec->stream_name_digital = "ALC889 Digital";
9325 if (!spec->num_adc_nids) {
9326 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9327 spec->adc_nids = alc889_adc_nids;
9329 if (!spec->capsrc_nids)
9330 spec->capsrc_nids = alc889_capsrc_nids;
9331 spec->capture_style = CAPT_1MUX_MIX; /* 1mux/Nmix-style
9335 spec->stream_name_analog = "ALC883 Analog";
9336 spec->stream_name_digital = "ALC883 Digital";
9337 if (!spec->num_adc_nids) {
9338 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9339 spec->adc_nids = alc883_adc_nids;
9341 if (!spec->capsrc_nids)
9342 spec->capsrc_nids = alc883_capsrc_nids;
9343 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9347 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9348 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9349 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9351 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9352 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9354 if (!spec->cap_mixer)
9355 set_capture_mixer(spec);
9356 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9358 spec->vmaster_nid = 0x0c;
9360 codec->patch_ops = alc_patch_ops;
9361 if (board_config == ALC883_AUTO)
9362 spec->init_hook = alc883_auto_init;
9364 #ifdef CONFIG_SND_HDA_POWER_SAVE
9365 if (!spec->loopback.amplist)
9366 spec->loopback.amplist = alc883_loopbacks;
9368 codec->proc_widget_hook = print_realtek_coef;
9377 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9378 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9380 #define alc262_dac_nids alc260_dac_nids
9381 #define alc262_adc_nids alc882_adc_nids
9382 #define alc262_adc_nids_alt alc882_adc_nids_alt
9383 #define alc262_capsrc_nids alc882_capsrc_nids
9384 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9386 #define alc262_modes alc260_modes
9387 #define alc262_capture_source alc882_capture_source
9389 static hda_nid_t alc262_dmic_adc_nids[1] = {
9394 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9396 static struct snd_kcontrol_new alc262_base_mixer[] = {
9397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9398 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9399 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9400 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9401 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9402 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9408 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9409 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9410 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9411 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9412 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9416 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9417 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9418 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9424 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9425 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9427 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9428 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9429 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9434 /* update HP, line and mono-out pins according to the master switch */
9435 static void alc262_hp_master_update(struct hda_codec *codec)
9437 struct alc_spec *spec = codec->spec;
9438 int val = spec->master_sw;
9441 snd_hda_codec_write_cache(codec, 0x1b, 0,
9442 AC_VERB_SET_PIN_WIDGET_CONTROL,
9444 snd_hda_codec_write_cache(codec, 0x15, 0,
9445 AC_VERB_SET_PIN_WIDGET_CONTROL,
9447 /* mono (speaker) depending on the HP jack sense */
9448 val = val && !spec->jack_present;
9449 snd_hda_codec_write_cache(codec, 0x16, 0,
9450 AC_VERB_SET_PIN_WIDGET_CONTROL,
9454 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9456 struct alc_spec *spec = codec->spec;
9457 unsigned int presence;
9458 presence = snd_hda_codec_read(codec, 0x1b, 0,
9459 AC_VERB_GET_PIN_SENSE, 0);
9460 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9461 alc262_hp_master_update(codec);
9464 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9466 if ((res >> 26) != ALC880_HP_EVENT)
9468 alc262_hp_bpc_automute(codec);
9471 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9473 struct alc_spec *spec = codec->spec;
9474 unsigned int presence;
9475 presence = snd_hda_codec_read(codec, 0x15, 0,
9476 AC_VERB_GET_PIN_SENSE, 0);
9477 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9478 alc262_hp_master_update(codec);
9481 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9484 if ((res >> 26) != ALC880_HP_EVENT)
9486 alc262_hp_wildwest_automute(codec);
9489 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9490 struct snd_ctl_elem_value *ucontrol)
9492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9493 struct alc_spec *spec = codec->spec;
9494 *ucontrol->value.integer.value = spec->master_sw;
9498 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9499 struct snd_ctl_elem_value *ucontrol)
9501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9502 struct alc_spec *spec = codec->spec;
9503 int val = !!*ucontrol->value.integer.value;
9505 if (val == spec->master_sw)
9507 spec->master_sw = val;
9508 alc262_hp_master_update(codec);
9512 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9514 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9515 .name = "Master Playback Switch",
9516 .info = snd_ctl_boolean_mono_info,
9517 .get = alc262_hp_master_sw_get,
9518 .put = alc262_hp_master_sw_put,
9520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9521 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9523 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9525 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9528 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9529 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9530 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9531 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9532 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9533 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9534 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9535 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9536 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9537 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9538 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9542 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9545 .name = "Master Playback Switch",
9546 .info = snd_ctl_boolean_mono_info,
9547 .get = alc262_hp_master_sw_get,
9548 .put = alc262_hp_master_sw_put,
9550 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9551 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9552 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9553 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9554 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9556 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9558 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9559 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9560 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9561 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9562 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9568 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9569 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9570 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9571 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9575 /* mute/unmute internal speaker according to the hp jack and mute state */
9576 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9578 struct alc_spec *spec = codec->spec;
9580 if (force || !spec->sense_updated) {
9581 unsigned int present;
9582 present = snd_hda_codec_read(codec, 0x15, 0,
9583 AC_VERB_GET_PIN_SENSE, 0);
9584 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9585 spec->sense_updated = 1;
9587 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9588 spec->jack_present ? HDA_AMP_MUTE : 0);
9591 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9594 if ((res >> 26) != ALC880_HP_EVENT)
9596 alc262_hp_t5735_automute(codec, 1);
9599 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9601 alc262_hp_t5735_automute(codec, 1);
9604 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9605 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9606 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9607 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9608 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9611 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9615 static struct hda_verb alc262_hp_t5735_verbs[] = {
9616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9617 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9619 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9623 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9624 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9627 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9633 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9634 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9636 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9637 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9638 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9639 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9640 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9641 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9642 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9643 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9647 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9654 /* bind hp and internal speaker mute (with plug check) */
9655 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9656 struct snd_ctl_elem_value *ucontrol)
9658 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9659 long *valp = ucontrol->value.integer.value;
9662 /* change hp mute */
9663 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9665 valp[0] ? 0 : HDA_AMP_MUTE);
9666 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9668 valp[1] ? 0 : HDA_AMP_MUTE);
9670 /* change speaker according to HP jack state */
9671 struct alc_spec *spec = codec->spec;
9673 if (spec->jack_present)
9674 mute = HDA_AMP_MUTE;
9676 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9678 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9679 HDA_AMP_MUTE, mute);
9684 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9685 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9688 .name = "Master Playback Switch",
9689 .info = snd_hda_mixer_amp_switch_info,
9690 .get = snd_hda_mixer_amp_switch_get,
9691 .put = alc262_sony_master_sw_put,
9692 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9695 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9696 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9697 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9701 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9705 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9706 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9707 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9708 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9712 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
9713 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9714 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9715 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
9716 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
9717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9722 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9723 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9724 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9728 static struct hda_verb alc262_tyan_verbs[] = {
9729 /* Headphone automute */
9730 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9731 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9732 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9734 /* P11 AUX_IN, white 4-pin connector */
9735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9736 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
9737 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
9738 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
9743 /* unsolicited event for HP jack sensing */
9744 static void alc262_tyan_automute(struct hda_codec *codec)
9747 unsigned int present;
9749 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9750 present = snd_hda_codec_read(codec, 0x1b, 0,
9751 AC_VERB_GET_PIN_SENSE, 0);
9752 present = (present & 0x80000000) != 0;
9754 /* mute line output on ATX panel */
9755 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9756 HDA_AMP_MUTE, HDA_AMP_MUTE);
9758 /* unmute line output if necessary */
9759 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9760 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9761 HDA_AMP_MUTE, mute);
9765 static void alc262_tyan_unsol_event(struct hda_codec *codec,
9768 if ((res >> 26) != ALC880_HP_EVENT)
9770 alc262_tyan_automute(codec);
9773 #define alc262_capture_mixer alc882_capture_mixer
9774 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9777 * generic initialization of ADC, input mixers and output mixers
9779 static struct hda_verb alc262_init_verbs[] = {
9781 * Unmute ADC0-2 and set the default input to mic-in
9783 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9785 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9787 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9790 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9792 * Note: PASD motherboards uses the Line In 2 as the input for
9793 * front panel mic (mic 2)
9795 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9799 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9800 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9803 * Set up output mixers (0x0c - 0x0e)
9805 /* set vol=0 to output mixers */
9806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9809 /* set up input amps for analog loopback */
9810 /* Amp Indices: DAC = 0, mixer = 1 */
9811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9813 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9814 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9815 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9816 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9820 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9821 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9829 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9831 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9832 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9834 /* FIXME: use matrix-type input source selection */
9835 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9836 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9837 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9840 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9842 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9843 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9844 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9845 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9847 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9848 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9849 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9850 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9855 static struct hda_verb alc262_eapd_verbs[] = {
9856 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9857 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9861 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9867 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9868 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9870 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9872 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9873 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9877 static struct hda_verb alc262_sony_unsol_verbs[] = {
9878 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9883 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9887 static struct hda_input_mux alc262_dmic_capture_source = {
9890 { "Int DMic", 0x9 },
9895 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9896 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9897 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9898 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9900 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9904 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9905 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9908 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9909 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9910 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9911 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9916 static void alc262_dmic_automute(struct hda_codec *codec)
9918 unsigned int present;
9920 present = snd_hda_codec_read(codec, 0x18, 0,
9921 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9922 snd_hda_codec_write(codec, 0x22, 0,
9923 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9926 /* toggle speaker-output according to the hp-jack state */
9927 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9929 unsigned int present;
9932 present = snd_hda_codec_read(codec, 0x15, 0,
9933 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9934 bits = present ? 0 : PIN_OUT;
9935 snd_hda_codec_write(codec, 0x14, 0,
9936 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9941 /* unsolicited event for HP jack sensing */
9942 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9945 if ((res >> 26) == ALC880_HP_EVENT)
9946 alc262_toshiba_s06_speaker_automute(codec);
9947 if ((res >> 26) == ALC880_MIC_EVENT)
9948 alc262_dmic_automute(codec);
9952 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9954 alc262_toshiba_s06_speaker_automute(codec);
9955 alc262_dmic_automute(codec);
9958 /* mute/unmute internal speaker according to the hp jack and mute state */
9959 static void alc262_hippo_automute(struct hda_codec *codec)
9961 struct alc_spec *spec = codec->spec;
9963 unsigned int present;
9965 /* need to execute and sync at first */
9966 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9967 present = snd_hda_codec_read(codec, 0x15, 0,
9968 AC_VERB_GET_PIN_SENSE, 0);
9969 spec->jack_present = (present & 0x80000000) != 0;
9970 if (spec->jack_present) {
9971 /* mute internal speaker */
9972 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9973 HDA_AMP_MUTE, HDA_AMP_MUTE);
9975 /* unmute internal speaker if necessary */
9976 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9977 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9978 HDA_AMP_MUTE, mute);
9982 /* unsolicited event for HP jack sensing */
9983 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9986 if ((res >> 26) != ALC880_HP_EVENT)
9988 alc262_hippo_automute(codec);
9991 static void alc262_hippo1_automute(struct hda_codec *codec)
9994 unsigned int present;
9996 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9997 present = snd_hda_codec_read(codec, 0x1b, 0,
9998 AC_VERB_GET_PIN_SENSE, 0);
9999 present = (present & 0x80000000) != 0;
10001 /* mute internal speaker */
10002 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10003 HDA_AMP_MUTE, HDA_AMP_MUTE);
10005 /* unmute internal speaker if necessary */
10006 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10007 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10008 HDA_AMP_MUTE, mute);
10012 /* unsolicited event for HP jack sensing */
10013 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
10016 if ((res >> 26) != ALC880_HP_EVENT)
10018 alc262_hippo1_automute(codec);
10024 * 0x16 = internal speaker
10025 * 0x18 = external mic
10028 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10029 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10030 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10033 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10034 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10036 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10037 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10041 static struct hda_verb alc262_nec_verbs[] = {
10042 /* Unmute Speaker */
10043 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10046 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10049 /* External mic to headphone */
10050 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10051 /* External mic to speaker */
10052 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10058 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10059 * 0x1b = port replicator headphone out
10062 #define ALC_HP_EVENT 0x37
10064 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10065 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10066 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10067 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10068 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10072 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10073 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10074 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10078 static struct hda_input_mux alc262_fujitsu_capture_source = {
10082 { "Int Mic", 0x1 },
10087 static struct hda_input_mux alc262_HP_capture_source = {
10091 { "Front Mic", 0x1 },
10098 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10102 { "Front Mic", 0x2 },
10108 /* mute/unmute internal speaker according to the hp jacks and mute state */
10109 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10111 struct alc_spec *spec = codec->spec;
10114 if (force || !spec->sense_updated) {
10115 unsigned int present;
10116 /* need to execute and sync at first */
10117 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10118 /* check laptop HP jack */
10119 present = snd_hda_codec_read(codec, 0x14, 0,
10120 AC_VERB_GET_PIN_SENSE, 0);
10121 /* need to execute and sync at first */
10122 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10123 /* check docking HP jack */
10124 present |= snd_hda_codec_read(codec, 0x1b, 0,
10125 AC_VERB_GET_PIN_SENSE, 0);
10126 if (present & AC_PINSENSE_PRESENCE)
10127 spec->jack_present = 1;
10129 spec->jack_present = 0;
10130 spec->sense_updated = 1;
10132 /* unmute internal speaker only if both HPs are unplugged and
10133 * master switch is on
10135 if (spec->jack_present)
10136 mute = HDA_AMP_MUTE;
10138 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10139 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10140 HDA_AMP_MUTE, mute);
10143 /* unsolicited event for HP jack sensing */
10144 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10147 if ((res >> 26) != ALC_HP_EVENT)
10149 alc262_fujitsu_automute(codec, 1);
10152 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10154 alc262_fujitsu_automute(codec, 1);
10157 /* bind volumes of both NID 0x0c and 0x0d */
10158 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10159 .ops = &snd_hda_bind_vol,
10161 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10162 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10167 /* mute/unmute internal speaker according to the hp jack and mute state */
10168 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10170 struct alc_spec *spec = codec->spec;
10173 if (force || !spec->sense_updated) {
10174 unsigned int present_int_hp;
10175 /* need to execute and sync at first */
10176 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10177 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10178 AC_VERB_GET_PIN_SENSE, 0);
10179 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10180 spec->sense_updated = 1;
10182 if (spec->jack_present) {
10183 /* mute internal speaker */
10184 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10185 HDA_AMP_MUTE, HDA_AMP_MUTE);
10186 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10187 HDA_AMP_MUTE, HDA_AMP_MUTE);
10189 /* unmute internal speaker if necessary */
10190 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10191 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10192 HDA_AMP_MUTE, mute);
10193 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10194 HDA_AMP_MUTE, mute);
10198 /* unsolicited event for HP jack sensing */
10199 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10202 if ((res >> 26) != ALC_HP_EVENT)
10204 alc262_lenovo_3000_automute(codec, 1);
10207 /* bind hp and internal speaker mute (with plug check) */
10208 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10209 struct snd_ctl_elem_value *ucontrol)
10211 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10212 long *valp = ucontrol->value.integer.value;
10215 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10217 valp ? 0 : HDA_AMP_MUTE);
10218 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10220 valp ? 0 : HDA_AMP_MUTE);
10223 alc262_fujitsu_automute(codec, 0);
10227 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10228 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10231 .name = "Master Playback Switch",
10232 .info = snd_hda_mixer_amp_switch_info,
10233 .get = snd_hda_mixer_amp_switch_get,
10234 .put = alc262_fujitsu_master_sw_put,
10235 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10237 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10238 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10239 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10240 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10242 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10243 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10244 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10248 /* bind hp and internal speaker mute (with plug check) */
10249 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10250 struct snd_ctl_elem_value *ucontrol)
10252 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10253 long *valp = ucontrol->value.integer.value;
10256 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10258 valp ? 0 : HDA_AMP_MUTE);
10261 alc262_lenovo_3000_automute(codec, 0);
10265 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10266 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10269 .name = "Master Playback Switch",
10270 .info = snd_hda_mixer_amp_switch_info,
10271 .get = snd_hda_mixer_amp_switch_get,
10272 .put = alc262_lenovo_3000_master_sw_put,
10273 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10275 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10276 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10277 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10278 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10279 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10280 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10281 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10282 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10286 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10287 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10289 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10290 .name = "Master Playback Switch",
10291 .info = snd_hda_mixer_amp_switch_info,
10292 .get = snd_hda_mixer_amp_switch_get,
10293 .put = alc262_sony_master_sw_put,
10294 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
10296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10305 /* additional init verbs for Benq laptops */
10306 static struct hda_verb alc262_EAPD_verbs[] = {
10307 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10308 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10312 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10313 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10314 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10316 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10317 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10321 /* Samsung Q1 Ultra Vista model setup */
10322 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10323 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10324 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10327 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10328 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10332 static struct hda_verb alc262_ultra_verbs[] = {
10334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10335 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10336 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10340 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10341 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10343 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10344 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10347 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10351 /* ADC, choose mic */
10352 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10365 /* mute/unmute internal speaker according to the hp jack and mute state */
10366 static void alc262_ultra_automute(struct hda_codec *codec)
10368 struct alc_spec *spec = codec->spec;
10372 /* auto-mute only when HP is used as HP */
10373 if (!spec->cur_mux[0]) {
10374 unsigned int present;
10375 /* need to execute and sync at first */
10376 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10377 present = snd_hda_codec_read(codec, 0x15, 0,
10378 AC_VERB_GET_PIN_SENSE, 0);
10379 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10380 if (spec->jack_present)
10381 mute = HDA_AMP_MUTE;
10383 /* mute/unmute internal speaker */
10384 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10385 HDA_AMP_MUTE, mute);
10386 /* mute/unmute HP */
10387 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10388 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10391 /* unsolicited event for HP jack sensing */
10392 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10395 if ((res >> 26) != ALC880_HP_EVENT)
10397 alc262_ultra_automute(codec);
10400 static struct hda_input_mux alc262_ultra_capture_source = {
10404 { "Headphone", 0x7 },
10408 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10409 struct snd_ctl_elem_value *ucontrol)
10411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10412 struct alc_spec *spec = codec->spec;
10415 ret = alc_mux_enum_put(kcontrol, ucontrol);
10418 /* reprogram the HP pin as mic or HP according to the input source */
10419 snd_hda_codec_write_cache(codec, 0x15, 0,
10420 AC_VERB_SET_PIN_WIDGET_CONTROL,
10421 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10422 alc262_ultra_automute(codec); /* mute/unmute HP */
10426 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10427 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10428 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10431 .name = "Capture Source",
10432 .info = alc_mux_enum_info,
10433 .get = alc_mux_enum_get,
10434 .put = alc262_ultra_mux_enum_put,
10439 /* add playback controls from the parsed DAC table */
10440 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10441 const struct auto_pin_cfg *cfg)
10446 spec->multiout.num_dacs = 1; /* only use one dac */
10447 spec->multiout.dac_nids = spec->private_dac_nids;
10448 spec->multiout.dac_nids[0] = 2;
10450 nid = cfg->line_out_pins[0];
10452 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10453 "Front Playback Volume",
10454 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10457 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10458 "Front Playback Switch",
10459 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10464 nid = cfg->speaker_pins[0];
10467 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10468 "Speaker Playback Volume",
10469 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10473 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10474 "Speaker Playback Switch",
10475 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10480 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10481 "Speaker Playback Switch",
10482 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10488 nid = cfg->hp_pins[0];
10490 /* spec->multiout.hp_nid = 2; */
10492 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10493 "Headphone Playback Volume",
10494 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10498 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10499 "Headphone Playback Switch",
10500 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10505 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10506 "Headphone Playback Switch",
10507 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10516 /* identical with ALC880 */
10517 #define alc262_auto_create_analog_input_ctls \
10518 alc880_auto_create_analog_input_ctls
10521 * generic initialization of ADC, input mixers and output mixers
10523 static struct hda_verb alc262_volume_init_verbs[] = {
10525 * Unmute ADC0-2 and set the default input to mic-in
10527 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10529 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10531 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10534 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10536 * Note: PASD motherboards uses the Line In 2 as the input for
10537 * front panel mic (mic 2)
10539 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10547 * Set up output mixers (0x0c - 0x0f)
10549 /* set vol=0 to output mixers */
10550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10551 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10554 /* set up input amps for analog loopback */
10555 /* Amp Indices: DAC = 0, mixer = 1 */
10556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10558 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10560 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10563 /* FIXME: use matrix-type input source selection */
10564 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10565 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10569 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10584 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10586 * Unmute ADC0-2 and set the default input to mic-in
10588 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10589 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10590 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10591 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10592 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10595 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10597 * Note: PASD motherboards uses the Line In 2 as the input for
10598 * front panel mic (mic 2)
10600 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10601 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10610 * Set up output mixers (0x0c - 0x0e)
10612 /* set vol=0 to output mixers */
10613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10615 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10617 /* set up input amps for analog loopback */
10618 /* Amp Indices: DAC = 0, mixer = 1 */
10619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10624 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10626 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10628 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10630 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10633 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10634 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10637 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10638 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10640 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10642 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10646 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10647 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10650 /* FIXME: use matrix-type input source selection */
10651 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10652 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10666 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10668 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10673 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10675 * Unmute ADC0-2 and set the default input to mic-in
10677 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10679 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10680 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10681 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10684 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10686 * Note: PASD motherboards uses the Line In 2 as the input for front
10687 * panel mic (mic 2)
10689 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10694 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10695 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10696 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10699 * Set up output mixers (0x0c - 0x0e)
10701 /* set vol=0 to output mixers */
10702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10703 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10706 /* set up input amps for analog loopback */
10707 /* Amp Indices: DAC = 0, mixer = 1 */
10708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10709 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10710 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10711 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10712 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10713 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10717 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10720 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10721 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10722 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10724 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10727 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10728 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10730 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10731 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10732 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10733 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10734 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10735 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10737 /* FIXME: use matrix-type input source selection */
10738 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10739 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10744 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10745 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10748 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10749 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10753 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10756 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10761 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10769 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10771 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10773 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10776 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10777 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10782 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10787 #ifdef CONFIG_SND_HDA_POWER_SAVE
10788 #define alc262_loopbacks alc880_loopbacks
10791 /* pcm configuration: identiacal with ALC880 */
10792 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10793 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10794 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10795 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10798 * BIOS auto configuration
10800 static int alc262_parse_auto_config(struct hda_codec *codec)
10802 struct alc_spec *spec = codec->spec;
10804 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10806 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10810 if (!spec->autocfg.line_outs) {
10811 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
10812 spec->multiout.max_channels = 2;
10813 spec->no_analog = 1;
10816 return 0; /* can't find valid BIOS pin config */
10818 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10821 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10825 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10828 if (spec->autocfg.dig_outs) {
10829 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10830 spec->dig_out_type = spec->autocfg.dig_out_type[0];
10832 if (spec->autocfg.dig_in_pin)
10833 spec->dig_in_nid = ALC262_DIGIN_NID;
10835 if (spec->kctls.list)
10836 add_mixer(spec, spec->kctls.list);
10838 add_verb(spec, alc262_volume_init_verbs);
10839 spec->num_mux_defs = 1;
10840 spec->input_mux = &spec->private_imux[0];
10842 err = alc_auto_add_mic_boost(codec);
10849 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10850 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10851 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10852 #define alc262_auto_init_input_src alc882_auto_init_input_src
10855 /* init callback for auto-configuration model -- overriding the default init */
10856 static void alc262_auto_init(struct hda_codec *codec)
10858 struct alc_spec *spec = codec->spec;
10859 alc262_auto_init_multi_out(codec);
10860 alc262_auto_init_hp_out(codec);
10861 alc262_auto_init_analog_input(codec);
10862 alc262_auto_init_input_src(codec);
10863 if (spec->unsol_event)
10864 alc_inithook(codec);
10868 * configuration and preset
10870 static const char *alc262_models[ALC262_MODEL_LAST] = {
10871 [ALC262_BASIC] = "basic",
10872 [ALC262_HIPPO] = "hippo",
10873 [ALC262_HIPPO_1] = "hippo_1",
10874 [ALC262_FUJITSU] = "fujitsu",
10875 [ALC262_HP_BPC] = "hp-bpc",
10876 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10877 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10878 [ALC262_HP_RP5700] = "hp-rp5700",
10879 [ALC262_BENQ_ED8] = "benq",
10880 [ALC262_BENQ_T31] = "benq-t31",
10881 [ALC262_SONY_ASSAMD] = "sony-assamd",
10882 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10883 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10884 [ALC262_ULTRA] = "ultra",
10885 [ALC262_LENOVO_3000] = "lenovo-3000",
10886 [ALC262_NEC] = "nec",
10887 [ALC262_TYAN] = "tyan",
10888 [ALC262_AUTO] = "auto",
10891 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10892 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10893 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10894 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10896 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10898 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
10900 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10901 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10902 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10903 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10904 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10905 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10906 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10907 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10908 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10909 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10910 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10911 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10912 ALC262_HP_TC_T5735),
10913 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10914 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10915 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10916 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10917 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
10918 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
10919 ALC262_SONY_ASSAMD),
10920 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10921 ALC262_TOSHIBA_RX1),
10922 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10923 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10924 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10925 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
10926 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10928 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
10929 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10930 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10931 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10932 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10936 static struct alc_config_preset alc262_presets[] = {
10938 .mixers = { alc262_base_mixer },
10939 .init_verbs = { alc262_init_verbs },
10940 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10941 .dac_nids = alc262_dac_nids,
10943 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10944 .channel_mode = alc262_modes,
10945 .input_mux = &alc262_capture_source,
10948 .mixers = { alc262_base_mixer },
10949 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10950 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10951 .dac_nids = alc262_dac_nids,
10953 .dig_out_nid = ALC262_DIGOUT_NID,
10954 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10955 .channel_mode = alc262_modes,
10956 .input_mux = &alc262_capture_source,
10957 .unsol_event = alc262_hippo_unsol_event,
10958 .init_hook = alc262_hippo_automute,
10960 [ALC262_HIPPO_1] = {
10961 .mixers = { alc262_hippo1_mixer },
10962 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10963 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10964 .dac_nids = alc262_dac_nids,
10966 .dig_out_nid = ALC262_DIGOUT_NID,
10967 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10968 .channel_mode = alc262_modes,
10969 .input_mux = &alc262_capture_source,
10970 .unsol_event = alc262_hippo1_unsol_event,
10971 .init_hook = alc262_hippo1_automute,
10973 [ALC262_FUJITSU] = {
10974 .mixers = { alc262_fujitsu_mixer },
10975 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10976 alc262_fujitsu_unsol_verbs },
10977 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10978 .dac_nids = alc262_dac_nids,
10980 .dig_out_nid = ALC262_DIGOUT_NID,
10981 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10982 .channel_mode = alc262_modes,
10983 .input_mux = &alc262_fujitsu_capture_source,
10984 .unsol_event = alc262_fujitsu_unsol_event,
10985 .init_hook = alc262_fujitsu_init_hook,
10987 [ALC262_HP_BPC] = {
10988 .mixers = { alc262_HP_BPC_mixer },
10989 .init_verbs = { alc262_HP_BPC_init_verbs },
10990 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10991 .dac_nids = alc262_dac_nids,
10993 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10994 .channel_mode = alc262_modes,
10995 .input_mux = &alc262_HP_capture_source,
10996 .unsol_event = alc262_hp_bpc_unsol_event,
10997 .init_hook = alc262_hp_bpc_automute,
10999 [ALC262_HP_BPC_D7000_WF] = {
11000 .mixers = { alc262_HP_BPC_WildWest_mixer },
11001 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11002 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11003 .dac_nids = alc262_dac_nids,
11005 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11006 .channel_mode = alc262_modes,
11007 .input_mux = &alc262_HP_D7000_capture_source,
11008 .unsol_event = alc262_hp_wildwest_unsol_event,
11009 .init_hook = alc262_hp_wildwest_automute,
11011 [ALC262_HP_BPC_D7000_WL] = {
11012 .mixers = { alc262_HP_BPC_WildWest_mixer,
11013 alc262_HP_BPC_WildWest_option_mixer },
11014 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11015 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11016 .dac_nids = alc262_dac_nids,
11018 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11019 .channel_mode = alc262_modes,
11020 .input_mux = &alc262_HP_D7000_capture_source,
11021 .unsol_event = alc262_hp_wildwest_unsol_event,
11022 .init_hook = alc262_hp_wildwest_automute,
11024 [ALC262_HP_TC_T5735] = {
11025 .mixers = { alc262_hp_t5735_mixer },
11026 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11027 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11028 .dac_nids = alc262_dac_nids,
11030 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11031 .channel_mode = alc262_modes,
11032 .input_mux = &alc262_capture_source,
11033 .unsol_event = alc262_hp_t5735_unsol_event,
11034 .init_hook = alc262_hp_t5735_init_hook,
11036 [ALC262_HP_RP5700] = {
11037 .mixers = { alc262_hp_rp5700_mixer },
11038 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11039 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11040 .dac_nids = alc262_dac_nids,
11041 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11042 .channel_mode = alc262_modes,
11043 .input_mux = &alc262_hp_rp5700_capture_source,
11045 [ALC262_BENQ_ED8] = {
11046 .mixers = { alc262_base_mixer },
11047 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11048 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11049 .dac_nids = alc262_dac_nids,
11051 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11052 .channel_mode = alc262_modes,
11053 .input_mux = &alc262_capture_source,
11055 [ALC262_SONY_ASSAMD] = {
11056 .mixers = { alc262_sony_mixer },
11057 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11058 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11059 .dac_nids = alc262_dac_nids,
11061 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11062 .channel_mode = alc262_modes,
11063 .input_mux = &alc262_capture_source,
11064 .unsol_event = alc262_hippo_unsol_event,
11065 .init_hook = alc262_hippo_automute,
11067 [ALC262_BENQ_T31] = {
11068 .mixers = { alc262_benq_t31_mixer },
11069 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11070 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11071 .dac_nids = alc262_dac_nids,
11073 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11074 .channel_mode = alc262_modes,
11075 .input_mux = &alc262_capture_source,
11076 .unsol_event = alc262_hippo_unsol_event,
11077 .init_hook = alc262_hippo_automute,
11080 .mixers = { alc262_ultra_mixer },
11081 .cap_mixer = alc262_ultra_capture_mixer,
11082 .init_verbs = { alc262_ultra_verbs },
11083 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11084 .dac_nids = alc262_dac_nids,
11085 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11086 .channel_mode = alc262_modes,
11087 .input_mux = &alc262_ultra_capture_source,
11088 .adc_nids = alc262_adc_nids, /* ADC0 */
11089 .capsrc_nids = alc262_capsrc_nids,
11090 .num_adc_nids = 1, /* single ADC */
11091 .unsol_event = alc262_ultra_unsol_event,
11092 .init_hook = alc262_ultra_automute,
11094 [ALC262_LENOVO_3000] = {
11095 .mixers = { alc262_lenovo_3000_mixer },
11096 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11097 alc262_lenovo_3000_unsol_verbs },
11098 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11099 .dac_nids = alc262_dac_nids,
11101 .dig_out_nid = ALC262_DIGOUT_NID,
11102 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11103 .channel_mode = alc262_modes,
11104 .input_mux = &alc262_fujitsu_capture_source,
11105 .unsol_event = alc262_lenovo_3000_unsol_event,
11108 .mixers = { alc262_nec_mixer },
11109 .init_verbs = { alc262_nec_verbs },
11110 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11111 .dac_nids = alc262_dac_nids,
11113 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11114 .channel_mode = alc262_modes,
11115 .input_mux = &alc262_capture_source,
11117 [ALC262_TOSHIBA_S06] = {
11118 .mixers = { alc262_toshiba_s06_mixer },
11119 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11120 alc262_eapd_verbs },
11121 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11122 .capsrc_nids = alc262_dmic_capsrc_nids,
11123 .dac_nids = alc262_dac_nids,
11124 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11125 .dig_out_nid = ALC262_DIGOUT_NID,
11126 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11127 .channel_mode = alc262_modes,
11128 .input_mux = &alc262_dmic_capture_source,
11129 .unsol_event = alc262_toshiba_s06_unsol_event,
11130 .init_hook = alc262_toshiba_s06_init_hook,
11132 [ALC262_TOSHIBA_RX1] = {
11133 .mixers = { alc262_toshiba_rx1_mixer },
11134 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11135 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11136 .dac_nids = alc262_dac_nids,
11138 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11139 .channel_mode = alc262_modes,
11140 .input_mux = &alc262_capture_source,
11141 .unsol_event = alc262_hippo_unsol_event,
11142 .init_hook = alc262_hippo_automute,
11145 .mixers = { alc262_tyan_mixer },
11146 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11147 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11148 .dac_nids = alc262_dac_nids,
11150 .dig_out_nid = ALC262_DIGOUT_NID,
11151 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11152 .channel_mode = alc262_modes,
11153 .input_mux = &alc262_capture_source,
11154 .unsol_event = alc262_tyan_unsol_event,
11155 .init_hook = alc262_tyan_automute,
11159 static int patch_alc262(struct hda_codec *codec)
11161 struct alc_spec *spec;
11165 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11169 codec->spec = spec;
11171 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11176 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11177 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11178 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11179 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11183 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11185 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11189 if (board_config < 0) {
11190 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
11191 "trying auto-probe from BIOS...\n");
11192 board_config = ALC262_AUTO;
11195 if (board_config == ALC262_AUTO) {
11196 /* automatic parse from the BIOS config */
11197 err = alc262_parse_auto_config(codec);
11203 "hda_codec: Cannot set up configuration "
11204 "from BIOS. Using base mode...\n");
11205 board_config = ALC262_BASIC;
11209 if (!spec->no_analog) {
11210 err = snd_hda_attach_beep_device(codec, 0x1);
11217 if (board_config != ALC262_AUTO)
11218 setup_preset(spec, &alc262_presets[board_config]);
11220 spec->stream_name_analog = "ALC262 Analog";
11221 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11222 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11224 spec->stream_name_digital = "ALC262 Digital";
11225 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11226 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11228 spec->capture_style = CAPT_MIX;
11229 if (!spec->adc_nids && spec->input_mux) {
11230 /* check whether NID 0x07 is valid */
11231 unsigned int wcap = get_wcaps(codec, 0x07);
11234 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11235 if (wcap != AC_WID_AUD_IN) {
11236 spec->adc_nids = alc262_adc_nids_alt;
11237 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
11238 spec->capsrc_nids = alc262_capsrc_nids_alt;
11240 spec->adc_nids = alc262_adc_nids;
11241 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
11242 spec->capsrc_nids = alc262_capsrc_nids;
11245 if (!spec->cap_mixer && !spec->no_analog)
11246 set_capture_mixer(spec);
11247 if (!spec->no_analog)
11248 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11250 spec->vmaster_nid = 0x0c;
11252 codec->patch_ops = alc_patch_ops;
11253 if (board_config == ALC262_AUTO)
11254 spec->init_hook = alc262_auto_init;
11255 #ifdef CONFIG_SND_HDA_POWER_SAVE
11256 if (!spec->loopback.amplist)
11257 spec->loopback.amplist = alc262_loopbacks;
11259 codec->proc_widget_hook = print_realtek_coef;
11265 * ALC268 channel source setting (2 channel)
11267 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11268 #define alc268_modes alc260_modes
11270 static hda_nid_t alc268_dac_nids[2] = {
11275 static hda_nid_t alc268_adc_nids[2] = {
11280 static hda_nid_t alc268_adc_nids_alt[1] = {
11285 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11287 static struct snd_kcontrol_new alc268_base_mixer[] = {
11288 /* output mixer control */
11289 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11293 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11295 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11299 /* bind Beep switches of both NID 0x0f and 0x10 */
11300 static struct hda_bind_ctls alc268_bind_beep_sw = {
11301 .ops = &snd_hda_bind_sw,
11303 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11304 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11309 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11310 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11311 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11315 static struct hda_verb alc268_eapd_verbs[] = {
11316 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11317 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11321 /* Toshiba specific */
11322 #define alc268_toshiba_automute alc262_hippo_automute
11324 static struct hda_verb alc268_toshiba_verbs[] = {
11325 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11329 static struct hda_input_mux alc268_acer_lc_capture_source = {
11337 /* Acer specific */
11338 /* bind volumes of both NID 0x02 and 0x03 */
11339 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11340 .ops = &snd_hda_bind_vol,
11342 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11343 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11348 /* mute/unmute internal speaker according to the hp jack and mute state */
11349 static void alc268_acer_automute(struct hda_codec *codec, int force)
11351 struct alc_spec *spec = codec->spec;
11354 if (force || !spec->sense_updated) {
11355 unsigned int present;
11356 present = snd_hda_codec_read(codec, 0x14, 0,
11357 AC_VERB_GET_PIN_SENSE, 0);
11358 spec->jack_present = (present & 0x80000000) != 0;
11359 spec->sense_updated = 1;
11361 if (spec->jack_present)
11362 mute = HDA_AMP_MUTE; /* mute internal speaker */
11363 else /* unmute internal speaker if necessary */
11364 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11365 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11366 HDA_AMP_MUTE, mute);
11370 /* bind hp and internal speaker mute (with plug check) */
11371 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11372 struct snd_ctl_elem_value *ucontrol)
11374 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11375 long *valp = ucontrol->value.integer.value;
11378 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11380 valp[0] ? 0 : HDA_AMP_MUTE);
11381 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11383 valp[1] ? 0 : HDA_AMP_MUTE);
11385 alc268_acer_automute(codec, 0);
11389 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11390 /* output mixer control */
11391 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11394 .name = "Master Playback Switch",
11395 .info = snd_hda_mixer_amp_switch_info,
11396 .get = snd_hda_mixer_amp_switch_get,
11397 .put = alc268_acer_master_sw_put,
11398 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11400 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11404 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11405 /* output mixer control */
11406 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11409 .name = "Master Playback Switch",
11410 .info = snd_hda_mixer_amp_switch_info,
11411 .get = snd_hda_mixer_amp_switch_get,
11412 .put = alc268_acer_master_sw_put,
11413 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11415 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11416 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11417 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11421 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11422 /* output mixer control */
11423 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11425 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11426 .name = "Master Playback Switch",
11427 .info = snd_hda_mixer_amp_switch_info,
11428 .get = snd_hda_mixer_amp_switch_get,
11429 .put = alc268_acer_master_sw_put,
11430 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11432 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11433 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11437 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11438 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11439 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11440 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11441 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11442 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11443 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11447 static struct hda_verb alc268_acer_verbs[] = {
11448 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11449 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11450 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11453 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11454 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11458 /* unsolicited event for HP jack sensing */
11459 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
11462 if ((res >> 26) != ALC880_HP_EVENT)
11464 alc268_toshiba_automute(codec);
11467 static void alc268_acer_unsol_event(struct hda_codec *codec,
11470 if ((res >> 26) != ALC880_HP_EVENT)
11472 alc268_acer_automute(codec, 1);
11475 static void alc268_acer_init_hook(struct hda_codec *codec)
11477 alc268_acer_automute(codec, 1);
11480 /* toggle speaker-output according to the hp-jack state */
11481 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11483 unsigned int present;
11484 unsigned char bits;
11486 present = snd_hda_codec_read(codec, 0x15, 0,
11487 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11488 bits = present ? AMP_IN_MUTE(0) : 0;
11489 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11490 AMP_IN_MUTE(0), bits);
11491 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11492 AMP_IN_MUTE(0), bits);
11496 static void alc268_acer_mic_automute(struct hda_codec *codec)
11498 unsigned int present;
11500 present = snd_hda_codec_read(codec, 0x18, 0,
11501 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11502 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11503 present ? 0x0 : 0x6);
11506 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11509 if ((res >> 26) == ALC880_HP_EVENT)
11510 alc268_aspire_one_speaker_automute(codec);
11511 if ((res >> 26) == ALC880_MIC_EVENT)
11512 alc268_acer_mic_automute(codec);
11515 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11517 alc268_aspire_one_speaker_automute(codec);
11518 alc268_acer_mic_automute(codec);
11521 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11522 /* output mixer control */
11523 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11524 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11525 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11527 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11528 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11532 static struct hda_verb alc268_dell_verbs[] = {
11533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11539 /* mute/unmute internal speaker according to the hp jack and mute state */
11540 static void alc268_dell_automute(struct hda_codec *codec)
11542 unsigned int present;
11545 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11546 if (present & 0x80000000)
11547 mute = HDA_AMP_MUTE;
11549 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11550 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11551 HDA_AMP_MUTE, mute);
11554 static void alc268_dell_unsol_event(struct hda_codec *codec,
11557 if ((res >> 26) != ALC880_HP_EVENT)
11559 alc268_dell_automute(codec);
11562 #define alc268_dell_init_hook alc268_dell_automute
11564 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11565 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11569 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11570 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11571 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11572 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11576 static struct hda_verb alc267_quanta_il1_verbs[] = {
11577 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11578 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11582 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11584 unsigned int present;
11586 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11587 & AC_PINSENSE_PRESENCE;
11588 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11589 present ? 0 : PIN_OUT);
11592 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11594 unsigned int present;
11596 present = snd_hda_codec_read(codec, 0x18, 0,
11597 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11598 snd_hda_codec_write(codec, 0x23, 0,
11599 AC_VERB_SET_CONNECT_SEL,
11600 present ? 0x00 : 0x01);
11603 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11605 alc267_quanta_il1_hp_automute(codec);
11606 alc267_quanta_il1_mic_automute(codec);
11609 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11612 switch (res >> 26) {
11613 case ALC880_HP_EVENT:
11614 alc267_quanta_il1_hp_automute(codec);
11616 case ALC880_MIC_EVENT:
11617 alc267_quanta_il1_mic_automute(codec);
11623 * generic initialization of ADC, input mixers and output mixers
11625 static struct hda_verb alc268_base_init_verbs[] = {
11626 /* Unmute DAC0-1 and set vol = 0 */
11627 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11628 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11631 * Set up output mixers (0x0c - 0x0e)
11633 /* set vol=0 to output mixers */
11634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11635 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11638 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11642 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11643 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11644 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11646 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11647 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11652 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11653 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11655 /* set PCBEEP vol = 0, mute connections */
11656 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11657 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11658 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11660 /* Unmute Selector 23h,24h and set the default input to mic-in */
11662 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11664 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11671 * generic initialization of ADC, input mixers and output mixers
11673 static struct hda_verb alc268_volume_init_verbs[] = {
11674 /* set output DAC */
11675 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11676 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11678 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11679 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11681 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11682 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11684 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11686 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11688 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11689 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11691 /* set PCBEEP vol = 0, mute connections */
11692 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11694 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11699 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11700 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11701 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11704 /* The multiple "Capture Source" controls confuse alsamixer
11705 * So call somewhat different..
11707 /* .name = "Capture Source", */
11708 .name = "Input Source",
11710 .info = alc_mux_enum_info,
11711 .get = alc_mux_enum_get,
11712 .put = alc_mux_enum_put,
11717 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11718 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11719 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11720 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11721 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11723 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11724 /* The multiple "Capture Source" controls confuse alsamixer
11725 * So call somewhat different..
11727 /* .name = "Capture Source", */
11728 .name = "Input Source",
11730 .info = alc_mux_enum_info,
11731 .get = alc_mux_enum_get,
11732 .put = alc_mux_enum_put,
11737 static struct hda_input_mux alc268_capture_source = {
11741 { "Front Mic", 0x1 },
11747 static struct hda_input_mux alc268_acer_capture_source = {
11751 { "Internal Mic", 0x1 },
11756 static struct hda_input_mux alc268_acer_dmic_capture_source = {
11760 { "Internal Mic", 0x6 },
11765 #ifdef CONFIG_SND_DEBUG
11766 static struct snd_kcontrol_new alc268_test_mixer[] = {
11767 /* Volume widgets */
11768 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11769 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11770 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11771 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11772 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11773 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11774 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11775 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11776 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11777 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11778 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11779 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11780 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11781 /* The below appears problematic on some hardwares */
11782 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11783 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11784 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11785 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11786 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11788 /* Modes for retasking pin widgets */
11789 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11790 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11791 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11792 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11794 /* Controls for GPIO pins, assuming they are configured as outputs */
11795 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11796 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11797 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11798 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11800 /* Switches to allow the digital SPDIF output pin to be enabled.
11801 * The ALC268 does not have an SPDIF input.
11803 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11805 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11806 * this output to turn on an external amplifier.
11808 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11809 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11815 /* create input playback/capture controls for the given pin */
11816 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11817 const char *ctlname, int idx)
11822 sprintf(name, "%s Playback Volume", ctlname);
11824 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11825 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11829 } else if (nid == 0x15) {
11830 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11831 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11837 sprintf(name, "%s Playback Switch", ctlname);
11838 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11839 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11845 /* add playback controls from the parsed DAC table */
11846 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11847 const struct auto_pin_cfg *cfg)
11852 spec->multiout.num_dacs = 2; /* only use one dac */
11853 spec->multiout.dac_nids = spec->private_dac_nids;
11854 spec->multiout.dac_nids[0] = 2;
11855 spec->multiout.dac_nids[1] = 3;
11857 nid = cfg->line_out_pins[0];
11859 alc268_new_analog_output(spec, nid, "Front", 0);
11861 nid = cfg->speaker_pins[0];
11863 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11864 "Speaker Playback Volume",
11865 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11869 nid = cfg->hp_pins[0];
11871 alc268_new_analog_output(spec, nid, "Headphone", 0);
11873 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11875 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11876 "Mono Playback Switch",
11877 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11884 /* create playback/capture controls for input pins */
11885 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11886 const struct auto_pin_cfg *cfg)
11888 struct hda_input_mux *imux = &spec->private_imux[0];
11891 for (i = 0; i < AUTO_PIN_LAST; i++) {
11892 switch(cfg->input_pins[i]) {
11894 idx1 = 0; /* Mic 1 */
11897 idx1 = 1; /* Mic 2 */
11900 idx1 = 2; /* Line In */
11907 idx1 = 6; /* digital mics */
11912 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11913 imux->items[imux->num_items].index = idx1;
11919 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11921 struct alc_spec *spec = codec->spec;
11922 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11923 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11924 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11925 unsigned int dac_vol1, dac_vol2;
11928 snd_hda_codec_write(codec, speaker_nid, 0,
11929 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11930 snd_hda_codec_write(codec, 0x0f, 0,
11931 AC_VERB_SET_AMP_GAIN_MUTE,
11933 snd_hda_codec_write(codec, 0x10, 0,
11934 AC_VERB_SET_AMP_GAIN_MUTE,
11937 snd_hda_codec_write(codec, 0x0f, 0,
11938 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11939 snd_hda_codec_write(codec, 0x10, 0,
11940 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11943 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11944 if (line_nid == 0x14)
11945 dac_vol2 = AMP_OUT_ZERO;
11946 else if (line_nid == 0x15)
11947 dac_vol1 = AMP_OUT_ZERO;
11948 if (hp_nid == 0x14)
11949 dac_vol2 = AMP_OUT_ZERO;
11950 else if (hp_nid == 0x15)
11951 dac_vol1 = AMP_OUT_ZERO;
11952 if (line_nid != 0x16 || hp_nid != 0x16 ||
11953 spec->autocfg.line_out_pins[1] != 0x16 ||
11954 spec->autocfg.line_out_pins[2] != 0x16)
11955 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11957 snd_hda_codec_write(codec, 0x02, 0,
11958 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11959 snd_hda_codec_write(codec, 0x03, 0,
11960 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11963 /* pcm configuration: identiacal with ALC880 */
11964 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11965 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11966 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11967 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11970 * BIOS auto configuration
11972 static int alc268_parse_auto_config(struct hda_codec *codec)
11974 struct alc_spec *spec = codec->spec;
11976 static hda_nid_t alc268_ignore[] = { 0 };
11978 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11982 if (!spec->autocfg.line_outs) {
11983 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11984 spec->multiout.max_channels = 2;
11985 spec->no_analog = 1;
11988 return 0; /* can't find valid BIOS pin config */
11990 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11993 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11997 spec->multiout.max_channels = 2;
12000 /* digital only support output */
12001 if (spec->autocfg.dig_outs) {
12002 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12003 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12005 if (spec->kctls.list)
12006 add_mixer(spec, spec->kctls.list);
12008 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12009 add_mixer(spec, alc268_beep_mixer);
12011 add_verb(spec, alc268_volume_init_verbs);
12012 spec->num_mux_defs = 1;
12013 spec->input_mux = &spec->private_imux[0];
12015 err = alc_auto_add_mic_boost(codec);
12022 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12023 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12024 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12026 /* init callback for auto-configuration model -- overriding the default init */
12027 static void alc268_auto_init(struct hda_codec *codec)
12029 struct alc_spec *spec = codec->spec;
12030 alc268_auto_init_multi_out(codec);
12031 alc268_auto_init_hp_out(codec);
12032 alc268_auto_init_mono_speaker_out(codec);
12033 alc268_auto_init_analog_input(codec);
12034 if (spec->unsol_event)
12035 alc_inithook(codec);
12039 * configuration and preset
12041 static const char *alc268_models[ALC268_MODEL_LAST] = {
12042 [ALC267_QUANTA_IL1] = "quanta-il1",
12043 [ALC268_3ST] = "3stack",
12044 [ALC268_TOSHIBA] = "toshiba",
12045 [ALC268_ACER] = "acer",
12046 [ALC268_ACER_DMIC] = "acer-dmic",
12047 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12048 [ALC268_DELL] = "dell",
12049 [ALC268_ZEPTO] = "zepto",
12050 #ifdef CONFIG_SND_DEBUG
12051 [ALC268_TEST] = "test",
12053 [ALC268_AUTO] = "auto",
12056 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12057 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12058 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12059 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12060 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12061 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12062 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12063 ALC268_ACER_ASPIRE_ONE),
12064 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12065 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12066 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
12067 SND_PCI_QUIRK(0x103c, 0x30f1, "HP TX25xx series", ALC268_TOSHIBA),
12068 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12069 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
12070 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
12071 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
12072 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12073 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12074 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12075 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12079 static struct alc_config_preset alc268_presets[] = {
12080 [ALC267_QUANTA_IL1] = {
12081 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12082 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12083 alc267_quanta_il1_verbs },
12084 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12085 .dac_nids = alc268_dac_nids,
12086 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12087 .adc_nids = alc268_adc_nids_alt,
12089 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12090 .channel_mode = alc268_modes,
12091 .input_mux = &alc268_capture_source,
12092 .unsol_event = alc267_quanta_il1_unsol_event,
12093 .init_hook = alc267_quanta_il1_automute,
12096 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12097 alc268_beep_mixer },
12098 .init_verbs = { alc268_base_init_verbs },
12099 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12100 .dac_nids = alc268_dac_nids,
12101 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12102 .adc_nids = alc268_adc_nids_alt,
12103 .capsrc_nids = alc268_capsrc_nids,
12105 .dig_out_nid = ALC268_DIGOUT_NID,
12106 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12107 .channel_mode = alc268_modes,
12108 .input_mux = &alc268_capture_source,
12110 [ALC268_TOSHIBA] = {
12111 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12112 alc268_beep_mixer },
12113 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12114 alc268_toshiba_verbs },
12115 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12116 .dac_nids = alc268_dac_nids,
12117 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12118 .adc_nids = alc268_adc_nids_alt,
12119 .capsrc_nids = alc268_capsrc_nids,
12121 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12122 .channel_mode = alc268_modes,
12123 .input_mux = &alc268_capture_source,
12124 .unsol_event = alc268_toshiba_unsol_event,
12125 .init_hook = alc268_toshiba_automute,
12128 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12129 alc268_beep_mixer },
12130 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12131 alc268_acer_verbs },
12132 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12133 .dac_nids = alc268_dac_nids,
12134 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12135 .adc_nids = alc268_adc_nids_alt,
12136 .capsrc_nids = alc268_capsrc_nids,
12138 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12139 .channel_mode = alc268_modes,
12140 .input_mux = &alc268_acer_capture_source,
12141 .unsol_event = alc268_acer_unsol_event,
12142 .init_hook = alc268_acer_init_hook,
12144 [ALC268_ACER_DMIC] = {
12145 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12146 alc268_beep_mixer },
12147 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12148 alc268_acer_verbs },
12149 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12150 .dac_nids = alc268_dac_nids,
12151 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12152 .adc_nids = alc268_adc_nids_alt,
12153 .capsrc_nids = alc268_capsrc_nids,
12155 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12156 .channel_mode = alc268_modes,
12157 .input_mux = &alc268_acer_dmic_capture_source,
12158 .unsol_event = alc268_acer_unsol_event,
12159 .init_hook = alc268_acer_init_hook,
12161 [ALC268_ACER_ASPIRE_ONE] = {
12162 .mixers = { alc268_acer_aspire_one_mixer,
12164 alc268_capture_alt_mixer },
12165 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12166 alc268_acer_aspire_one_verbs },
12167 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12168 .dac_nids = alc268_dac_nids,
12169 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12170 .adc_nids = alc268_adc_nids_alt,
12171 .capsrc_nids = alc268_capsrc_nids,
12173 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12174 .channel_mode = alc268_modes,
12175 .input_mux = &alc268_acer_lc_capture_source,
12176 .unsol_event = alc268_acer_lc_unsol_event,
12177 .init_hook = alc268_acer_lc_init_hook,
12180 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12181 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12182 alc268_dell_verbs },
12183 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12184 .dac_nids = alc268_dac_nids,
12186 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12187 .channel_mode = alc268_modes,
12188 .unsol_event = alc268_dell_unsol_event,
12189 .init_hook = alc268_dell_init_hook,
12190 .input_mux = &alc268_capture_source,
12193 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12194 alc268_beep_mixer },
12195 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12196 alc268_toshiba_verbs },
12197 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12198 .dac_nids = alc268_dac_nids,
12199 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12200 .adc_nids = alc268_adc_nids_alt,
12201 .capsrc_nids = alc268_capsrc_nids,
12203 .dig_out_nid = ALC268_DIGOUT_NID,
12204 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12205 .channel_mode = alc268_modes,
12206 .input_mux = &alc268_capture_source,
12207 .unsol_event = alc268_toshiba_unsol_event,
12208 .init_hook = alc268_toshiba_automute
12210 #ifdef CONFIG_SND_DEBUG
12212 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12213 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12214 alc268_volume_init_verbs },
12215 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12216 .dac_nids = alc268_dac_nids,
12217 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12218 .adc_nids = alc268_adc_nids_alt,
12219 .capsrc_nids = alc268_capsrc_nids,
12221 .dig_out_nid = ALC268_DIGOUT_NID,
12222 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12223 .channel_mode = alc268_modes,
12224 .input_mux = &alc268_capture_source,
12229 static int patch_alc268(struct hda_codec *codec)
12231 struct alc_spec *spec;
12233 int i, has_beep, err;
12235 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12239 codec->spec = spec;
12241 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12245 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12246 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
12247 "trying auto-probe from BIOS...\n");
12248 board_config = ALC268_AUTO;
12251 if (board_config == ALC268_AUTO) {
12252 /* automatic parse from the BIOS config */
12253 err = alc268_parse_auto_config(codec);
12259 "hda_codec: Cannot set up configuration "
12260 "from BIOS. Using base mode...\n");
12261 board_config = ALC268_3ST;
12265 if (board_config != ALC268_AUTO)
12266 setup_preset(spec, &alc268_presets[board_config]);
12268 if (codec->vendor_id == 0x10ec0267) {
12269 spec->stream_name_analog = "ALC267 Analog";
12270 spec->stream_name_digital = "ALC267 Digital";
12272 spec->stream_name_analog = "ALC268 Analog";
12273 spec->stream_name_digital = "ALC268 Digital";
12276 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12277 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12278 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12280 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12283 for (i = 0; i < spec->num_mixers; i++) {
12284 if (spec->mixers[i] == alc268_beep_mixer) {
12291 err = snd_hda_attach_beep_device(codec, 0x1);
12296 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12297 /* override the amp caps for beep generator */
12298 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12299 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12300 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12301 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12302 (0 << AC_AMPCAP_MUTE_SHIFT));
12305 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12306 /* check whether NID 0x07 is valid */
12307 unsigned int wcap = get_wcaps(codec, 0x07);
12311 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12312 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12313 spec->adc_nids = alc268_adc_nids_alt;
12314 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12315 add_mixer(spec, alc268_capture_alt_mixer);
12317 spec->adc_nids = alc268_adc_nids;
12318 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12319 add_mixer(spec, alc268_capture_mixer);
12321 spec->capsrc_nids = alc268_capsrc_nids;
12322 /* set default input source */
12323 for (i = 0; i < spec->num_adc_nids; i++)
12324 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12325 0, AC_VERB_SET_CONNECT_SEL,
12326 spec->input_mux->items[0].index);
12329 spec->vmaster_nid = 0x02;
12331 codec->patch_ops = alc_patch_ops;
12332 if (board_config == ALC268_AUTO)
12333 spec->init_hook = alc268_auto_init;
12335 codec->proc_widget_hook = print_realtek_coef;
12341 * ALC269 channel source setting (2 channel)
12343 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12345 #define alc269_dac_nids alc260_dac_nids
12347 static hda_nid_t alc269_adc_nids[1] = {
12352 static hda_nid_t alc269_capsrc_nids[1] = {
12356 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12360 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12368 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12376 #define alc269_modes alc260_modes
12377 #define alc269_capture_source alc880_lg_lw_capture_source
12379 static struct snd_kcontrol_new alc269_base_mixer[] = {
12380 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12381 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12382 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12383 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12385 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12386 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12387 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12388 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12389 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12391 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12395 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12396 /* output mixer control */
12397 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12400 .name = "Master Playback Switch",
12401 .info = snd_hda_mixer_amp_switch_info,
12402 .get = snd_hda_mixer_amp_switch_get,
12403 .put = alc268_acer_master_sw_put,
12404 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12408 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12410 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12411 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12415 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12416 /* output mixer control */
12417 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12419 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12420 .name = "Master Playback Switch",
12421 .info = snd_hda_mixer_amp_switch_info,
12422 .get = snd_hda_mixer_amp_switch_get,
12423 .put = alc268_acer_master_sw_put,
12424 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12428 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12429 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12430 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12431 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12433 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12434 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12438 /* bind volumes of both NID 0x0c and 0x0d */
12439 static struct hda_bind_ctls alc269_epc_bind_vol = {
12440 .ops = &snd_hda_bind_vol,
12442 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12443 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12448 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12449 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12450 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12451 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12455 /* capture mixer elements */
12456 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12457 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12458 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12459 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12464 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12465 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12466 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12467 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12471 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12475 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12476 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12477 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12481 static struct hda_verb alc269_lifebook_verbs[] = {
12482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12483 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12484 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12485 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12487 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12488 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12489 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12490 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12491 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12495 /* toggle speaker-output according to the hp-jack state */
12496 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12498 unsigned int present;
12499 unsigned char bits;
12501 present = snd_hda_codec_read(codec, 0x15, 0,
12502 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12503 bits = present ? AMP_IN_MUTE(0) : 0;
12504 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12505 AMP_IN_MUTE(0), bits);
12506 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12507 AMP_IN_MUTE(0), bits);
12509 snd_hda_codec_write(codec, 0x20, 0,
12510 AC_VERB_SET_COEF_INDEX, 0x0c);
12511 snd_hda_codec_write(codec, 0x20, 0,
12512 AC_VERB_SET_PROC_COEF, 0x680);
12514 snd_hda_codec_write(codec, 0x20, 0,
12515 AC_VERB_SET_COEF_INDEX, 0x0c);
12516 snd_hda_codec_write(codec, 0x20, 0,
12517 AC_VERB_SET_PROC_COEF, 0x480);
12520 /* toggle speaker-output according to the hp-jacks state */
12521 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12523 unsigned int present;
12524 unsigned char bits;
12526 /* Check laptop headphone socket */
12527 present = snd_hda_codec_read(codec, 0x15, 0,
12528 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12530 /* Check port replicator headphone socket */
12531 present |= snd_hda_codec_read(codec, 0x1a, 0,
12532 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12534 bits = present ? AMP_IN_MUTE(0) : 0;
12535 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12536 AMP_IN_MUTE(0), bits);
12537 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12538 AMP_IN_MUTE(0), bits);
12540 snd_hda_codec_write(codec, 0x20, 0,
12541 AC_VERB_SET_COEF_INDEX, 0x0c);
12542 snd_hda_codec_write(codec, 0x20, 0,
12543 AC_VERB_SET_PROC_COEF, 0x680);
12545 snd_hda_codec_write(codec, 0x20, 0,
12546 AC_VERB_SET_COEF_INDEX, 0x0c);
12547 snd_hda_codec_write(codec, 0x20, 0,
12548 AC_VERB_SET_PROC_COEF, 0x480);
12551 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12553 unsigned int present;
12555 present = snd_hda_codec_read(codec, 0x18, 0,
12556 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12557 snd_hda_codec_write(codec, 0x23, 0,
12558 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12561 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12563 unsigned int present_laptop;
12564 unsigned int present_dock;
12566 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12569 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12570 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12572 /* Laptop mic port overrides dock mic port, design decision */
12574 snd_hda_codec_write(codec, 0x23, 0,
12575 AC_VERB_SET_CONNECT_SEL, 0x3);
12576 if (present_laptop)
12577 snd_hda_codec_write(codec, 0x23, 0,
12578 AC_VERB_SET_CONNECT_SEL, 0x0);
12579 if (!present_dock && !present_laptop)
12580 snd_hda_codec_write(codec, 0x23, 0,
12581 AC_VERB_SET_CONNECT_SEL, 0x1);
12584 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12587 if ((res >> 26) == ALC880_HP_EVENT)
12588 alc269_quanta_fl1_speaker_automute(codec);
12589 if ((res >> 26) == ALC880_MIC_EVENT)
12590 alc269_quanta_fl1_mic_automute(codec);
12593 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12596 if ((res >> 26) == ALC880_HP_EVENT)
12597 alc269_lifebook_speaker_automute(codec);
12598 if ((res >> 26) == ALC880_MIC_EVENT)
12599 alc269_lifebook_mic_autoswitch(codec);
12602 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12604 alc269_quanta_fl1_speaker_automute(codec);
12605 alc269_quanta_fl1_mic_automute(codec);
12608 static void alc269_lifebook_init_hook(struct hda_codec *codec)
12610 alc269_lifebook_speaker_automute(codec);
12611 alc269_lifebook_mic_autoswitch(codec);
12614 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12616 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12617 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12619 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12620 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12621 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12625 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12626 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12627 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12628 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12631 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12635 /* toggle speaker-output according to the hp-jack state */
12636 static void alc269_speaker_automute(struct hda_codec *codec)
12638 unsigned int present;
12639 unsigned char bits;
12641 present = snd_hda_codec_read(codec, 0x15, 0,
12642 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12643 bits = present ? AMP_IN_MUTE(0) : 0;
12644 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12645 AMP_IN_MUTE(0), bits);
12646 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12647 AMP_IN_MUTE(0), bits);
12650 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12652 unsigned int present;
12654 present = snd_hda_codec_read(codec, 0x18, 0,
12655 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12656 snd_hda_codec_write(codec, 0x23, 0,
12657 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12660 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12662 unsigned int present;
12664 present = snd_hda_codec_read(codec, 0x18, 0,
12665 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12666 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12667 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12668 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12669 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12672 /* unsolicited event for HP jack sensing */
12673 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12676 if ((res >> 26) == ALC880_HP_EVENT)
12677 alc269_speaker_automute(codec);
12679 if ((res >> 26) == ALC880_MIC_EVENT)
12680 alc269_eeepc_dmic_automute(codec);
12683 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12685 alc269_speaker_automute(codec);
12686 alc269_eeepc_dmic_automute(codec);
12689 /* unsolicited event for HP jack sensing */
12690 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12693 if ((res >> 26) == ALC880_HP_EVENT)
12694 alc269_speaker_automute(codec);
12696 if ((res >> 26) == ALC880_MIC_EVENT)
12697 alc269_eeepc_amic_automute(codec);
12700 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12702 alc269_speaker_automute(codec);
12703 alc269_eeepc_amic_automute(codec);
12707 * generic initialization of ADC, input mixers and output mixers
12709 static struct hda_verb alc269_init_verbs[] = {
12711 * Unmute ADC0 and set the default input to mic-in
12713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12715 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12716 * analog-loopback mixer widget
12717 * Note: PASD motherboards uses the Line In 2 as the input for
12718 * front panel mic (mic 2)
12720 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12728 * Set up output mixers (0x0c - 0x0e)
12730 /* set vol=0 to output mixers */
12731 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12732 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12734 /* set up input amps for analog loopback */
12735 /* Amp Indices: DAC = 0, mixer = 1 */
12736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12741 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12745 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12747 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12748 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12749 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12755 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12756 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12757 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12759 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12760 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12762 /* FIXME: use matrix-type input source selection */
12763 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12764 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12771 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12772 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12776 /* add playback controls from the parsed DAC table */
12777 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12778 const struct auto_pin_cfg *cfg)
12783 spec->multiout.num_dacs = 1; /* only use one dac */
12784 spec->multiout.dac_nids = spec->private_dac_nids;
12785 spec->multiout.dac_nids[0] = 2;
12787 nid = cfg->line_out_pins[0];
12789 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12790 "Front Playback Volume",
12791 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12794 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12795 "Front Playback Switch",
12796 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12801 nid = cfg->speaker_pins[0];
12803 if (!cfg->line_out_pins[0]) {
12804 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12805 "Speaker Playback Volume",
12806 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12812 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12813 "Speaker Playback Switch",
12814 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12819 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12820 "Speaker Playback Switch",
12821 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12827 nid = cfg->hp_pins[0];
12829 /* spec->multiout.hp_nid = 2; */
12830 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12831 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12832 "Headphone Playback Volume",
12833 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12839 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12840 "Headphone Playback Switch",
12841 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12846 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12847 "Headphone Playback Switch",
12848 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12857 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12858 const struct auto_pin_cfg *cfg)
12862 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12865 /* digital-mic input pin is excluded in alc880_auto_create..()
12866 * because it's under 0x18
12868 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12869 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12870 struct hda_input_mux *imux = &spec->private_imux[0];
12871 imux->items[imux->num_items].label = "Int Mic";
12872 imux->items[imux->num_items].index = 0x05;
12878 #ifdef CONFIG_SND_HDA_POWER_SAVE
12879 #define alc269_loopbacks alc880_loopbacks
12882 /* pcm configuration: identiacal with ALC880 */
12883 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12884 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12885 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12886 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12888 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
12892 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12893 /* NID is set in alc_build_pcms */
12895 .open = alc880_playback_pcm_open,
12896 .prepare = alc880_playback_pcm_prepare,
12897 .cleanup = alc880_playback_pcm_cleanup
12901 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
12905 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
12906 /* NID is set in alc_build_pcms */
12910 * BIOS auto configuration
12912 static int alc269_parse_auto_config(struct hda_codec *codec)
12914 struct alc_spec *spec = codec->spec;
12916 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12918 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12923 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12926 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12930 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12932 if (spec->autocfg.dig_outs)
12933 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12935 if (spec->kctls.list)
12936 add_mixer(spec, spec->kctls.list);
12938 add_verb(spec, alc269_init_verbs);
12939 spec->num_mux_defs = 1;
12940 spec->input_mux = &spec->private_imux[0];
12941 /* set default input source */
12942 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12943 0, AC_VERB_SET_CONNECT_SEL,
12944 spec->input_mux->items[0].index);
12946 err = alc_auto_add_mic_boost(codec);
12950 if (!spec->cap_mixer && !spec->no_analog)
12951 set_capture_mixer(spec);
12956 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12957 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12958 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12961 /* init callback for auto-configuration model -- overriding the default init */
12962 static void alc269_auto_init(struct hda_codec *codec)
12964 struct alc_spec *spec = codec->spec;
12965 alc269_auto_init_multi_out(codec);
12966 alc269_auto_init_hp_out(codec);
12967 alc269_auto_init_analog_input(codec);
12968 if (spec->unsol_event)
12969 alc_inithook(codec);
12973 * configuration and preset
12975 static const char *alc269_models[ALC269_MODEL_LAST] = {
12976 [ALC269_BASIC] = "basic",
12977 [ALC269_QUANTA_FL1] = "quanta",
12978 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12979 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12980 [ALC269_FUJITSU] = "fujitsu",
12981 [ALC269_LIFEBOOK] = "lifebook"
12984 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12985 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12986 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12987 ALC269_ASUS_EEEPC_P703),
12988 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
12989 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
12990 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
12991 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
12992 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
12993 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
12994 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12995 ALC269_ASUS_EEEPC_P901),
12996 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12997 ALC269_ASUS_EEEPC_P901),
12998 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
12999 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13000 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13004 static struct alc_config_preset alc269_presets[] = {
13006 .mixers = { alc269_base_mixer },
13007 .init_verbs = { alc269_init_verbs },
13008 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13009 .dac_nids = alc269_dac_nids,
13011 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13012 .channel_mode = alc269_modes,
13013 .input_mux = &alc269_capture_source,
13015 [ALC269_QUANTA_FL1] = {
13016 .mixers = { alc269_quanta_fl1_mixer },
13017 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13018 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13019 .dac_nids = alc269_dac_nids,
13021 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13022 .channel_mode = alc269_modes,
13023 .input_mux = &alc269_capture_source,
13024 .unsol_event = alc269_quanta_fl1_unsol_event,
13025 .init_hook = alc269_quanta_fl1_init_hook,
13027 [ALC269_ASUS_EEEPC_P703] = {
13028 .mixers = { alc269_eeepc_mixer },
13029 .cap_mixer = alc269_epc_capture_mixer,
13030 .init_verbs = { alc269_init_verbs,
13031 alc269_eeepc_amic_init_verbs },
13032 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13033 .dac_nids = alc269_dac_nids,
13035 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13036 .channel_mode = alc269_modes,
13037 .input_mux = &alc269_eeepc_amic_capture_source,
13038 .unsol_event = alc269_eeepc_amic_unsol_event,
13039 .init_hook = alc269_eeepc_amic_inithook,
13041 [ALC269_ASUS_EEEPC_P901] = {
13042 .mixers = { alc269_eeepc_mixer },
13043 .cap_mixer = alc269_epc_capture_mixer,
13044 .init_verbs = { alc269_init_verbs,
13045 alc269_eeepc_dmic_init_verbs },
13046 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13047 .dac_nids = alc269_dac_nids,
13049 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13050 .channel_mode = alc269_modes,
13051 .input_mux = &alc269_eeepc_dmic_capture_source,
13052 .unsol_event = alc269_eeepc_dmic_unsol_event,
13053 .init_hook = alc269_eeepc_dmic_inithook,
13055 [ALC269_FUJITSU] = {
13056 .mixers = { alc269_fujitsu_mixer },
13057 .cap_mixer = alc269_epc_capture_mixer,
13058 .init_verbs = { alc269_init_verbs,
13059 alc269_eeepc_dmic_init_verbs },
13060 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13061 .dac_nids = alc269_dac_nids,
13063 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13064 .channel_mode = alc269_modes,
13065 .input_mux = &alc269_eeepc_dmic_capture_source,
13066 .unsol_event = alc269_eeepc_dmic_unsol_event,
13067 .init_hook = alc269_eeepc_dmic_inithook,
13069 [ALC269_LIFEBOOK] = {
13070 .mixers = { alc269_lifebook_mixer },
13071 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13072 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13073 .dac_nids = alc269_dac_nids,
13075 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13076 .channel_mode = alc269_modes,
13077 .input_mux = &alc269_capture_source,
13078 .unsol_event = alc269_lifebook_unsol_event,
13079 .init_hook = alc269_lifebook_init_hook,
13083 static int patch_alc269(struct hda_codec *codec)
13085 struct alc_spec *spec;
13089 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13093 codec->spec = spec;
13095 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13097 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13101 if (board_config < 0) {
13102 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
13103 "trying auto-probe from BIOS...\n");
13104 board_config = ALC269_AUTO;
13107 if (board_config == ALC269_AUTO) {
13108 /* automatic parse from the BIOS config */
13109 err = alc269_parse_auto_config(codec);
13115 "hda_codec: Cannot set up configuration "
13116 "from BIOS. Using base mode...\n");
13117 board_config = ALC269_BASIC;
13121 err = snd_hda_attach_beep_device(codec, 0x1);
13127 if (board_config != ALC269_AUTO)
13128 setup_preset(spec, &alc269_presets[board_config]);
13130 spec->stream_name_analog = "ALC269 Analog";
13131 if (codec->subsystem_id == 0x17aa3bf8) {
13132 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13133 * fix the sample rate of analog I/O to 44.1kHz
13135 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13136 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13138 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13139 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13141 spec->stream_name_digital = "ALC269 Digital";
13142 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13143 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13145 spec->adc_nids = alc269_adc_nids;
13146 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13147 spec->capsrc_nids = alc269_capsrc_nids;
13148 if (!spec->cap_mixer)
13149 set_capture_mixer(spec);
13150 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13152 codec->patch_ops = alc_patch_ops;
13153 if (board_config == ALC269_AUTO)
13154 spec->init_hook = alc269_auto_init;
13155 #ifdef CONFIG_SND_HDA_POWER_SAVE
13156 if (!spec->loopback.amplist)
13157 spec->loopback.amplist = alc269_loopbacks;
13159 codec->proc_widget_hook = print_realtek_coef;
13165 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13169 * set the path ways for 2 channel output
13170 * need to set the codec line out and mic 1 pin widgets to inputs
13172 static struct hda_verb alc861_threestack_ch2_init[] = {
13173 /* set pin widget 1Ah (line in) for input */
13174 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13175 /* set pin widget 18h (mic1/2) for input, for mic also enable
13178 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13180 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13182 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13183 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13189 * need to set the codec line out and mic 1 pin widgets to outputs
13191 static struct hda_verb alc861_threestack_ch6_init[] = {
13192 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13193 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13194 /* set pin widget 18h (mic1) for output (CLFE)*/
13195 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13197 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13198 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13200 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13202 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13203 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13208 static struct hda_channel_mode alc861_threestack_modes[2] = {
13209 { 2, alc861_threestack_ch2_init },
13210 { 6, alc861_threestack_ch6_init },
13212 /* Set mic1 as input and unmute the mixer */
13213 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13214 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13215 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13218 /* Set mic1 as output and mute mixer */
13219 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13220 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13221 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13225 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13226 { 2, alc861_uniwill_m31_ch2_init },
13227 { 4, alc861_uniwill_m31_ch4_init },
13230 /* Set mic1 and line-in as input and unmute the mixer */
13231 static struct hda_verb alc861_asus_ch2_init[] = {
13232 /* set pin widget 1Ah (line in) for input */
13233 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13234 /* set pin widget 18h (mic1/2) for input, for mic also enable
13237 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13239 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13241 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13242 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13246 /* Set mic1 nad line-in as output and mute mixer */
13247 static struct hda_verb alc861_asus_ch6_init[] = {
13248 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13249 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13250 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13251 /* set pin widget 18h (mic1) for output (CLFE)*/
13252 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13253 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13254 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13255 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13257 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13259 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13260 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13265 static struct hda_channel_mode alc861_asus_modes[2] = {
13266 { 2, alc861_asus_ch2_init },
13267 { 6, alc861_asus_ch6_init },
13272 static struct snd_kcontrol_new alc861_base_mixer[] = {
13273 /* output mixer control */
13274 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13277 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13278 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13280 /*Input mixer control */
13281 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13282 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13283 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13284 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13285 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13286 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13288 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13289 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13290 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13295 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13296 /* output mixer control */
13297 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13298 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13299 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13300 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13301 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13303 /* Input mixer control */
13304 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13305 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13306 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13307 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13308 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13309 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13310 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13311 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13312 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13316 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13317 .name = "Channel Mode",
13318 .info = alc_ch_mode_info,
13319 .get = alc_ch_mode_get,
13320 .put = alc_ch_mode_put,
13321 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13326 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13327 /* output mixer control */
13328 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13330 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13335 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13336 /* output mixer control */
13337 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13338 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13339 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13340 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13341 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13343 /* Input mixer control */
13344 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13345 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13346 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13347 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13348 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13349 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13351 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13352 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13353 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13357 .name = "Channel Mode",
13358 .info = alc_ch_mode_info,
13359 .get = alc_ch_mode_get,
13360 .put = alc_ch_mode_put,
13361 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13366 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13367 /* output mixer control */
13368 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13369 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13370 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13371 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13372 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13374 /* Input mixer control */
13375 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13376 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13377 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13378 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13379 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13380 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13382 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13383 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13388 .name = "Channel Mode",
13389 .info = alc_ch_mode_info,
13390 .get = alc_ch_mode_get,
13391 .put = alc_ch_mode_put,
13392 .private_value = ARRAY_SIZE(alc861_asus_modes),
13397 /* additional mixer */
13398 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13399 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13400 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13405 * generic initialization of ADC, input mixers and output mixers
13407 static struct hda_verb alc861_base_init_verbs[] = {
13409 * Unmute ADC0 and set the default input to mic-in
13411 /* port-A for surround (rear panel) */
13412 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13413 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13414 /* port-B for mic-in (rear panel) with vref */
13415 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13416 /* port-C for line-in (rear panel) */
13417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13418 /* port-D for Front */
13419 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13420 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13421 /* port-E for HP out (front panel) */
13422 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13423 /* route front PCM to HP */
13424 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13425 /* port-F for mic-in (front panel) with vref */
13426 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13427 /* port-G for CLFE (rear panel) */
13428 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13429 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13430 /* port-H for side (rear panel) */
13431 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13432 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13434 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13435 /* route front mic to ADC1*/
13436 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13439 /* Unmute DAC0~3 & spdif out*/
13440 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13442 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13443 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13444 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13446 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13447 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13449 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13450 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13452 /* Unmute Stereo Mixer 15 */
13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13455 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13458 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13462 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13463 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13464 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13465 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13466 /* hp used DAC 3 (Front) */
13467 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13468 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13473 static struct hda_verb alc861_threestack_init_verbs[] = {
13475 * Unmute ADC0 and set the default input to mic-in
13477 /* port-A for surround (rear panel) */
13478 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13479 /* port-B for mic-in (rear panel) with vref */
13480 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13481 /* port-C for line-in (rear panel) */
13482 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13483 /* port-D for Front */
13484 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13485 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13486 /* port-E for HP out (front panel) */
13487 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13488 /* route front PCM to HP */
13489 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13490 /* port-F for mic-in (front panel) with vref */
13491 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13492 /* port-G for CLFE (rear panel) */
13493 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13494 /* port-H for side (rear panel) */
13495 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13497 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13498 /* route front mic to ADC1*/
13499 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13500 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13501 /* Unmute DAC0~3 & spdif out*/
13502 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13503 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13504 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13505 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13508 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13509 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13510 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13511 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13512 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13514 /* Unmute Stereo Mixer 15 */
13515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13520 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13521 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13522 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13523 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13524 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13525 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13526 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13527 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13528 /* hp used DAC 3 (Front) */
13529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13530 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13534 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13536 * Unmute ADC0 and set the default input to mic-in
13538 /* port-A for surround (rear panel) */
13539 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13540 /* port-B for mic-in (rear panel) with vref */
13541 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13542 /* port-C for line-in (rear panel) */
13543 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13544 /* port-D for Front */
13545 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13546 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13547 /* port-E for HP out (front panel) */
13548 /* this has to be set to VREF80 */
13549 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13550 /* route front PCM to HP */
13551 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13552 /* port-F for mic-in (front panel) with vref */
13553 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13554 /* port-G for CLFE (rear panel) */
13555 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13556 /* port-H for side (rear panel) */
13557 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13559 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13560 /* route front mic to ADC1*/
13561 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13562 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13563 /* Unmute DAC0~3 & spdif out*/
13564 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13565 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13566 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13567 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13570 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13571 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13572 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13573 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13574 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13576 /* Unmute Stereo Mixer 15 */
13577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13580 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13582 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13583 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13584 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13585 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13589 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13590 /* hp used DAC 3 (Front) */
13591 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13592 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13596 static struct hda_verb alc861_asus_init_verbs[] = {
13598 * Unmute ADC0 and set the default input to mic-in
13600 /* port-A for surround (rear panel)
13601 * according to codec#0 this is the HP jack
13603 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13604 /* route front PCM to HP */
13605 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13606 /* port-B for mic-in (rear panel) with vref */
13607 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13608 /* port-C for line-in (rear panel) */
13609 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13610 /* port-D for Front */
13611 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13612 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13613 /* port-E for HP out (front panel) */
13614 /* this has to be set to VREF80 */
13615 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13616 /* route front PCM to HP */
13617 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13618 /* port-F for mic-in (front panel) with vref */
13619 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13620 /* port-G for CLFE (rear panel) */
13621 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13622 /* port-H for side (rear panel) */
13623 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13625 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13626 /* route front mic to ADC1*/
13627 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13628 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13629 /* Unmute DAC0~3 & spdif out*/
13630 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13631 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13632 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13633 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13634 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13635 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13636 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13637 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13638 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13639 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13641 /* Unmute Stereo Mixer 15 */
13642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13647 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13648 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13649 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13650 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13651 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13652 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13655 /* hp used DAC 3 (Front) */
13656 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13657 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13661 /* additional init verbs for ASUS laptops */
13662 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13663 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13664 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13669 * generic initialization of ADC, input mixers and output mixers
13671 static struct hda_verb alc861_auto_init_verbs[] = {
13673 * Unmute ADC0 and set the default input to mic-in
13675 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13676 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13678 /* Unmute DAC0~3 & spdif out*/
13679 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13681 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13682 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13685 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13686 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13687 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13688 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13689 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13691 /* Unmute Stereo Mixer 15 */
13692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13693 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13697 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13698 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13699 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13702 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13703 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13706 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13709 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13711 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13712 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13713 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13715 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13720 static struct hda_verb alc861_toshiba_init_verbs[] = {
13721 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13726 /* toggle speaker-output according to the hp-jack state */
13727 static void alc861_toshiba_automute(struct hda_codec *codec)
13729 unsigned int present;
13731 present = snd_hda_codec_read(codec, 0x0f, 0,
13732 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13733 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13734 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13735 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13736 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13739 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13742 if ((res >> 26) == ALC880_HP_EVENT)
13743 alc861_toshiba_automute(codec);
13746 /* pcm configuration: identiacal with ALC880 */
13747 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13748 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13749 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13750 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13753 #define ALC861_DIGOUT_NID 0x07
13755 static struct hda_channel_mode alc861_8ch_modes[1] = {
13759 static hda_nid_t alc861_dac_nids[4] = {
13760 /* front, surround, clfe, side */
13761 0x03, 0x06, 0x05, 0x04
13764 static hda_nid_t alc660_dac_nids[3] = {
13765 /* front, clfe, surround */
13769 static hda_nid_t alc861_adc_nids[1] = {
13774 static struct hda_input_mux alc861_capture_source = {
13778 { "Front Mic", 0x3 },
13785 /* fill in the dac_nids table from the parsed pin configuration */
13786 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13787 const struct auto_pin_cfg *cfg)
13792 spec->multiout.dac_nids = spec->private_dac_nids;
13793 for (i = 0; i < cfg->line_outs; i++) {
13794 nid = cfg->line_out_pins[i];
13796 if (i >= ARRAY_SIZE(alc861_dac_nids))
13798 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13801 spec->multiout.num_dacs = cfg->line_outs;
13805 /* add playback controls from the parsed DAC table */
13806 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13807 const struct auto_pin_cfg *cfg)
13810 static const char *chname[4] = {
13811 "Front", "Surround", NULL /*CLFE*/, "Side"
13816 for (i = 0; i < cfg->line_outs; i++) {
13817 nid = spec->multiout.dac_nids[i];
13822 err = add_control(spec, ALC_CTL_BIND_MUTE,
13823 "Center Playback Switch",
13824 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13828 err = add_control(spec, ALC_CTL_BIND_MUTE,
13829 "LFE Playback Switch",
13830 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13835 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13837 if (nid == alc861_dac_nids[idx])
13839 sprintf(name, "%s Playback Switch", chname[idx]);
13840 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13841 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13850 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13858 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13860 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13861 "Headphone Playback Switch",
13862 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13865 spec->multiout.hp_nid = nid;
13870 /* create playback/capture controls for input pins */
13871 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13872 const struct auto_pin_cfg *cfg)
13874 struct hda_input_mux *imux = &spec->private_imux[0];
13875 int i, err, idx, idx1;
13877 for (i = 0; i < AUTO_PIN_LAST; i++) {
13878 switch (cfg->input_pins[i]) {
13881 idx = 2; /* Line In */
13885 idx = 2; /* Line In */
13889 idx = 1; /* Mic In */
13893 idx = 1; /* Mic In */
13903 err = new_analog_input(spec, cfg->input_pins[i],
13904 auto_pin_cfg_labels[i], idx, 0x15);
13908 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13909 imux->items[imux->num_items].index = idx1;
13915 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13917 int pin_type, int dac_idx)
13919 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13921 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13925 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13927 struct alc_spec *spec = codec->spec;
13930 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13931 for (i = 0; i < spec->autocfg.line_outs; i++) {
13932 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13933 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13935 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13936 spec->multiout.dac_nids[i]);
13940 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13942 struct alc_spec *spec = codec->spec;
13945 pin = spec->autocfg.hp_pins[0];
13946 if (pin) /* connect to front */
13947 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13948 spec->multiout.dac_nids[0]);
13949 pin = spec->autocfg.speaker_pins[0];
13951 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13954 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13956 struct alc_spec *spec = codec->spec;
13959 for (i = 0; i < AUTO_PIN_LAST; i++) {
13960 hda_nid_t nid = spec->autocfg.input_pins[i];
13961 if (nid >= 0x0c && nid <= 0x11)
13962 alc_set_input_pin(codec, nid, i);
13966 /* parse the BIOS configuration and set up the alc_spec */
13967 /* return 1 if successful, 0 if the proper config is not found,
13968 * or a negative error code
13970 static int alc861_parse_auto_config(struct hda_codec *codec)
13972 struct alc_spec *spec = codec->spec;
13974 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13976 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13980 if (!spec->autocfg.line_outs)
13981 return 0; /* can't find valid BIOS pin config */
13983 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13986 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13989 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13992 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13996 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13998 if (spec->autocfg.dig_outs)
13999 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14001 if (spec->kctls.list)
14002 add_mixer(spec, spec->kctls.list);
14004 add_verb(spec, alc861_auto_init_verbs);
14006 spec->num_mux_defs = 1;
14007 spec->input_mux = &spec->private_imux[0];
14009 spec->adc_nids = alc861_adc_nids;
14010 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14011 set_capture_mixer(spec);
14016 /* additional initialization for auto-configuration model */
14017 static void alc861_auto_init(struct hda_codec *codec)
14019 struct alc_spec *spec = codec->spec;
14020 alc861_auto_init_multi_out(codec);
14021 alc861_auto_init_hp_out(codec);
14022 alc861_auto_init_analog_input(codec);
14023 if (spec->unsol_event)
14024 alc_inithook(codec);
14027 #ifdef CONFIG_SND_HDA_POWER_SAVE
14028 static struct hda_amp_list alc861_loopbacks[] = {
14029 { 0x15, HDA_INPUT, 0 },
14030 { 0x15, HDA_INPUT, 1 },
14031 { 0x15, HDA_INPUT, 2 },
14032 { 0x15, HDA_INPUT, 3 },
14039 * configuration and preset
14041 static const char *alc861_models[ALC861_MODEL_LAST] = {
14042 [ALC861_3ST] = "3stack",
14043 [ALC660_3ST] = "3stack-660",
14044 [ALC861_3ST_DIG] = "3stack-dig",
14045 [ALC861_6ST_DIG] = "6stack-dig",
14046 [ALC861_UNIWILL_M31] = "uniwill-m31",
14047 [ALC861_TOSHIBA] = "toshiba",
14048 [ALC861_ASUS] = "asus",
14049 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14050 [ALC861_AUTO] = "auto",
14053 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14054 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14055 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14056 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14057 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14058 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14059 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14060 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14061 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14062 * Any other models that need this preset?
14064 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14065 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14066 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14067 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14068 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14069 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14070 /* FIXME: the below seems conflict */
14071 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14072 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14073 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14077 static struct alc_config_preset alc861_presets[] = {
14079 .mixers = { alc861_3ST_mixer },
14080 .init_verbs = { alc861_threestack_init_verbs },
14081 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14082 .dac_nids = alc861_dac_nids,
14083 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14084 .channel_mode = alc861_threestack_modes,
14086 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14087 .adc_nids = alc861_adc_nids,
14088 .input_mux = &alc861_capture_source,
14090 [ALC861_3ST_DIG] = {
14091 .mixers = { alc861_base_mixer },
14092 .init_verbs = { alc861_threestack_init_verbs },
14093 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14094 .dac_nids = alc861_dac_nids,
14095 .dig_out_nid = ALC861_DIGOUT_NID,
14096 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14097 .channel_mode = alc861_threestack_modes,
14099 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14100 .adc_nids = alc861_adc_nids,
14101 .input_mux = &alc861_capture_source,
14103 [ALC861_6ST_DIG] = {
14104 .mixers = { alc861_base_mixer },
14105 .init_verbs = { alc861_base_init_verbs },
14106 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14107 .dac_nids = alc861_dac_nids,
14108 .dig_out_nid = ALC861_DIGOUT_NID,
14109 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14110 .channel_mode = alc861_8ch_modes,
14111 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14112 .adc_nids = alc861_adc_nids,
14113 .input_mux = &alc861_capture_source,
14116 .mixers = { alc861_3ST_mixer },
14117 .init_verbs = { alc861_threestack_init_verbs },
14118 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14119 .dac_nids = alc660_dac_nids,
14120 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14121 .channel_mode = alc861_threestack_modes,
14123 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14124 .adc_nids = alc861_adc_nids,
14125 .input_mux = &alc861_capture_source,
14127 [ALC861_UNIWILL_M31] = {
14128 .mixers = { alc861_uniwill_m31_mixer },
14129 .init_verbs = { alc861_uniwill_m31_init_verbs },
14130 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14131 .dac_nids = alc861_dac_nids,
14132 .dig_out_nid = ALC861_DIGOUT_NID,
14133 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14134 .channel_mode = alc861_uniwill_m31_modes,
14136 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14137 .adc_nids = alc861_adc_nids,
14138 .input_mux = &alc861_capture_source,
14140 [ALC861_TOSHIBA] = {
14141 .mixers = { alc861_toshiba_mixer },
14142 .init_verbs = { alc861_base_init_verbs,
14143 alc861_toshiba_init_verbs },
14144 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14145 .dac_nids = alc861_dac_nids,
14146 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14147 .channel_mode = alc883_3ST_2ch_modes,
14148 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14149 .adc_nids = alc861_adc_nids,
14150 .input_mux = &alc861_capture_source,
14151 .unsol_event = alc861_toshiba_unsol_event,
14152 .init_hook = alc861_toshiba_automute,
14155 .mixers = { alc861_asus_mixer },
14156 .init_verbs = { alc861_asus_init_verbs },
14157 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14158 .dac_nids = alc861_dac_nids,
14159 .dig_out_nid = ALC861_DIGOUT_NID,
14160 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14161 .channel_mode = alc861_asus_modes,
14164 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14165 .adc_nids = alc861_adc_nids,
14166 .input_mux = &alc861_capture_source,
14168 [ALC861_ASUS_LAPTOP] = {
14169 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14170 .init_verbs = { alc861_asus_init_verbs,
14171 alc861_asus_laptop_init_verbs },
14172 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14173 .dac_nids = alc861_dac_nids,
14174 .dig_out_nid = ALC861_DIGOUT_NID,
14175 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14176 .channel_mode = alc883_3ST_2ch_modes,
14178 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14179 .adc_nids = alc861_adc_nids,
14180 .input_mux = &alc861_capture_source,
14185 static int patch_alc861(struct hda_codec *codec)
14187 struct alc_spec *spec;
14191 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14195 codec->spec = spec;
14197 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14201 if (board_config < 0) {
14202 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
14203 "trying auto-probe from BIOS...\n");
14204 board_config = ALC861_AUTO;
14207 if (board_config == ALC861_AUTO) {
14208 /* automatic parse from the BIOS config */
14209 err = alc861_parse_auto_config(codec);
14215 "hda_codec: Cannot set up configuration "
14216 "from BIOS. Using base mode...\n");
14217 board_config = ALC861_3ST_DIG;
14221 err = snd_hda_attach_beep_device(codec, 0x23);
14227 if (board_config != ALC861_AUTO)
14228 setup_preset(spec, &alc861_presets[board_config]);
14230 spec->stream_name_analog = "ALC861 Analog";
14231 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14232 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14234 spec->stream_name_digital = "ALC861 Digital";
14235 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14236 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14238 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14240 spec->vmaster_nid = 0x03;
14242 codec->patch_ops = alc_patch_ops;
14243 if (board_config == ALC861_AUTO)
14244 spec->init_hook = alc861_auto_init;
14245 #ifdef CONFIG_SND_HDA_POWER_SAVE
14246 if (!spec->loopback.amplist)
14247 spec->loopback.amplist = alc861_loopbacks;
14249 codec->proc_widget_hook = print_realtek_coef;
14255 * ALC861-VD support
14259 * In addition, an independent DAC
14261 #define ALC861VD_DIGOUT_NID 0x06
14263 static hda_nid_t alc861vd_dac_nids[4] = {
14264 /* front, surr, clfe, side surr */
14265 0x02, 0x03, 0x04, 0x05
14268 /* dac_nids for ALC660vd are in a different order - according to
14269 * Realtek's driver.
14270 * This should probably tesult in a different mixer for 6stack models
14271 * of ALC660vd codecs, but for now there is only 3stack mixer
14272 * - and it is the same as in 861vd.
14273 * adc_nids in ALC660vd are (is) the same as in 861vd
14275 static hda_nid_t alc660vd_dac_nids[3] = {
14276 /* front, rear, clfe, rear_surr */
14280 static hda_nid_t alc861vd_adc_nids[1] = {
14285 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14288 /* FIXME: should be a matrix-type input source selection */
14289 static struct hda_input_mux alc861vd_capture_source = {
14293 { "Front Mic", 0x1 },
14299 static struct hda_input_mux alc861vd_dallas_capture_source = {
14302 { "Ext Mic", 0x0 },
14303 { "Int Mic", 0x1 },
14307 static struct hda_input_mux alc861vd_hp_capture_source = {
14310 { "Front Mic", 0x0 },
14311 { "ATAPI Mic", 0x1 },
14318 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14325 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14326 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14327 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14328 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14329 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14336 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14337 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14338 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14339 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14340 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14344 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14345 { 6, alc861vd_6stack_ch6_init },
14346 { 8, alc861vd_6stack_ch8_init },
14349 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14352 .name = "Channel Mode",
14353 .info = alc_ch_mode_info,
14354 .get = alc_ch_mode_get,
14355 .put = alc_ch_mode_put,
14360 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14361 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14363 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14364 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14365 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14370 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14372 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14374 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14375 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14377 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14378 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14382 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14383 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14387 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14388 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14390 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14391 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14393 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14394 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14399 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14400 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14405 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14409 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14410 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14417 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14422 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14423 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14424 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14425 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14434 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14437 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14438 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14443 /* Pin assignment: Speaker=0x14, HP = 0x15,
14444 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14446 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14447 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14448 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14449 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14450 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14451 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14452 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14453 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14454 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14455 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14456 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14460 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14461 * Front Mic=0x18, ATAPI Mic = 0x19,
14463 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14464 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14465 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14466 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14467 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14468 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14469 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14470 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14471 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14477 * generic initialization of ADC, input mixers and output mixers
14479 static struct hda_verb alc861vd_volume_init_verbs[] = {
14481 * Unmute ADC0 and set the default input to mic-in
14483 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14486 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14487 * the analog-loopback mixer widget
14489 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14496 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14503 * Set up output mixers (0x02 - 0x05)
14505 /* set vol=0 to output mixers */
14506 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14507 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14508 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14509 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14511 /* set up input amps for analog loopback */
14512 /* Amp Indices: DAC = 0, mixer = 1 */
14513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14514 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14515 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14519 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14526 * 3-stack pin configuration:
14527 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14529 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14531 * Set pin mode and muting
14533 /* set front pin widgets 0x14 for output */
14534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14536 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14538 /* Mic (rear) pin: input vref at 80% */
14539 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14540 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14541 /* Front Mic pin: input vref at 80% */
14542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14543 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14544 /* Line In pin: input */
14545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14546 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14547 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14549 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14550 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14551 /* CD pin widget for input */
14552 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14558 * 6-stack pin configuration:
14560 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14562 * Set pin mode and muting
14564 /* set front pin widgets 0x14 for output */
14565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14566 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14567 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14569 /* Rear Pin: output 1 (0x0d) */
14570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14572 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14573 /* CLFE Pin: output 2 (0x0e) */
14574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14576 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14577 /* Side Pin: output 3 (0x0f) */
14578 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14579 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14580 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14582 /* Mic (rear) pin: input vref at 80% */
14583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14585 /* Front Mic pin: input vref at 80% */
14586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14588 /* Line In pin: input */
14589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14591 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14592 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14593 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14594 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14595 /* CD pin widget for input */
14596 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14601 static struct hda_verb alc861vd_eapd_verbs[] = {
14602 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14606 static struct hda_verb alc660vd_eapd_verbs[] = {
14607 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14608 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14612 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14615 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14616 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14617 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14621 /* toggle speaker-output according to the hp-jack state */
14622 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14624 unsigned int present;
14625 unsigned char bits;
14627 present = snd_hda_codec_read(codec, 0x1b, 0,
14628 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14629 bits = present ? HDA_AMP_MUTE : 0;
14630 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14631 HDA_AMP_MUTE, bits);
14634 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14636 unsigned int present;
14637 unsigned char bits;
14639 present = snd_hda_codec_read(codec, 0x18, 0,
14640 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14641 bits = present ? HDA_AMP_MUTE : 0;
14642 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14643 HDA_AMP_MUTE, bits);
14646 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14648 alc861vd_lenovo_hp_automute(codec);
14649 alc861vd_lenovo_mic_automute(codec);
14652 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14655 switch (res >> 26) {
14656 case ALC880_HP_EVENT:
14657 alc861vd_lenovo_hp_automute(codec);
14659 case ALC880_MIC_EVENT:
14660 alc861vd_lenovo_mic_automute(codec);
14665 static struct hda_verb alc861vd_dallas_verbs[] = {
14666 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14667 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14668 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14669 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14673 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14674 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14675 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14676 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14677 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14678 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14680 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14681 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14684 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14685 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14686 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14687 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14691 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14692 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14694 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14695 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14696 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14701 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14703 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14704 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14710 /* toggle speaker-output according to the hp-jack state */
14711 static void alc861vd_dallas_automute(struct hda_codec *codec)
14713 unsigned int present;
14715 present = snd_hda_codec_read(codec, 0x15, 0,
14716 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14717 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14718 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14721 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14723 if ((res >> 26) == ALC880_HP_EVENT)
14724 alc861vd_dallas_automute(codec);
14727 #ifdef CONFIG_SND_HDA_POWER_SAVE
14728 #define alc861vd_loopbacks alc880_loopbacks
14731 /* pcm configuration: identiacal with ALC880 */
14732 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14733 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14734 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14735 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14738 * configuration and preset
14740 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14741 [ALC660VD_3ST] = "3stack-660",
14742 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14743 [ALC660VD_ASUS_V1S] = "asus-v1s",
14744 [ALC861VD_3ST] = "3stack",
14745 [ALC861VD_3ST_DIG] = "3stack-digout",
14746 [ALC861VD_6ST_DIG] = "6stack-digout",
14747 [ALC861VD_LENOVO] = "lenovo",
14748 [ALC861VD_DALLAS] = "dallas",
14749 [ALC861VD_HP] = "hp",
14750 [ALC861VD_AUTO] = "auto",
14753 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14754 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14755 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14756 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14757 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14758 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14759 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14760 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14761 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14762 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14763 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14764 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14765 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14766 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14767 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
14768 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14772 static struct alc_config_preset alc861vd_presets[] = {
14774 .mixers = { alc861vd_3st_mixer },
14775 .init_verbs = { alc861vd_volume_init_verbs,
14776 alc861vd_3stack_init_verbs },
14777 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14778 .dac_nids = alc660vd_dac_nids,
14779 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14780 .channel_mode = alc861vd_3stack_2ch_modes,
14781 .input_mux = &alc861vd_capture_source,
14783 [ALC660VD_3ST_DIG] = {
14784 .mixers = { alc861vd_3st_mixer },
14785 .init_verbs = { alc861vd_volume_init_verbs,
14786 alc861vd_3stack_init_verbs },
14787 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14788 .dac_nids = alc660vd_dac_nids,
14789 .dig_out_nid = ALC861VD_DIGOUT_NID,
14790 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14791 .channel_mode = alc861vd_3stack_2ch_modes,
14792 .input_mux = &alc861vd_capture_source,
14795 .mixers = { alc861vd_3st_mixer },
14796 .init_verbs = { alc861vd_volume_init_verbs,
14797 alc861vd_3stack_init_verbs },
14798 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14799 .dac_nids = alc861vd_dac_nids,
14800 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14801 .channel_mode = alc861vd_3stack_2ch_modes,
14802 .input_mux = &alc861vd_capture_source,
14804 [ALC861VD_3ST_DIG] = {
14805 .mixers = { alc861vd_3st_mixer },
14806 .init_verbs = { alc861vd_volume_init_verbs,
14807 alc861vd_3stack_init_verbs },
14808 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14809 .dac_nids = alc861vd_dac_nids,
14810 .dig_out_nid = ALC861VD_DIGOUT_NID,
14811 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14812 .channel_mode = alc861vd_3stack_2ch_modes,
14813 .input_mux = &alc861vd_capture_source,
14815 [ALC861VD_6ST_DIG] = {
14816 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14817 .init_verbs = { alc861vd_volume_init_verbs,
14818 alc861vd_6stack_init_verbs },
14819 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14820 .dac_nids = alc861vd_dac_nids,
14821 .dig_out_nid = ALC861VD_DIGOUT_NID,
14822 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14823 .channel_mode = alc861vd_6stack_modes,
14824 .input_mux = &alc861vd_capture_source,
14826 [ALC861VD_LENOVO] = {
14827 .mixers = { alc861vd_lenovo_mixer },
14828 .init_verbs = { alc861vd_volume_init_verbs,
14829 alc861vd_3stack_init_verbs,
14830 alc861vd_eapd_verbs,
14831 alc861vd_lenovo_unsol_verbs },
14832 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14833 .dac_nids = alc660vd_dac_nids,
14834 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14835 .channel_mode = alc861vd_3stack_2ch_modes,
14836 .input_mux = &alc861vd_capture_source,
14837 .unsol_event = alc861vd_lenovo_unsol_event,
14838 .init_hook = alc861vd_lenovo_automute,
14840 [ALC861VD_DALLAS] = {
14841 .mixers = { alc861vd_dallas_mixer },
14842 .init_verbs = { alc861vd_dallas_verbs },
14843 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14844 .dac_nids = alc861vd_dac_nids,
14845 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14846 .channel_mode = alc861vd_3stack_2ch_modes,
14847 .input_mux = &alc861vd_dallas_capture_source,
14848 .unsol_event = alc861vd_dallas_unsol_event,
14849 .init_hook = alc861vd_dallas_automute,
14852 .mixers = { alc861vd_hp_mixer },
14853 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14854 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14855 .dac_nids = alc861vd_dac_nids,
14856 .dig_out_nid = ALC861VD_DIGOUT_NID,
14857 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14858 .channel_mode = alc861vd_3stack_2ch_modes,
14859 .input_mux = &alc861vd_hp_capture_source,
14860 .unsol_event = alc861vd_dallas_unsol_event,
14861 .init_hook = alc861vd_dallas_automute,
14863 [ALC660VD_ASUS_V1S] = {
14864 .mixers = { alc861vd_lenovo_mixer },
14865 .init_verbs = { alc861vd_volume_init_verbs,
14866 alc861vd_3stack_init_verbs,
14867 alc861vd_eapd_verbs,
14868 alc861vd_lenovo_unsol_verbs },
14869 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14870 .dac_nids = alc660vd_dac_nids,
14871 .dig_out_nid = ALC861VD_DIGOUT_NID,
14872 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14873 .channel_mode = alc861vd_3stack_2ch_modes,
14874 .input_mux = &alc861vd_capture_source,
14875 .unsol_event = alc861vd_lenovo_unsol_event,
14876 .init_hook = alc861vd_lenovo_automute,
14881 * BIOS auto configuration
14883 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14884 hda_nid_t nid, int pin_type, int dac_idx)
14886 alc_set_pin_output(codec, nid, pin_type);
14889 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14891 struct alc_spec *spec = codec->spec;
14894 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14895 for (i = 0; i <= HDA_SIDE; i++) {
14896 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14897 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14899 alc861vd_auto_set_output_and_unmute(codec, nid,
14905 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14907 struct alc_spec *spec = codec->spec;
14910 pin = spec->autocfg.hp_pins[0];
14911 if (pin) /* connect to front and use dac 0 */
14912 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14913 pin = spec->autocfg.speaker_pins[0];
14915 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14918 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14919 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14921 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14923 struct alc_spec *spec = codec->spec;
14926 for (i = 0; i < AUTO_PIN_LAST; i++) {
14927 hda_nid_t nid = spec->autocfg.input_pins[i];
14928 if (alc861vd_is_input_pin(nid)) {
14929 alc_set_input_pin(codec, nid, i);
14930 if (nid != ALC861VD_PIN_CD_NID &&
14931 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
14932 snd_hda_codec_write(codec, nid, 0,
14933 AC_VERB_SET_AMP_GAIN_MUTE,
14939 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14941 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14942 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14944 /* add playback controls from the parsed DAC table */
14945 /* Based on ALC880 version. But ALC861VD has separate,
14946 * different NIDs for mute/unmute switch and volume control */
14947 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14948 const struct auto_pin_cfg *cfg)
14951 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14952 hda_nid_t nid_v, nid_s;
14955 for (i = 0; i < cfg->line_outs; i++) {
14956 if (!spec->multiout.dac_nids[i])
14958 nid_v = alc861vd_idx_to_mixer_vol(
14960 spec->multiout.dac_nids[i]));
14961 nid_s = alc861vd_idx_to_mixer_switch(
14963 spec->multiout.dac_nids[i]));
14967 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14968 "Center Playback Volume",
14969 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14973 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14974 "LFE Playback Volume",
14975 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14979 err = add_control(spec, ALC_CTL_BIND_MUTE,
14980 "Center Playback Switch",
14981 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14985 err = add_control(spec, ALC_CTL_BIND_MUTE,
14986 "LFE Playback Switch",
14987 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14992 sprintf(name, "%s Playback Volume", chname[i]);
14993 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14994 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14998 sprintf(name, "%s Playback Switch", chname[i]);
14999 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15000 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15009 /* add playback controls for speaker and HP outputs */
15010 /* Based on ALC880 version. But ALC861VD has separate,
15011 * different NIDs for mute/unmute switch and volume control */
15012 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15013 hda_nid_t pin, const char *pfx)
15015 hda_nid_t nid_v, nid_s;
15022 if (alc880_is_fixed_pin(pin)) {
15023 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15024 /* specify the DAC as the extra output */
15025 if (!spec->multiout.hp_nid)
15026 spec->multiout.hp_nid = nid_v;
15028 spec->multiout.extra_out_nid[0] = nid_v;
15029 /* control HP volume/switch on the output mixer amp */
15030 nid_v = alc861vd_idx_to_mixer_vol(
15031 alc880_fixed_pin_idx(pin));
15032 nid_s = alc861vd_idx_to_mixer_switch(
15033 alc880_fixed_pin_idx(pin));
15035 sprintf(name, "%s Playback Volume", pfx);
15036 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15037 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15040 sprintf(name, "%s Playback Switch", pfx);
15041 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15042 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15045 } else if (alc880_is_multi_pin(pin)) {
15046 /* set manual connection */
15047 /* we have only a switch on HP-out PIN */
15048 sprintf(name, "%s Playback Switch", pfx);
15049 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15050 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15057 /* parse the BIOS configuration and set up the alc_spec
15058 * return 1 if successful, 0 if the proper config is not found,
15059 * or a negative error code
15060 * Based on ALC880 version - had to change it to override
15061 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15062 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15064 struct alc_spec *spec = codec->spec;
15066 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15068 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15072 if (!spec->autocfg.line_outs)
15073 return 0; /* can't find valid BIOS pin config */
15075 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15078 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15081 err = alc861vd_auto_create_extra_out(spec,
15082 spec->autocfg.speaker_pins[0],
15086 err = alc861vd_auto_create_extra_out(spec,
15087 spec->autocfg.hp_pins[0],
15091 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15095 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15097 if (spec->autocfg.dig_outs)
15098 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15100 if (spec->kctls.list)
15101 add_mixer(spec, spec->kctls.list);
15103 add_verb(spec, alc861vd_volume_init_verbs);
15105 spec->num_mux_defs = 1;
15106 spec->input_mux = &spec->private_imux[0];
15108 err = alc_auto_add_mic_boost(codec);
15115 /* additional initialization for auto-configuration model */
15116 static void alc861vd_auto_init(struct hda_codec *codec)
15118 struct alc_spec *spec = codec->spec;
15119 alc861vd_auto_init_multi_out(codec);
15120 alc861vd_auto_init_hp_out(codec);
15121 alc861vd_auto_init_analog_input(codec);
15122 alc861vd_auto_init_input_src(codec);
15123 if (spec->unsol_event)
15124 alc_inithook(codec);
15127 static int patch_alc861vd(struct hda_codec *codec)
15129 struct alc_spec *spec;
15130 int err, board_config;
15132 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15136 codec->spec = spec;
15138 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15142 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15143 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
15144 "ALC861VD, trying auto-probe from BIOS...\n");
15145 board_config = ALC861VD_AUTO;
15148 if (board_config == ALC861VD_AUTO) {
15149 /* automatic parse from the BIOS config */
15150 err = alc861vd_parse_auto_config(codec);
15156 "hda_codec: Cannot set up configuration "
15157 "from BIOS. Using base mode...\n");
15158 board_config = ALC861VD_3ST;
15162 err = snd_hda_attach_beep_device(codec, 0x23);
15168 if (board_config != ALC861VD_AUTO)
15169 setup_preset(spec, &alc861vd_presets[board_config]);
15171 if (codec->vendor_id == 0x10ec0660) {
15172 spec->stream_name_analog = "ALC660-VD Analog";
15173 spec->stream_name_digital = "ALC660-VD Digital";
15174 /* always turn on EAPD */
15175 add_verb(spec, alc660vd_eapd_verbs);
15177 spec->stream_name_analog = "ALC861VD Analog";
15178 spec->stream_name_digital = "ALC861VD Digital";
15181 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15182 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15184 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15185 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15187 spec->adc_nids = alc861vd_adc_nids;
15188 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15189 spec->capsrc_nids = alc861vd_capsrc_nids;
15190 spec->capture_style = CAPT_MIX;
15192 set_capture_mixer(spec);
15193 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15195 spec->vmaster_nid = 0x02;
15197 codec->patch_ops = alc_patch_ops;
15199 if (board_config == ALC861VD_AUTO)
15200 spec->init_hook = alc861vd_auto_init;
15201 #ifdef CONFIG_SND_HDA_POWER_SAVE
15202 if (!spec->loopback.amplist)
15203 spec->loopback.amplist = alc861vd_loopbacks;
15205 codec->proc_widget_hook = print_realtek_coef;
15213 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15214 * configuration. Each pin widget can choose any input DACs and a mixer.
15215 * Each ADC is connected from a mixer of all inputs. This makes possible
15216 * 6-channel independent captures.
15218 * In addition, an independent DAC for the multi-playback (not used in this
15221 #define ALC662_DIGOUT_NID 0x06
15222 #define ALC662_DIGIN_NID 0x0a
15224 static hda_nid_t alc662_dac_nids[4] = {
15225 /* front, rear, clfe, rear_surr */
15229 static hda_nid_t alc272_dac_nids[2] = {
15233 static hda_nid_t alc662_adc_nids[1] = {
15238 static hda_nid_t alc272_adc_nids[1] = {
15243 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15244 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15248 /* FIXME: should be a matrix-type input source selection */
15249 static struct hda_input_mux alc662_capture_source = {
15253 { "Front Mic", 0x1 },
15259 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15267 static struct hda_input_mux alc662_eeepc_capture_source = {
15275 static struct hda_input_mux alc663_capture_source = {
15279 { "Front Mic", 0x1 },
15284 static struct hda_input_mux alc663_m51va_capture_source = {
15287 { "Ext-Mic", 0x0 },
15295 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15302 static struct hda_verb alc662_3ST_ch2_init[] = {
15303 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15304 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15305 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15306 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15313 static struct hda_verb alc662_3ST_ch6_init[] = {
15314 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15315 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15316 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15317 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15318 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15319 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15323 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15324 { 2, alc662_3ST_ch2_init },
15325 { 6, alc662_3ST_ch6_init },
15331 static struct hda_verb alc662_sixstack_ch6_init[] = {
15332 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15333 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15334 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15341 static struct hda_verb alc662_sixstack_ch8_init[] = {
15342 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15343 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15344 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15348 static struct hda_channel_mode alc662_5stack_modes[2] = {
15349 { 2, alc662_sixstack_ch6_init },
15350 { 6, alc662_sixstack_ch8_init },
15353 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15354 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15357 static struct snd_kcontrol_new alc662_base_mixer[] = {
15358 /* output mixer control */
15359 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15360 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15361 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15362 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15363 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15364 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15365 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15366 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15369 /*Input mixer control */
15370 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15371 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15372 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15373 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15374 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15375 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15376 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15377 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15381 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15382 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15383 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15390 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15391 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15392 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15396 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15397 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15398 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15400 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15401 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15402 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15403 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15404 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15405 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15406 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15407 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15408 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15409 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15412 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15413 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15417 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15418 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15419 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15420 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15421 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15430 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15431 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15433 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15434 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15436 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15437 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15438 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15440 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15441 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15442 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15446 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15447 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15449 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15450 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
15451 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15453 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
15454 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
15455 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15456 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15464 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15465 .ops = &snd_hda_bind_vol,
15467 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15468 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15473 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15474 .ops = &snd_hda_bind_sw,
15476 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15477 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15482 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15483 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15484 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15490 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15491 .ops = &snd_hda_bind_sw,
15493 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15494 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15495 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15500 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15501 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15502 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15505 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15506 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15511 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15512 .ops = &snd_hda_bind_sw,
15514 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15515 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15516 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15521 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15522 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15523 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15525 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15526 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15527 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15531 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15532 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15533 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15537 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15538 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15542 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15543 .ops = &snd_hda_bind_vol,
15545 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15546 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15551 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15552 .ops = &snd_hda_bind_sw,
15554 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15555 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15560 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15561 HDA_BIND_VOL("Master Playback Volume",
15562 &alc663_asus_two_bind_master_vol),
15563 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15564 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15571 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15572 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15573 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15581 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15583 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15584 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15585 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15586 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15590 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15591 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15595 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15596 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15597 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15602 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15603 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15604 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15605 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15609 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15612 .name = "Channel Mode",
15613 .info = alc_ch_mode_info,
15614 .get = alc_ch_mode_get,
15615 .put = alc_ch_mode_put,
15620 static struct hda_verb alc662_init_verbs[] = {
15621 /* ADC: mute amp left and right */
15622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15623 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15624 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15626 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15627 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15636 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 /* Front Pin: output 0 (0x0c) */
15640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15643 /* Rear Pin: output 1 (0x0d) */
15644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15647 /* CLFE Pin: output 2 (0x0e) */
15648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15651 /* Mic (rear) pin: input vref at 80% */
15652 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15653 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15654 /* Front Mic pin: input vref at 80% */
15655 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15657 /* Line In pin: input */
15658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15660 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15661 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15662 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15663 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15664 /* CD pin widget for input */
15665 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15667 /* FIXME: use matrix-type input source selection */
15668 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15673 /* always trun on EAPD */
15674 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15675 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15680 static struct hda_verb alc662_sue_init_verbs[] = {
15681 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15682 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15686 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15687 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15688 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15692 /* Set Unsolicited Event*/
15693 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15694 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15695 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15700 * generic initialization of ADC, input mixers and output mixers
15702 static struct hda_verb alc662_auto_init_verbs[] = {
15704 * Unmute ADC and set the default input to mic-in
15706 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15711 * Note: PASD motherboards uses the Line In 2 as the input for front
15712 * panel mic (mic 2)
15714 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15717 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15722 * Set up output mixers (0x0c - 0x0f)
15724 /* set vol=0 to output mixers */
15725 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15726 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15729 /* set up input amps for analog loopback */
15730 /* Amp Indices: DAC = 0, mixer = 1 */
15731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15734 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15736 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15739 /* FIXME: use matrix-type input source selection */
15740 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15742 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15743 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 /* additional verbs for ALC663 */
15748 static struct hda_verb alc663_auto_init_verbs[] = {
15749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15754 static struct hda_verb alc663_m51va_init_verbs[] = {
15755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15756 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15757 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15758 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15759 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15762 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15763 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15767 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15768 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15769 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15770 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15773 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15774 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15778 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15779 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15780 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15781 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15782 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15783 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15784 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15785 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15786 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15790 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15791 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15792 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15795 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15797 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15801 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15803 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15804 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15805 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15807 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15808 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15812 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15813 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15817 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15820 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15821 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15827 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15828 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15833 static struct hda_verb alc663_g71v_init_verbs[] = {
15834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15835 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15836 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15838 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15839 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15840 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15842 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15843 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15844 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15848 static struct hda_verb alc663_g50v_init_verbs[] = {
15849 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15850 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15851 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15853 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15854 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15858 static struct hda_verb alc662_ecs_init_verbs[] = {
15859 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15861 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15862 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15866 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
15867 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15868 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15869 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15870 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15871 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15872 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15873 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15876 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15877 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15881 static struct hda_verb alc272_dell_init_verbs[] = {
15882 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15883 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15885 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15886 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15887 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15888 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15891 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15892 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15896 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15897 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15898 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15902 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
15903 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
15904 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
15908 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15910 unsigned int present;
15911 unsigned char bits;
15913 present = snd_hda_codec_read(codec, 0x14, 0,
15914 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15915 bits = present ? HDA_AMP_MUTE : 0;
15916 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15917 HDA_AMP_MUTE, bits);
15920 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15922 unsigned int present;
15923 unsigned char bits;
15925 present = snd_hda_codec_read(codec, 0x1b, 0,
15926 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15927 bits = present ? HDA_AMP_MUTE : 0;
15928 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15929 HDA_AMP_MUTE, bits);
15930 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15931 HDA_AMP_MUTE, bits);
15934 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15937 if ((res >> 26) == ALC880_HP_EVENT)
15938 alc662_lenovo_101e_all_automute(codec);
15939 if ((res >> 26) == ALC880_FRONT_EVENT)
15940 alc662_lenovo_101e_ispeaker_automute(codec);
15943 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15945 unsigned int present;
15947 present = snd_hda_codec_read(codec, 0x18, 0,
15948 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15949 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15950 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15951 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15952 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15953 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15954 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15955 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15956 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15959 /* unsolicited event for HP jack sensing */
15960 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15963 if ((res >> 26) == ALC880_HP_EVENT)
15964 alc262_hippo1_automute( codec );
15966 if ((res >> 26) == ALC880_MIC_EVENT)
15967 alc662_eeepc_mic_automute(codec);
15970 static void alc662_eeepc_inithook(struct hda_codec *codec)
15972 alc262_hippo1_automute( codec );
15973 alc662_eeepc_mic_automute(codec);
15976 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15979 unsigned int present;
15981 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15982 present = snd_hda_codec_read(codec, 0x14, 0,
15983 AC_VERB_GET_PIN_SENSE, 0);
15984 present = (present & 0x80000000) != 0;
15986 /* mute internal speaker */
15987 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15988 HDA_AMP_MUTE, HDA_AMP_MUTE);
15990 /* unmute internal speaker if necessary */
15991 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15992 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15993 HDA_AMP_MUTE, mute);
15997 /* unsolicited event for HP jack sensing */
15998 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
16001 if ((res >> 26) == ALC880_HP_EVENT)
16002 alc662_eeepc_ep20_automute(codec);
16005 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16007 alc662_eeepc_ep20_automute(codec);
16010 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16012 unsigned int present;
16013 unsigned char bits;
16015 present = snd_hda_codec_read(codec, 0x21, 0,
16016 AC_VERB_GET_PIN_SENSE, 0)
16017 & AC_PINSENSE_PRESENCE;
16018 bits = present ? HDA_AMP_MUTE : 0;
16019 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16020 AMP_IN_MUTE(0), bits);
16021 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16022 AMP_IN_MUTE(0), bits);
16025 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16027 unsigned int present;
16028 unsigned char bits;
16030 present = snd_hda_codec_read(codec, 0x21, 0,
16031 AC_VERB_GET_PIN_SENSE, 0)
16032 & AC_PINSENSE_PRESENCE;
16033 bits = present ? HDA_AMP_MUTE : 0;
16034 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16035 AMP_IN_MUTE(0), bits);
16036 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16037 AMP_IN_MUTE(0), bits);
16038 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16039 AMP_IN_MUTE(0), bits);
16040 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16041 AMP_IN_MUTE(0), bits);
16044 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16046 unsigned int present;
16047 unsigned char bits;
16049 present = snd_hda_codec_read(codec, 0x15, 0,
16050 AC_VERB_GET_PIN_SENSE, 0)
16051 & AC_PINSENSE_PRESENCE;
16052 bits = present ? HDA_AMP_MUTE : 0;
16053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16054 AMP_IN_MUTE(0), bits);
16055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16056 AMP_IN_MUTE(0), bits);
16057 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16058 AMP_IN_MUTE(0), bits);
16059 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16060 AMP_IN_MUTE(0), bits);
16063 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16065 unsigned int present;
16066 unsigned char bits;
16068 present = snd_hda_codec_read(codec, 0x1b, 0,
16069 AC_VERB_GET_PIN_SENSE, 0)
16070 & AC_PINSENSE_PRESENCE;
16071 bits = present ? 0 : PIN_OUT;
16072 snd_hda_codec_write(codec, 0x14, 0,
16073 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16076 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16078 unsigned int present1, present2;
16080 present1 = snd_hda_codec_read(codec, 0x21, 0,
16081 AC_VERB_GET_PIN_SENSE, 0)
16082 & AC_PINSENSE_PRESENCE;
16083 present2 = snd_hda_codec_read(codec, 0x15, 0,
16084 AC_VERB_GET_PIN_SENSE, 0)
16085 & AC_PINSENSE_PRESENCE;
16087 if (present1 || present2) {
16088 snd_hda_codec_write_cache(codec, 0x14, 0,
16089 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16091 snd_hda_codec_write_cache(codec, 0x14, 0,
16092 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16096 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16098 unsigned int present1, present2;
16100 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16101 AC_VERB_GET_PIN_SENSE, 0)
16102 & AC_PINSENSE_PRESENCE;
16103 present2 = snd_hda_codec_read(codec, 0x15, 0,
16104 AC_VERB_GET_PIN_SENSE, 0)
16105 & AC_PINSENSE_PRESENCE;
16107 if (present1 || present2) {
16108 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16109 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16110 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16111 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16113 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16114 AMP_IN_MUTE(0), 0);
16115 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16116 AMP_IN_MUTE(0), 0);
16120 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16122 unsigned int present;
16124 present = snd_hda_codec_read(codec, 0x18, 0,
16125 AC_VERB_GET_PIN_SENSE, 0)
16126 & AC_PINSENSE_PRESENCE;
16127 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16128 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16129 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16130 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16131 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16132 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16133 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16134 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16137 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16140 switch (res >> 26) {
16141 case ALC880_HP_EVENT:
16142 alc663_m51va_speaker_automute(codec);
16144 case ALC880_MIC_EVENT:
16145 alc663_m51va_mic_automute(codec);
16150 static void alc663_m51va_inithook(struct hda_codec *codec)
16152 alc663_m51va_speaker_automute(codec);
16153 alc663_m51va_mic_automute(codec);
16156 /* ***************** Mode1 ******************************/
16157 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16160 switch (res >> 26) {
16161 case ALC880_HP_EVENT:
16162 alc663_m51va_speaker_automute(codec);
16164 case ALC880_MIC_EVENT:
16165 alc662_eeepc_mic_automute(codec);
16170 static void alc663_mode1_inithook(struct hda_codec *codec)
16172 alc663_m51va_speaker_automute(codec);
16173 alc662_eeepc_mic_automute(codec);
16175 /* ***************** Mode2 ******************************/
16176 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16179 switch (res >> 26) {
16180 case ALC880_HP_EVENT:
16181 alc662_f5z_speaker_automute(codec);
16183 case ALC880_MIC_EVENT:
16184 alc662_eeepc_mic_automute(codec);
16189 static void alc662_mode2_inithook(struct hda_codec *codec)
16191 alc662_f5z_speaker_automute(codec);
16192 alc662_eeepc_mic_automute(codec);
16194 /* ***************** Mode3 ******************************/
16195 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16198 switch (res >> 26) {
16199 case ALC880_HP_EVENT:
16200 alc663_two_hp_m1_speaker_automute(codec);
16202 case ALC880_MIC_EVENT:
16203 alc662_eeepc_mic_automute(codec);
16208 static void alc663_mode3_inithook(struct hda_codec *codec)
16210 alc663_two_hp_m1_speaker_automute(codec);
16211 alc662_eeepc_mic_automute(codec);
16213 /* ***************** Mode4 ******************************/
16214 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16217 switch (res >> 26) {
16218 case ALC880_HP_EVENT:
16219 alc663_21jd_two_speaker_automute(codec);
16221 case ALC880_MIC_EVENT:
16222 alc662_eeepc_mic_automute(codec);
16227 static void alc663_mode4_inithook(struct hda_codec *codec)
16229 alc663_21jd_two_speaker_automute(codec);
16230 alc662_eeepc_mic_automute(codec);
16232 /* ***************** Mode5 ******************************/
16233 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16236 switch (res >> 26) {
16237 case ALC880_HP_EVENT:
16238 alc663_15jd_two_speaker_automute(codec);
16240 case ALC880_MIC_EVENT:
16241 alc662_eeepc_mic_automute(codec);
16246 static void alc663_mode5_inithook(struct hda_codec *codec)
16248 alc663_15jd_two_speaker_automute(codec);
16249 alc662_eeepc_mic_automute(codec);
16251 /* ***************** Mode6 ******************************/
16252 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16255 switch (res >> 26) {
16256 case ALC880_HP_EVENT:
16257 alc663_two_hp_m2_speaker_automute(codec);
16259 case ALC880_MIC_EVENT:
16260 alc662_eeepc_mic_automute(codec);
16265 static void alc663_mode6_inithook(struct hda_codec *codec)
16267 alc663_two_hp_m2_speaker_automute(codec);
16268 alc662_eeepc_mic_automute(codec);
16271 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16273 unsigned int present;
16274 unsigned char bits;
16276 present = snd_hda_codec_read(codec, 0x21, 0,
16277 AC_VERB_GET_PIN_SENSE, 0)
16278 & AC_PINSENSE_PRESENCE;
16279 bits = present ? HDA_AMP_MUTE : 0;
16280 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16281 HDA_AMP_MUTE, bits);
16282 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16283 HDA_AMP_MUTE, bits);
16286 static void alc663_g71v_front_automute(struct hda_codec *codec)
16288 unsigned int present;
16289 unsigned char bits;
16291 present = snd_hda_codec_read(codec, 0x15, 0,
16292 AC_VERB_GET_PIN_SENSE, 0)
16293 & AC_PINSENSE_PRESENCE;
16294 bits = present ? HDA_AMP_MUTE : 0;
16295 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16296 HDA_AMP_MUTE, bits);
16299 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16302 switch (res >> 26) {
16303 case ALC880_HP_EVENT:
16304 alc663_g71v_hp_automute(codec);
16306 case ALC880_FRONT_EVENT:
16307 alc663_g71v_front_automute(codec);
16309 case ALC880_MIC_EVENT:
16310 alc662_eeepc_mic_automute(codec);
16315 static void alc663_g71v_inithook(struct hda_codec *codec)
16317 alc663_g71v_front_automute(codec);
16318 alc663_g71v_hp_automute(codec);
16319 alc662_eeepc_mic_automute(codec);
16322 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16325 switch (res >> 26) {
16326 case ALC880_HP_EVENT:
16327 alc663_m51va_speaker_automute(codec);
16329 case ALC880_MIC_EVENT:
16330 alc662_eeepc_mic_automute(codec);
16335 static void alc663_g50v_inithook(struct hda_codec *codec)
16337 alc663_m51va_speaker_automute(codec);
16338 alc662_eeepc_mic_automute(codec);
16341 /* bind hp and internal speaker mute (with plug check) */
16342 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
16343 struct snd_ctl_elem_value *ucontrol)
16345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
16346 long *valp = ucontrol->value.integer.value;
16349 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
16351 valp[0] ? 0 : HDA_AMP_MUTE);
16352 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
16354 valp[1] ? 0 : HDA_AMP_MUTE);
16356 alc262_hippo1_automute(codec);
16360 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16361 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16363 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16364 .name = "Master Playback Switch",
16365 .info = snd_hda_mixer_amp_switch_info,
16366 .get = snd_hda_mixer_amp_switch_get,
16367 .put = alc662_ecs_master_sw_put,
16368 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16371 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16372 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16373 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16375 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16376 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16377 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16381 #ifdef CONFIG_SND_HDA_POWER_SAVE
16382 #define alc662_loopbacks alc880_loopbacks
16386 /* pcm configuration: identiacal with ALC880 */
16387 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16388 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16389 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16390 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16393 * configuration and preset
16395 static const char *alc662_models[ALC662_MODEL_LAST] = {
16396 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16397 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16398 [ALC662_3ST_6ch] = "3stack-6ch",
16399 [ALC662_5ST_DIG] = "6stack-dig",
16400 [ALC662_LENOVO_101E] = "lenovo-101e",
16401 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16402 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16403 [ALC662_ECS] = "ecs",
16404 [ALC663_ASUS_M51VA] = "m51va",
16405 [ALC663_ASUS_G71V] = "g71v",
16406 [ALC663_ASUS_H13] = "h13",
16407 [ALC663_ASUS_G50V] = "g50v",
16408 [ALC663_ASUS_MODE1] = "asus-mode1",
16409 [ALC662_ASUS_MODE2] = "asus-mode2",
16410 [ALC663_ASUS_MODE3] = "asus-mode3",
16411 [ALC663_ASUS_MODE4] = "asus-mode4",
16412 [ALC663_ASUS_MODE5] = "asus-mode5",
16413 [ALC663_ASUS_MODE6] = "asus-mode6",
16414 [ALC662_AUTO] = "auto",
16417 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16418 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16419 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16420 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16421 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16422 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16423 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16424 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16425 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16426 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16427 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16428 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16429 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16430 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16431 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16432 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16433 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16434 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16435 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16436 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16437 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16438 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16439 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16440 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16441 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16442 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16443 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16444 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16445 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16446 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16447 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16448 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16449 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16450 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16451 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16452 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16453 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16454 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16455 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16456 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16457 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16458 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16459 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16460 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16461 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16462 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16463 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16464 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16465 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16466 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16467 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16468 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16469 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16470 ALC662_3ST_6ch_DIG),
16471 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16472 ALC662_3ST_6ch_DIG),
16473 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16474 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16475 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16476 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16477 ALC662_3ST_6ch_DIG),
16478 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16483 static struct alc_config_preset alc662_presets[] = {
16484 [ALC662_3ST_2ch_DIG] = {
16485 .mixers = { alc662_3ST_2ch_mixer },
16486 .init_verbs = { alc662_init_verbs },
16487 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16488 .dac_nids = alc662_dac_nids,
16489 .dig_out_nid = ALC662_DIGOUT_NID,
16490 .dig_in_nid = ALC662_DIGIN_NID,
16491 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16492 .channel_mode = alc662_3ST_2ch_modes,
16493 .input_mux = &alc662_capture_source,
16495 [ALC662_3ST_6ch_DIG] = {
16496 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16497 .init_verbs = { alc662_init_verbs },
16498 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16499 .dac_nids = alc662_dac_nids,
16500 .dig_out_nid = ALC662_DIGOUT_NID,
16501 .dig_in_nid = ALC662_DIGIN_NID,
16502 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16503 .channel_mode = alc662_3ST_6ch_modes,
16505 .input_mux = &alc662_capture_source,
16507 [ALC662_3ST_6ch] = {
16508 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16509 .init_verbs = { alc662_init_verbs },
16510 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16511 .dac_nids = alc662_dac_nids,
16512 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16513 .channel_mode = alc662_3ST_6ch_modes,
16515 .input_mux = &alc662_capture_source,
16517 [ALC662_5ST_DIG] = {
16518 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16519 .init_verbs = { alc662_init_verbs },
16520 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16521 .dac_nids = alc662_dac_nids,
16522 .dig_out_nid = ALC662_DIGOUT_NID,
16523 .dig_in_nid = ALC662_DIGIN_NID,
16524 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16525 .channel_mode = alc662_5stack_modes,
16526 .input_mux = &alc662_capture_source,
16528 [ALC662_LENOVO_101E] = {
16529 .mixers = { alc662_lenovo_101e_mixer },
16530 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16531 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16532 .dac_nids = alc662_dac_nids,
16533 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16534 .channel_mode = alc662_3ST_2ch_modes,
16535 .input_mux = &alc662_lenovo_101e_capture_source,
16536 .unsol_event = alc662_lenovo_101e_unsol_event,
16537 .init_hook = alc662_lenovo_101e_all_automute,
16539 [ALC662_ASUS_EEEPC_P701] = {
16540 .mixers = { alc662_eeepc_p701_mixer },
16541 .init_verbs = { alc662_init_verbs,
16542 alc662_eeepc_sue_init_verbs },
16543 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16544 .dac_nids = alc662_dac_nids,
16545 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16546 .channel_mode = alc662_3ST_2ch_modes,
16547 .input_mux = &alc662_eeepc_capture_source,
16548 .unsol_event = alc662_eeepc_unsol_event,
16549 .init_hook = alc662_eeepc_inithook,
16551 [ALC662_ASUS_EEEPC_EP20] = {
16552 .mixers = { alc662_eeepc_ep20_mixer,
16553 alc662_chmode_mixer },
16554 .init_verbs = { alc662_init_verbs,
16555 alc662_eeepc_ep20_sue_init_verbs },
16556 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16557 .dac_nids = alc662_dac_nids,
16558 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16559 .channel_mode = alc662_3ST_6ch_modes,
16560 .input_mux = &alc662_lenovo_101e_capture_source,
16561 .unsol_event = alc662_eeepc_ep20_unsol_event,
16562 .init_hook = alc662_eeepc_ep20_inithook,
16565 .mixers = { alc662_ecs_mixer },
16566 .init_verbs = { alc662_init_verbs,
16567 alc662_ecs_init_verbs },
16568 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16569 .dac_nids = alc662_dac_nids,
16570 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16571 .channel_mode = alc662_3ST_2ch_modes,
16572 .input_mux = &alc662_eeepc_capture_source,
16573 .unsol_event = alc662_eeepc_unsol_event,
16574 .init_hook = alc662_eeepc_inithook,
16576 [ALC663_ASUS_M51VA] = {
16577 .mixers = { alc663_m51va_mixer },
16578 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16579 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16580 .dac_nids = alc662_dac_nids,
16581 .dig_out_nid = ALC662_DIGOUT_NID,
16582 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16583 .channel_mode = alc662_3ST_2ch_modes,
16584 .input_mux = &alc663_m51va_capture_source,
16585 .unsol_event = alc663_m51va_unsol_event,
16586 .init_hook = alc663_m51va_inithook,
16588 [ALC663_ASUS_G71V] = {
16589 .mixers = { alc663_g71v_mixer },
16590 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16591 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16592 .dac_nids = alc662_dac_nids,
16593 .dig_out_nid = ALC662_DIGOUT_NID,
16594 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16595 .channel_mode = alc662_3ST_2ch_modes,
16596 .input_mux = &alc662_eeepc_capture_source,
16597 .unsol_event = alc663_g71v_unsol_event,
16598 .init_hook = alc663_g71v_inithook,
16600 [ALC663_ASUS_H13] = {
16601 .mixers = { alc663_m51va_mixer },
16602 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16603 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16604 .dac_nids = alc662_dac_nids,
16605 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16606 .channel_mode = alc662_3ST_2ch_modes,
16607 .input_mux = &alc663_m51va_capture_source,
16608 .unsol_event = alc663_m51va_unsol_event,
16609 .init_hook = alc663_m51va_inithook,
16611 [ALC663_ASUS_G50V] = {
16612 .mixers = { alc663_g50v_mixer },
16613 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16614 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16615 .dac_nids = alc662_dac_nids,
16616 .dig_out_nid = ALC662_DIGOUT_NID,
16617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16618 .channel_mode = alc662_3ST_6ch_modes,
16619 .input_mux = &alc663_capture_source,
16620 .unsol_event = alc663_g50v_unsol_event,
16621 .init_hook = alc663_g50v_inithook,
16623 [ALC663_ASUS_MODE1] = {
16624 .mixers = { alc663_m51va_mixer },
16625 .cap_mixer = alc662_auto_capture_mixer,
16626 .init_verbs = { alc662_init_verbs,
16627 alc663_21jd_amic_init_verbs },
16628 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16630 .dac_nids = alc662_dac_nids,
16631 .dig_out_nid = ALC662_DIGOUT_NID,
16632 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16633 .channel_mode = alc662_3ST_2ch_modes,
16634 .input_mux = &alc662_eeepc_capture_source,
16635 .unsol_event = alc663_mode1_unsol_event,
16636 .init_hook = alc663_mode1_inithook,
16638 [ALC662_ASUS_MODE2] = {
16639 .mixers = { alc662_1bjd_mixer },
16640 .cap_mixer = alc662_auto_capture_mixer,
16641 .init_verbs = { alc662_init_verbs,
16642 alc662_1bjd_amic_init_verbs },
16643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16644 .dac_nids = alc662_dac_nids,
16645 .dig_out_nid = ALC662_DIGOUT_NID,
16646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16647 .channel_mode = alc662_3ST_2ch_modes,
16648 .input_mux = &alc662_eeepc_capture_source,
16649 .unsol_event = alc662_mode2_unsol_event,
16650 .init_hook = alc662_mode2_inithook,
16652 [ALC663_ASUS_MODE3] = {
16653 .mixers = { alc663_two_hp_m1_mixer },
16654 .cap_mixer = alc662_auto_capture_mixer,
16655 .init_verbs = { alc662_init_verbs,
16656 alc663_two_hp_amic_m1_init_verbs },
16657 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16659 .dac_nids = alc662_dac_nids,
16660 .dig_out_nid = ALC662_DIGOUT_NID,
16661 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16662 .channel_mode = alc662_3ST_2ch_modes,
16663 .input_mux = &alc662_eeepc_capture_source,
16664 .unsol_event = alc663_mode3_unsol_event,
16665 .init_hook = alc663_mode3_inithook,
16667 [ALC663_ASUS_MODE4] = {
16668 .mixers = { alc663_asus_21jd_clfe_mixer },
16669 .cap_mixer = alc662_auto_capture_mixer,
16670 .init_verbs = { alc662_init_verbs,
16671 alc663_21jd_amic_init_verbs},
16672 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16674 .dac_nids = alc662_dac_nids,
16675 .dig_out_nid = ALC662_DIGOUT_NID,
16676 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16677 .channel_mode = alc662_3ST_2ch_modes,
16678 .input_mux = &alc662_eeepc_capture_source,
16679 .unsol_event = alc663_mode4_unsol_event,
16680 .init_hook = alc663_mode4_inithook,
16682 [ALC663_ASUS_MODE5] = {
16683 .mixers = { alc663_asus_15jd_clfe_mixer },
16684 .cap_mixer = alc662_auto_capture_mixer,
16685 .init_verbs = { alc662_init_verbs,
16686 alc663_15jd_amic_init_verbs },
16687 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16689 .dac_nids = alc662_dac_nids,
16690 .dig_out_nid = ALC662_DIGOUT_NID,
16691 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16692 .channel_mode = alc662_3ST_2ch_modes,
16693 .input_mux = &alc662_eeepc_capture_source,
16694 .unsol_event = alc663_mode5_unsol_event,
16695 .init_hook = alc663_mode5_inithook,
16697 [ALC663_ASUS_MODE6] = {
16698 .mixers = { alc663_two_hp_m2_mixer },
16699 .cap_mixer = alc662_auto_capture_mixer,
16700 .init_verbs = { alc662_init_verbs,
16701 alc663_two_hp_amic_m2_init_verbs },
16702 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16704 .dac_nids = alc662_dac_nids,
16705 .dig_out_nid = ALC662_DIGOUT_NID,
16706 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16707 .channel_mode = alc662_3ST_2ch_modes,
16708 .input_mux = &alc662_eeepc_capture_source,
16709 .unsol_event = alc663_mode6_unsol_event,
16710 .init_hook = alc663_mode6_inithook,
16713 .mixers = { alc663_m51va_mixer },
16714 .cap_mixer = alc272_auto_capture_mixer,
16715 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
16716 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16717 .dac_nids = alc662_dac_nids,
16718 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16719 .adc_nids = alc272_adc_nids,
16720 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
16721 .capsrc_nids = alc272_capsrc_nids,
16722 .channel_mode = alc662_3ST_2ch_modes,
16723 .input_mux = &alc663_m51va_capture_source,
16724 .unsol_event = alc663_m51va_unsol_event,
16725 .init_hook = alc663_m51va_inithook,
16727 [ALC272_DELL_ZM1] = {
16728 .mixers = { alc663_m51va_mixer },
16729 .cap_mixer = alc662_auto_capture_mixer,
16730 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
16731 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
16732 .dac_nids = alc662_dac_nids,
16733 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16734 .adc_nids = alc662_adc_nids,
16735 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
16736 .capsrc_nids = alc662_capsrc_nids,
16737 .channel_mode = alc662_3ST_2ch_modes,
16738 .input_mux = &alc663_m51va_capture_source,
16739 .unsol_event = alc663_m51va_unsol_event,
16740 .init_hook = alc663_m51va_inithook,
16746 * BIOS auto configuration
16749 /* add playback controls from the parsed DAC table */
16750 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16751 const struct auto_pin_cfg *cfg)
16754 static const char *chname[4] = {
16755 "Front", "Surround", NULL /*CLFE*/, "Side"
16760 for (i = 0; i < cfg->line_outs; i++) {
16761 if (!spec->multiout.dac_nids[i])
16763 nid = alc880_idx_to_dac(i);
16766 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16767 "Center Playback Volume",
16768 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16772 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16773 "LFE Playback Volume",
16774 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16778 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16779 "Center Playback Switch",
16780 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16784 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16785 "LFE Playback Switch",
16786 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16791 sprintf(name, "%s Playback Volume", chname[i]);
16792 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16793 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16797 sprintf(name, "%s Playback Switch", chname[i]);
16798 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16799 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16808 /* add playback controls for speaker and HP outputs */
16809 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16820 /* ALC663 has a mono output pin on 0x17 */
16821 sprintf(name, "%s Playback Switch", pfx);
16822 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16823 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16827 if (alc880_is_fixed_pin(pin)) {
16828 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16829 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16830 /* specify the DAC as the extra output */
16831 if (!spec->multiout.hp_nid)
16832 spec->multiout.hp_nid = nid;
16834 spec->multiout.extra_out_nid[0] = nid;
16835 /* control HP volume/switch on the output mixer amp */
16836 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16837 sprintf(name, "%s Playback Volume", pfx);
16838 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16839 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16842 sprintf(name, "%s Playback Switch", pfx);
16843 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16844 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16847 } else if (alc880_is_multi_pin(pin)) {
16848 /* set manual connection */
16849 /* we have only a switch on HP-out PIN */
16850 sprintf(name, "%s Playback Switch", pfx);
16851 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16852 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16859 /* return the index of the src widget from the connection list of the nid.
16860 * return -1 if not found
16862 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
16865 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
16868 conns = snd_hda_get_connections(codec, nid, conn_list,
16869 ARRAY_SIZE(conn_list));
16872 for (i = 0; i < conns; i++)
16873 if (conn_list[i] == src)
16878 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
16880 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
16881 return (pincap & AC_PINCAP_IN) != 0;
16884 /* create playback/capture controls for input pins */
16885 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
16886 const struct auto_pin_cfg *cfg)
16888 struct alc_spec *spec = codec->spec;
16889 struct hda_input_mux *imux = &spec->private_imux[0];
16892 for (i = 0; i < AUTO_PIN_LAST; i++) {
16893 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
16894 idx = alc662_input_pin_idx(codec, 0x0b,
16895 cfg->input_pins[i]);
16897 err = new_analog_input(spec, cfg->input_pins[i],
16898 auto_pin_cfg_labels[i],
16903 idx = alc662_input_pin_idx(codec, 0x22,
16904 cfg->input_pins[i]);
16906 imux->items[imux->num_items].label =
16907 auto_pin_cfg_labels[i];
16908 imux->items[imux->num_items].index = idx;
16916 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16917 hda_nid_t nid, int pin_type,
16920 alc_set_pin_output(codec, nid, pin_type);
16921 /* need the manual connection? */
16922 if (alc880_is_multi_pin(nid)) {
16923 struct alc_spec *spec = codec->spec;
16924 int idx = alc880_multi_pin_idx(nid);
16925 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16926 AC_VERB_SET_CONNECT_SEL,
16927 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16931 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16933 struct alc_spec *spec = codec->spec;
16936 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16937 for (i = 0; i <= HDA_SIDE; i++) {
16938 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16939 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16941 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16946 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16948 struct alc_spec *spec = codec->spec;
16951 pin = spec->autocfg.hp_pins[0];
16952 if (pin) /* connect to front */
16954 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16955 pin = spec->autocfg.speaker_pins[0];
16957 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16960 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16962 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16964 struct alc_spec *spec = codec->spec;
16967 for (i = 0; i < AUTO_PIN_LAST; i++) {
16968 hda_nid_t nid = spec->autocfg.input_pins[i];
16969 if (alc662_is_input_pin(codec, nid)) {
16970 alc_set_input_pin(codec, nid, i);
16971 if (nid != ALC662_PIN_CD_NID &&
16972 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16973 snd_hda_codec_write(codec, nid, 0,
16974 AC_VERB_SET_AMP_GAIN_MUTE,
16980 #define alc662_auto_init_input_src alc882_auto_init_input_src
16982 static int alc662_parse_auto_config(struct hda_codec *codec)
16984 struct alc_spec *spec = codec->spec;
16986 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16988 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16992 if (!spec->autocfg.line_outs)
16993 return 0; /* can't find valid BIOS pin config */
16995 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16998 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17001 err = alc662_auto_create_extra_out(spec,
17002 spec->autocfg.speaker_pins[0],
17006 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17010 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17014 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17016 if (spec->autocfg.dig_outs)
17017 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17019 if (spec->kctls.list)
17020 add_mixer(spec, spec->kctls.list);
17022 spec->num_mux_defs = 1;
17023 spec->input_mux = &spec->private_imux[0];
17025 add_verb(spec, alc662_auto_init_verbs);
17026 if (codec->vendor_id == 0x10ec0663)
17027 add_verb(spec, alc663_auto_init_verbs);
17029 err = alc_auto_add_mic_boost(codec);
17036 /* additional initialization for auto-configuration model */
17037 static void alc662_auto_init(struct hda_codec *codec)
17039 struct alc_spec *spec = codec->spec;
17040 alc662_auto_init_multi_out(codec);
17041 alc662_auto_init_hp_out(codec);
17042 alc662_auto_init_analog_input(codec);
17043 alc662_auto_init_input_src(codec);
17044 if (spec->unsol_event)
17045 alc_inithook(codec);
17048 static int patch_alc662(struct hda_codec *codec)
17050 struct alc_spec *spec;
17051 int err, board_config;
17053 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17057 codec->spec = spec;
17059 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17061 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17064 if (board_config < 0) {
17065 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
17066 "trying auto-probe from BIOS...\n");
17067 board_config = ALC662_AUTO;
17070 if (board_config == ALC662_AUTO) {
17071 /* automatic parse from the BIOS config */
17072 err = alc662_parse_auto_config(codec);
17078 "hda_codec: Cannot set up configuration "
17079 "from BIOS. Using base mode...\n");
17080 board_config = ALC662_3ST_2ch_DIG;
17084 err = snd_hda_attach_beep_device(codec, 0x1);
17090 if (board_config != ALC662_AUTO)
17091 setup_preset(spec, &alc662_presets[board_config]);
17093 if (codec->vendor_id == 0x10ec0663) {
17094 spec->stream_name_analog = "ALC663 Analog";
17095 spec->stream_name_digital = "ALC663 Digital";
17096 } else if (codec->vendor_id == 0x10ec0272) {
17097 spec->stream_name_analog = "ALC272 Analog";
17098 spec->stream_name_digital = "ALC272 Digital";
17100 spec->stream_name_analog = "ALC662 Analog";
17101 spec->stream_name_digital = "ALC662 Digital";
17104 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17105 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17107 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17108 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17110 spec->adc_nids = alc662_adc_nids;
17111 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17112 spec->capsrc_nids = alc662_capsrc_nids;
17113 spec->capture_style = CAPT_MIX;
17115 if (!spec->cap_mixer)
17116 set_capture_mixer(spec);
17117 if (codec->vendor_id == 0x10ec0662)
17118 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17120 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17122 spec->vmaster_nid = 0x02;
17124 codec->patch_ops = alc_patch_ops;
17125 if (board_config == ALC662_AUTO)
17126 spec->init_hook = alc662_auto_init;
17127 #ifdef CONFIG_SND_HDA_POWER_SAVE
17128 if (!spec->loopback.amplist)
17129 spec->loopback.amplist = alc662_loopbacks;
17131 codec->proc_widget_hook = print_realtek_coef;
17139 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17140 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17141 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17142 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17143 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17144 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17145 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17146 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17147 .patch = patch_alc861 },
17148 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17149 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17150 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17151 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17152 .patch = patch_alc883 },
17153 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17154 .patch = patch_alc662 },
17155 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17156 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17157 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17158 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17159 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17160 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17161 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17162 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17163 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17164 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17165 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17166 .patch = patch_alc883 },
17167 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17168 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17169 {} /* terminator */
17172 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17174 MODULE_LICENSE("GPL");
17175 MODULE_DESCRIPTION("Realtek HD-audio codec");
17177 static struct hda_codec_preset_list realtek_list = {
17178 .preset = snd_hda_preset_realtek,
17179 .owner = THIS_MODULE,
17182 static int __init patch_realtek_init(void)
17184 return snd_hda_add_codec_preset(&realtek_list);
17187 static void __exit patch_realtek_exit(void)
17189 snd_hda_delete_codec_preset(&realtek_list);
17192 module_init(patch_realtek_init)
17193 module_exit(patch_realtek_exit)