2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_patch.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
81 #ifdef CONFIG_SND_DEBUG
85 ALC260_MODEL_LAST /* last tag */
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
108 ALC262_MODEL_LAST /* last tag */
117 ALC268_ACER_ASPIRE_ONE,
120 #ifdef CONFIG_SND_DEBUG
124 ALC268_MODEL_LAST /* last tag */
131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901,
135 ALC269_MODEL_LAST /* last tag */
152 /* ALC861-VD models */
173 ALC662_ASUS_EEEPC_P701,
174 ALC662_ASUS_EEEPC_EP20,
213 ALC883_TARGA_2ch_DIG,
219 ALC883_LENOVO_101E_2ch,
220 ALC883_LENOVO_NB0763,
221 ALC888_LENOVO_MS7195_DIG,
228 ALC883_FUJITSU_PI2515,
229 ALC883_3ST_6ch_INTEL,
237 #define GPIO_MASK 0x03
240 /* codec parameterization */
241 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
242 unsigned int num_mixers;
243 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
245 const struct hda_verb *init_verbs[5]; /* initialization verbs
249 unsigned int num_init_verbs;
251 char *stream_name_analog; /* analog PCM stream */
252 struct hda_pcm_stream *stream_analog_playback;
253 struct hda_pcm_stream *stream_analog_capture;
254 struct hda_pcm_stream *stream_analog_alt_playback;
255 struct hda_pcm_stream *stream_analog_alt_capture;
257 char *stream_name_digital; /* digital PCM stream */
258 struct hda_pcm_stream *stream_digital_playback;
259 struct hda_pcm_stream *stream_digital_capture;
262 struct hda_multi_out multiout; /* playback set-up
263 * max_channels, dacs must be set
264 * dig_out_nid and hp_nid are optional
266 hda_nid_t alt_dac_nid;
269 unsigned int num_adc_nids;
271 hda_nid_t *capsrc_nids;
272 hda_nid_t dig_in_nid; /* digital-in NID; optional */
273 unsigned char is_mix_capture; /* matrix-style capture (non-mux) */
276 unsigned int num_mux_defs;
277 const struct hda_input_mux *input_mux;
278 unsigned int cur_mux[3];
281 const struct hda_channel_mode *channel_mode;
282 int num_channel_mode;
285 /* PCM information */
286 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
288 /* dynamic controls, init_verbs and input_mux */
289 struct auto_pin_cfg autocfg;
290 struct snd_array kctls;
291 struct hda_input_mux private_imux;
292 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
295 void (*init_hook)(struct hda_codec *codec);
296 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
298 /* for pin sensing */
299 unsigned int sense_updated: 1;
300 unsigned int jack_present: 1;
301 unsigned int master_sw: 1;
303 /* for virtual master */
304 hda_nid_t vmaster_nid;
305 #ifdef CONFIG_SND_HDA_POWER_SAVE
306 struct hda_loopback_check loopback;
311 unsigned int pll_coef_idx, pll_coef_bit;
313 #ifdef SND_HDA_NEEDS_RESUME
314 #define ALC_MAX_PINS 16
315 unsigned int num_pins;
316 hda_nid_t pin_nids[ALC_MAX_PINS];
317 unsigned int pin_cfgs[ALC_MAX_PINS];
322 * configuration template - to be copied to the spec instance
324 struct alc_config_preset {
325 struct snd_kcontrol_new *mixers[5]; /* should be identical size
328 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
329 const struct hda_verb *init_verbs[5];
330 unsigned int num_dacs;
332 hda_nid_t dig_out_nid; /* optional */
333 hda_nid_t hp_nid; /* optional */
334 unsigned int num_adc_nids;
336 hda_nid_t *capsrc_nids;
337 hda_nid_t dig_in_nid;
338 unsigned int num_channel_mode;
339 const struct hda_channel_mode *channel_mode;
341 unsigned int num_mux_defs;
342 const struct hda_input_mux *input_mux;
343 void (*unsol_event)(struct hda_codec *, unsigned int);
344 void (*init_hook)(struct hda_codec *);
345 #ifdef CONFIG_SND_HDA_POWER_SAVE
346 struct hda_amp_list *loopbacks;
354 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_info *uinfo)
357 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct alc_spec *spec = codec->spec;
359 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
360 if (mux_idx >= spec->num_mux_defs)
362 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
365 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct alc_spec *spec = codec->spec;
370 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
372 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
376 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
380 struct alc_spec *spec = codec->spec;
381 const struct hda_input_mux *imux = spec->input_mux;
382 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
383 hda_nid_t nid = spec->capsrc_nids ?
384 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
386 if (spec->is_mix_capture) {
387 /* Matrix-mixer style (e.g. ALC882) */
388 unsigned int *cur_val = &spec->cur_mux[adc_idx];
391 idx = ucontrol->value.enumerated.item[0];
392 if (idx >= imux->num_items)
393 idx = imux->num_items - 1;
396 for (i = 0; i < imux->num_items; i++) {
397 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
398 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
399 imux->items[i].index,
405 /* MUX style (e.g. ALC880) */
406 unsigned int mux_idx;
407 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
408 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx],
410 &spec->cur_mux[adc_idx]);
415 * channel mode setting
417 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
418 struct snd_ctl_elem_info *uinfo)
420 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
421 struct alc_spec *spec = codec->spec;
422 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
423 spec->num_channel_mode);
426 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
427 struct snd_ctl_elem_value *ucontrol)
429 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430 struct alc_spec *spec = codec->spec;
431 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
432 spec->num_channel_mode,
433 spec->multiout.max_channels);
436 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_value *ucontrol)
439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
440 struct alc_spec *spec = codec->spec;
441 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
442 spec->num_channel_mode,
443 &spec->multiout.max_channels);
444 if (err >= 0 && spec->need_dac_fix)
445 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
450 * Control the mode of pin widget settings via the mixer. "pc" is used
451 * instead of "%" to avoid consequences of accidently treating the % as
452 * being part of a format specifier. Maximum allowed length of a value is
453 * 63 characters plus NULL terminator.
455 * Note: some retasking pin complexes seem to ignore requests for input
456 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
457 * are requested. Therefore order this list so that this behaviour will not
458 * cause problems when mixer clients move through the enum sequentially.
459 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
462 static char *alc_pin_mode_names[] = {
463 "Mic 50pc bias", "Mic 80pc bias",
464 "Line in", "Line out", "Headphone out",
466 static unsigned char alc_pin_mode_values[] = {
467 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
469 /* The control can present all 5 options, or it can limit the options based
470 * in the pin being assumed to be exclusively an input or an output pin. In
471 * addition, "input" pins may or may not process the mic bias option
472 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
473 * accept requests for bias as of chip versions up to March 2006) and/or
474 * wiring in the computer.
476 #define ALC_PIN_DIR_IN 0x00
477 #define ALC_PIN_DIR_OUT 0x01
478 #define ALC_PIN_DIR_INOUT 0x02
479 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
480 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
482 /* Info about the pin modes supported by the different pin direction modes.
483 * For each direction the minimum and maximum values are given.
485 static signed char alc_pin_mode_dir_info[5][2] = {
486 { 0, 2 }, /* ALC_PIN_DIR_IN */
487 { 3, 4 }, /* ALC_PIN_DIR_OUT */
488 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
489 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
490 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
492 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
493 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
494 #define alc_pin_mode_n_items(_dir) \
495 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
497 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_info *uinfo)
500 unsigned int item_num = uinfo->value.enumerated.item;
501 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
503 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
505 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
507 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
508 item_num = alc_pin_mode_min(dir);
509 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
513 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
518 hda_nid_t nid = kcontrol->private_value & 0xffff;
519 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
520 long *valp = ucontrol->value.integer.value;
521 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
522 AC_VERB_GET_PIN_WIDGET_CONTROL,
525 /* Find enumerated value for current pinctl setting */
526 i = alc_pin_mode_min(dir);
527 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
529 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
533 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
534 struct snd_ctl_elem_value *ucontrol)
537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538 hda_nid_t nid = kcontrol->private_value & 0xffff;
539 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
540 long val = *ucontrol->value.integer.value;
541 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
542 AC_VERB_GET_PIN_WIDGET_CONTROL,
545 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
546 val = alc_pin_mode_min(dir);
548 change = pinctl != alc_pin_mode_values[val];
550 /* Set pin mode to that requested */
551 snd_hda_codec_write_cache(codec, nid, 0,
552 AC_VERB_SET_PIN_WIDGET_CONTROL,
553 alc_pin_mode_values[val]);
555 /* Also enable the retasking pin's input/output as required
556 * for the requested pin mode. Enum values of 2 or less are
559 * Dynamically switching the input/output buffers probably
560 * reduces noise slightly (particularly on input) so we'll
561 * do it. However, having both input and output buffers
562 * enabled simultaneously doesn't seem to be problematic if
563 * this turns out to be necessary in the future.
566 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
567 HDA_AMP_MUTE, HDA_AMP_MUTE);
568 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
571 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
572 HDA_AMP_MUTE, HDA_AMP_MUTE);
573 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
580 #define ALC_PIN_MODE(xname, nid, dir) \
581 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
582 .info = alc_pin_mode_info, \
583 .get = alc_pin_mode_get, \
584 .put = alc_pin_mode_put, \
585 .private_value = nid | (dir<<16) }
587 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
588 * together using a mask with more than one bit set. This control is
589 * currently used only by the ALC260 test model. At this stage they are not
590 * needed for any "production" models.
592 #ifdef CONFIG_SND_DEBUG
593 #define alc_gpio_data_info snd_ctl_boolean_mono_info
595 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
596 struct snd_ctl_elem_value *ucontrol)
598 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
599 hda_nid_t nid = kcontrol->private_value & 0xffff;
600 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
601 long *valp = ucontrol->value.integer.value;
602 unsigned int val = snd_hda_codec_read(codec, nid, 0,
603 AC_VERB_GET_GPIO_DATA, 0x00);
605 *valp = (val & mask) != 0;
608 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613 hda_nid_t nid = kcontrol->private_value & 0xffff;
614 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
615 long val = *ucontrol->value.integer.value;
616 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
617 AC_VERB_GET_GPIO_DATA,
620 /* Set/unset the masked GPIO bit(s) as needed */
621 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
626 snd_hda_codec_write_cache(codec, nid, 0,
627 AC_VERB_SET_GPIO_DATA, gpio_data);
631 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
632 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
633 .info = alc_gpio_data_info, \
634 .get = alc_gpio_data_get, \
635 .put = alc_gpio_data_put, \
636 .private_value = nid | (mask<<16) }
637 #endif /* CONFIG_SND_DEBUG */
639 /* A switch control to allow the enabling of the digital IO pins on the
640 * ALC260. This is incredibly simplistic; the intention of this control is
641 * to provide something in the test model allowing digital outputs to be
642 * identified if present. If models are found which can utilise these
643 * outputs a more complete mixer control can be devised for those models if
646 #ifdef CONFIG_SND_DEBUG
647 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
649 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
650 struct snd_ctl_elem_value *ucontrol)
652 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
653 hda_nid_t nid = kcontrol->private_value & 0xffff;
654 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
655 long *valp = ucontrol->value.integer.value;
656 unsigned int val = snd_hda_codec_read(codec, nid, 0,
657 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
659 *valp = (val & mask) != 0;
662 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667 hda_nid_t nid = kcontrol->private_value & 0xffff;
668 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
669 long val = *ucontrol->value.integer.value;
670 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
671 AC_VERB_GET_DIGI_CONVERT_1,
674 /* Set/unset the masked control bit(s) as needed */
675 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
680 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
685 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
686 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
687 .info = alc_spdif_ctrl_info, \
688 .get = alc_spdif_ctrl_get, \
689 .put = alc_spdif_ctrl_put, \
690 .private_value = nid | (mask<<16) }
691 #endif /* CONFIG_SND_DEBUG */
693 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
694 * Again, this is only used in the ALC26x test models to help identify when
695 * the EAPD line must be asserted for features to work.
697 #ifdef CONFIG_SND_DEBUG
698 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
700 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
701 struct snd_ctl_elem_value *ucontrol)
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long *valp = ucontrol->value.integer.value;
707 unsigned int val = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
710 *valp = (val & mask) != 0;
714 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_value *ucontrol)
718 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
719 hda_nid_t nid = kcontrol->private_value & 0xffff;
720 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
721 long val = *ucontrol->value.integer.value;
722 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
723 AC_VERB_GET_EAPD_BTLENABLE,
726 /* Set/unset the masked control bit(s) as needed */
727 change = (!val ? 0 : mask) != (ctrl_data & mask);
732 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
738 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
739 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
740 .info = alc_eapd_ctrl_info, \
741 .get = alc_eapd_ctrl_get, \
742 .put = alc_eapd_ctrl_put, \
743 .private_value = nid | (mask<<16) }
744 #endif /* CONFIG_SND_DEBUG */
748 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
750 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
752 spec->mixers[spec->num_mixers++] = mix;
755 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
757 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
759 spec->init_verbs[spec->num_init_verbs++] = verb;
763 * set up from the preset table
765 static void setup_preset(struct alc_spec *spec,
766 const struct alc_config_preset *preset)
770 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
771 add_mixer(spec, preset->mixers[i]);
772 spec->cap_mixer = preset->cap_mixer;
773 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
775 add_verb(spec, preset->init_verbs[i]);
777 spec->channel_mode = preset->channel_mode;
778 spec->num_channel_mode = preset->num_channel_mode;
779 spec->need_dac_fix = preset->need_dac_fix;
781 spec->multiout.max_channels = spec->channel_mode[0].channels;
783 spec->multiout.num_dacs = preset->num_dacs;
784 spec->multiout.dac_nids = preset->dac_nids;
785 spec->multiout.dig_out_nid = preset->dig_out_nid;
786 spec->multiout.hp_nid = preset->hp_nid;
788 spec->num_mux_defs = preset->num_mux_defs;
789 if (!spec->num_mux_defs)
790 spec->num_mux_defs = 1;
791 spec->input_mux = preset->input_mux;
793 spec->num_adc_nids = preset->num_adc_nids;
794 spec->adc_nids = preset->adc_nids;
795 spec->capsrc_nids = preset->capsrc_nids;
796 spec->dig_in_nid = preset->dig_in_nid;
798 spec->unsol_event = preset->unsol_event;
799 spec->init_hook = preset->init_hook;
800 #ifdef CONFIG_SND_HDA_POWER_SAVE
801 spec->loopback.amplist = preset->loopbacks;
805 /* Enable GPIO mask and set output */
806 static struct hda_verb alc_gpio1_init_verbs[] = {
807 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
808 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
809 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
813 static struct hda_verb alc_gpio2_init_verbs[] = {
814 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
815 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
816 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
820 static struct hda_verb alc_gpio3_init_verbs[] = {
821 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
822 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
823 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
828 * Fix hardware PLL issue
829 * On some codecs, the analog PLL gating control must be off while
830 * the default value is 1.
832 static void alc_fix_pll(struct hda_codec *codec)
834 struct alc_spec *spec = codec->spec;
839 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
841 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
842 AC_VERB_GET_PROC_COEF, 0);
843 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
845 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
846 val & ~(1 << spec->pll_coef_bit));
849 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
850 unsigned int coef_idx, unsigned int coef_bit)
852 struct alc_spec *spec = codec->spec;
854 spec->pll_coef_idx = coef_idx;
855 spec->pll_coef_bit = coef_bit;
859 static void alc_sku_automute(struct hda_codec *codec)
861 struct alc_spec *spec = codec->spec;
862 unsigned int present;
863 unsigned int hp_nid = spec->autocfg.hp_pins[0];
864 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
866 /* need to execute and sync at first */
867 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
868 present = snd_hda_codec_read(codec, hp_nid, 0,
869 AC_VERB_GET_PIN_SENSE, 0);
870 spec->jack_present = (present & 0x80000000) != 0;
871 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
872 spec->jack_present ? 0 : PIN_OUT);
875 #if 0 /* it's broken in some acses -- temporarily disabled */
876 static void alc_mic_automute(struct hda_codec *codec)
878 struct alc_spec *spec = codec->spec;
879 unsigned int present;
880 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
881 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
882 unsigned int mix_nid = spec->capsrc_nids[0];
883 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
885 capsrc_idx_mic = mic_nid - 0x18;
886 capsrc_idx_fmic = fmic_nid - 0x18;
887 present = snd_hda_codec_read(codec, mic_nid, 0,
888 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
889 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
890 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
891 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
892 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
893 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
894 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
897 #define alc_mic_automute(codec) /* NOP */
898 #endif /* disabled */
900 /* unsolicited event for HP jack sensing */
901 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
903 if (codec->vendor_id == 0x10ec0880)
907 if (res == ALC880_HP_EVENT)
908 alc_sku_automute(codec);
910 if (res == ALC880_MIC_EVENT)
911 alc_mic_automute(codec);
914 static void alc_inithook(struct hda_codec *codec)
916 alc_sku_automute(codec);
917 alc_mic_automute(codec);
920 /* additional initialization for ALC888 variants */
921 static void alc888_coef_init(struct hda_codec *codec)
925 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
926 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
927 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
928 if ((tmp & 0xf0) == 2)
930 snd_hda_codec_read(codec, 0x20, 0,
931 AC_VERB_SET_PROC_COEF, 0x830);
934 snd_hda_codec_read(codec, 0x20, 0,
935 AC_VERB_SET_PROC_COEF, 0x3030);
938 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
939 * 31 ~ 16 : Manufacture ID
941 * 7 ~ 0 : Assembly ID
942 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
944 static void alc_subsystem_id(struct hda_codec *codec,
945 unsigned int porta, unsigned int porte,
948 unsigned int ass, tmp, i;
950 struct alc_spec *spec = codec->spec;
952 ass = codec->subsystem_id & 0xffff;
953 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
957 * 31~30 : port conetcivity
960 * 19~16 : Check sum (15:1)
965 if (codec->vendor_id == 0x10ec0260)
967 ass = snd_hda_codec_read(codec, nid, 0,
968 AC_VERB_GET_CONFIG_DEFAULT, 0);
969 if (!(ass & 1) && !(ass & 0x100000))
971 if ((ass >> 30) != 1) /* no physical connection */
976 for (i = 1; i < 16; i++) {
980 if (((ass >> 16) & 0xf) != tmp)
986 * 2 : 0 --> Desktop, 1 --> Laptop
987 * 3~5 : External Amplifier control
990 tmp = (ass & 0x38) >> 3; /* external Amp control */
993 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
996 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
999 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1001 case 5: /* set EAPD output high */
1002 switch (codec->vendor_id) {
1004 snd_hda_codec_write(codec, 0x0f, 0,
1005 AC_VERB_SET_EAPD_BTLENABLE, 2);
1006 snd_hda_codec_write(codec, 0x10, 0,
1007 AC_VERB_SET_EAPD_BTLENABLE, 2);
1018 snd_hda_codec_write(codec, 0x14, 0,
1019 AC_VERB_SET_EAPD_BTLENABLE, 2);
1020 snd_hda_codec_write(codec, 0x15, 0,
1021 AC_VERB_SET_EAPD_BTLENABLE, 2);
1024 switch (codec->vendor_id) {
1026 snd_hda_codec_write(codec, 0x1a, 0,
1027 AC_VERB_SET_COEF_INDEX, 7);
1028 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1029 AC_VERB_GET_PROC_COEF, 0);
1030 snd_hda_codec_write(codec, 0x1a, 0,
1031 AC_VERB_SET_COEF_INDEX, 7);
1032 snd_hda_codec_write(codec, 0x1a, 0,
1033 AC_VERB_SET_PROC_COEF,
1042 snd_hda_codec_write(codec, 0x20, 0,
1043 AC_VERB_SET_COEF_INDEX, 7);
1044 tmp = snd_hda_codec_read(codec, 0x20, 0,
1045 AC_VERB_GET_PROC_COEF, 0);
1046 snd_hda_codec_write(codec, 0x20, 0,
1047 AC_VERB_SET_COEF_INDEX, 7);
1048 snd_hda_codec_write(codec, 0x20, 0,
1049 AC_VERB_SET_PROC_COEF,
1053 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1057 snd_hda_codec_write(codec, 0x20, 0,
1058 AC_VERB_SET_COEF_INDEX, 7);
1059 tmp = snd_hda_codec_read(codec, 0x20, 0,
1060 AC_VERB_GET_PROC_COEF, 0);
1061 snd_hda_codec_write(codec, 0x20, 0,
1062 AC_VERB_SET_COEF_INDEX, 7);
1063 snd_hda_codec_write(codec, 0x20, 0,
1064 AC_VERB_SET_PROC_COEF,
1072 /* is laptop or Desktop and enable the function "Mute internal speaker
1073 * when the external headphone out jack is plugged"
1075 if (!(ass & 0x8000))
1078 * 10~8 : Jack location
1079 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1081 * 15 : 1 --> enable the function "Mute internal speaker
1082 * when the external headphone out jack is plugged"
1084 if (!spec->autocfg.speaker_pins[0]) {
1085 if (spec->autocfg.line_out_pins[0])
1086 spec->autocfg.speaker_pins[0] =
1087 spec->autocfg.line_out_pins[0];
1092 if (!spec->autocfg.hp_pins[0]) {
1093 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1095 spec->autocfg.hp_pins[0] = porta;
1097 spec->autocfg.hp_pins[0] = porte;
1099 spec->autocfg.hp_pins[0] = portd;
1103 if (spec->autocfg.hp_pins[0])
1104 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1105 AC_VERB_SET_UNSOLICITED_ENABLE,
1106 AC_USRSP_EN | ALC880_HP_EVENT);
1108 #if 0 /* it's broken in some acses -- temporarily disabled */
1109 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1110 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1111 snd_hda_codec_write(codec,
1112 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1113 AC_VERB_SET_UNSOLICITED_ENABLE,
1114 AC_USRSP_EN | ALC880_MIC_EVENT);
1115 #endif /* disabled */
1117 spec->unsol_event = alc_sku_unsol_event;
1121 * Fix-up pin default configurations
1129 static void alc_fix_pincfg(struct hda_codec *codec,
1130 const struct snd_pci_quirk *quirk,
1131 const struct alc_pincfg **pinfix)
1133 const struct alc_pincfg *cfg;
1135 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1139 cfg = pinfix[quirk->value];
1140 for (; cfg->nid; cfg++) {
1143 for (i = 0; i < 4; i++) {
1144 snd_hda_codec_write(codec, cfg->nid, 0,
1145 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1153 * ALC880 3-stack model
1155 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1156 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1157 * F-Mic = 0x1b, HP = 0x19
1160 static hda_nid_t alc880_dac_nids[4] = {
1161 /* front, rear, clfe, rear_surr */
1162 0x02, 0x05, 0x04, 0x03
1165 static hda_nid_t alc880_adc_nids[3] = {
1170 /* The datasheet says the node 0x07 is connected from inputs,
1171 * but it shows zero connection in the real implementation on some devices.
1172 * Note: this is a 915GAV bug, fixed on 915GLV
1174 static hda_nid_t alc880_adc_nids_alt[2] = {
1179 #define ALC880_DIGOUT_NID 0x06
1180 #define ALC880_DIGIN_NID 0x0a
1182 static struct hda_input_mux alc880_capture_source = {
1186 { "Front Mic", 0x3 },
1192 /* channel source setting (2/6 channel selection for 3-stack) */
1194 static struct hda_verb alc880_threestack_ch2_init[] = {
1195 /* set line-in to input, mute it */
1196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1198 /* set mic-in to input vref 80%, mute it */
1199 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1200 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1205 static struct hda_verb alc880_threestack_ch6_init[] = {
1206 /* set line-in to output, unmute it */
1207 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1208 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1209 /* set mic-in to output, unmute it */
1210 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1211 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1215 static struct hda_channel_mode alc880_threestack_modes[2] = {
1216 { 2, alc880_threestack_ch2_init },
1217 { 6, alc880_threestack_ch6_init },
1220 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1222 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1223 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1224 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1225 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1234 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1235 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1236 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1237 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1238 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1241 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1242 .name = "Channel Mode",
1243 .info = alc_ch_mode_info,
1244 .get = alc_ch_mode_get,
1245 .put = alc_ch_mode_put,
1250 /* capture mixer elements */
1251 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1252 struct snd_ctl_elem_info *uinfo)
1254 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1255 struct alc_spec *spec = codec->spec;
1258 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1259 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1261 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1262 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1266 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1267 unsigned int size, unsigned int __user *tlv)
1269 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1270 struct alc_spec *spec = codec->spec;
1273 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1274 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1276 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1277 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1281 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1282 struct snd_ctl_elem_value *ucontrol);
1284 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1285 struct snd_ctl_elem_value *ucontrol,
1288 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1289 struct alc_spec *spec = codec->spec;
1290 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1293 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1294 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1296 err = func(kcontrol, ucontrol);
1297 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1301 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1302 struct snd_ctl_elem_value *ucontrol)
1304 return alc_cap_getput_caller(kcontrol, ucontrol,
1305 snd_hda_mixer_amp_volume_get);
1308 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1309 struct snd_ctl_elem_value *ucontrol)
1311 return alc_cap_getput_caller(kcontrol, ucontrol,
1312 snd_hda_mixer_amp_volume_put);
1315 /* capture mixer elements */
1316 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1318 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1319 struct snd_ctl_elem_value *ucontrol)
1321 return alc_cap_getput_caller(kcontrol, ucontrol,
1322 snd_hda_mixer_amp_switch_get);
1325 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1326 struct snd_ctl_elem_value *ucontrol)
1328 return alc_cap_getput_caller(kcontrol, ucontrol,
1329 snd_hda_mixer_amp_switch_put);
1332 #define DEFINE_CAPMIX(num) \
1333 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1336 .name = "Capture Switch", \
1337 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1339 .info = alc_cap_sw_info, \
1340 .get = alc_cap_sw_get, \
1341 .put = alc_cap_sw_put, \
1344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1345 .name = "Capture Volume", \
1346 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1347 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1348 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1350 .info = alc_cap_vol_info, \
1351 .get = alc_cap_vol_get, \
1352 .put = alc_cap_vol_put, \
1353 .tlv = { .c = alc_cap_vol_tlv }, \
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1357 /* .name = "Capture Source", */ \
1358 .name = "Input Source", \
1360 .info = alc_mux_enum_info, \
1361 .get = alc_mux_enum_get, \
1362 .put = alc_mux_enum_put, \
1367 /* up to three ADCs */
1374 * ALC880 5-stack model
1376 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1378 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1379 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1382 /* additional mixers to alc880_three_stack_mixer */
1383 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1384 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1385 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1389 /* channel source setting (6/8 channel selection for 5-stack) */
1391 static struct hda_verb alc880_fivestack_ch6_init[] = {
1392 /* set line-in to input, mute it */
1393 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1394 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1399 static struct hda_verb alc880_fivestack_ch8_init[] = {
1400 /* set line-in to output, unmute it */
1401 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1402 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1406 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1407 { 6, alc880_fivestack_ch6_init },
1408 { 8, alc880_fivestack_ch8_init },
1413 * ALC880 6-stack model
1415 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1416 * Side = 0x05 (0x0f)
1417 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1418 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1421 static hda_nid_t alc880_6st_dac_nids[4] = {
1422 /* front, rear, clfe, rear_surr */
1423 0x02, 0x03, 0x04, 0x05
1426 static struct hda_input_mux alc880_6stack_capture_source = {
1430 { "Front Mic", 0x1 },
1436 /* fixed 8-channels */
1437 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1441 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1442 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1443 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1444 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1445 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1446 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1447 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1448 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1449 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1450 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1451 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1452 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1453 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1454 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1455 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1456 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1457 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1458 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1460 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1461 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1464 .name = "Channel Mode",
1465 .info = alc_ch_mode_info,
1466 .get = alc_ch_mode_get,
1467 .put = alc_ch_mode_put,
1476 * W810 has rear IO for:
1479 * Center/LFE (DAC 04)
1482 * The system also has a pair of internal speakers, and a headphone jack.
1483 * These are both connected to Line2 on the codec, hence to DAC 02.
1485 * There is a variable resistor to control the speaker or headphone
1486 * volume. This is a hardware-only device without a software API.
1488 * Plugging headphones in will disable the internal speakers. This is
1489 * implemented in hardware, not via the driver using jack sense. In
1490 * a similar fashion, plugging into the rear socket marked "front" will
1491 * disable both the speakers and headphones.
1493 * For input, there's a microphone jack, and an "audio in" jack.
1494 * These may not do anything useful with this driver yet, because I
1495 * haven't setup any initialization verbs for these yet...
1498 static hda_nid_t alc880_w810_dac_nids[3] = {
1499 /* front, rear/surround, clfe */
1503 /* fixed 6 channels */
1504 static struct hda_channel_mode alc880_w810_modes[1] = {
1508 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1509 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1510 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1511 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1512 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1513 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1514 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1515 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1516 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1517 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1518 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1526 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1527 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1531 static hda_nid_t alc880_z71v_dac_nids[1] = {
1534 #define ALC880_Z71V_HP_DAC 0x03
1536 /* fixed 2 channels */
1537 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1541 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1542 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1543 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1544 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1545 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1546 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1547 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1555 * ALC880 F1734 model
1557 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1558 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1561 static hda_nid_t alc880_f1734_dac_nids[1] = {
1564 #define ALC880_F1734_HP_DAC 0x02
1566 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1567 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1568 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1569 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1570 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1573 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1574 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1578 static struct hda_input_mux alc880_f1734_capture_source = {
1590 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1591 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1592 * Mic = 0x18, Line = 0x1a
1595 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1596 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1598 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1599 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1600 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1601 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1602 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1603 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1604 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1607 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1608 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1615 .name = "Channel Mode",
1616 .info = alc_ch_mode_info,
1617 .get = alc_ch_mode_get,
1618 .put = alc_ch_mode_put,
1624 * ALC880 ASUS W1V model
1626 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1627 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1628 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1631 /* additional mixers to alc880_asus_mixer */
1632 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1633 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1634 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1638 /* additional mixers to alc880_asus_mixer */
1639 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1640 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1641 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1646 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1648 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1650 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1651 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1654 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1655 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1660 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1661 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1662 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1663 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1664 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1665 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1667 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1668 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1670 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1671 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1672 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1675 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1676 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1677 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1678 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1680 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1681 .name = "Channel Mode",
1682 .info = alc_ch_mode_info,
1683 .get = alc_ch_mode_get,
1684 .put = alc_ch_mode_put,
1689 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1690 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1691 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1692 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1693 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1694 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1695 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1696 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1697 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1698 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1699 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1703 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1705 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1706 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1707 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1714 * virtual master controls
1718 * slave controls for virtual master
1720 static const char *alc_slave_vols[] = {
1721 "Front Playback Volume",
1722 "Surround Playback Volume",
1723 "Center Playback Volume",
1724 "LFE Playback Volume",
1725 "Side Playback Volume",
1726 "Headphone Playback Volume",
1727 "Speaker Playback Volume",
1728 "Mono Playback Volume",
1729 "Line-Out Playback Volume",
1730 "PCM Playback Volume",
1734 static const char *alc_slave_sws[] = {
1735 "Front Playback Switch",
1736 "Surround Playback Switch",
1737 "Center Playback Switch",
1738 "LFE Playback Switch",
1739 "Side Playback Switch",
1740 "Headphone Playback Switch",
1741 "Speaker Playback Switch",
1742 "Mono Playback Switch",
1743 "IEC958 Playback Switch",
1748 * build control elements
1751 static void alc_free_kctls(struct hda_codec *codec);
1753 static int alc_build_controls(struct hda_codec *codec)
1755 struct alc_spec *spec = codec->spec;
1759 for (i = 0; i < spec->num_mixers; i++) {
1760 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1764 if (spec->cap_mixer) {
1765 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
1769 if (spec->multiout.dig_out_nid) {
1770 err = snd_hda_create_spdif_out_ctls(codec,
1771 spec->multiout.dig_out_nid);
1774 err = snd_hda_create_spdif_share_sw(codec,
1778 spec->multiout.share_spdif = 1;
1780 if (spec->dig_in_nid) {
1781 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1786 /* if we have no master control, let's create it */
1787 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1788 unsigned int vmaster_tlv[4];
1789 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1790 HDA_OUTPUT, vmaster_tlv);
1791 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1792 vmaster_tlv, alc_slave_vols);
1796 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1797 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1798 NULL, alc_slave_sws);
1803 alc_free_kctls(codec); /* no longer needed */
1809 * initialize the codec volumes, etc
1813 * generic initialization of ADC, input mixers and output mixers
1815 static struct hda_verb alc880_volume_init_verbs[] = {
1817 * Unmute ADC0-2 and set the default input to mic-in
1819 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1821 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1823 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1824 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1826 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1828 * Note: PASD motherboards uses the Line In 2 as the input for front
1831 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1841 * Set up output mixers (0x0c - 0x0f)
1843 /* set vol=0 to output mixers */
1844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1848 /* set up input amps for analog loopback */
1849 /* Amp Indices: DAC = 0, mixer = 1 */
1850 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1852 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1853 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1854 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1855 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1856 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1857 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1863 * 3-stack pin configuration:
1864 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1866 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1868 * preset connection lists of input pins
1869 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1871 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1872 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1873 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1876 * Set pin mode and muting
1878 /* set front pin widgets 0x14 for output */
1879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1882 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1883 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1884 /* Mic2 (as headphone out) for HP output */
1885 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1886 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1887 /* Line In pin widget for input */
1888 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1889 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1890 /* Line2 (as front mic) pin widget for input and vref at 80% */
1891 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1892 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1893 /* CD pin widget for input */
1894 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1900 * 5-stack pin configuration:
1901 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1902 * line-in/side = 0x1a, f-mic = 0x1b
1904 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1906 * preset connection lists of input pins
1907 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1909 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1910 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1913 * Set pin mode and muting
1915 /* set pin widgets 0x14-0x17 for output */
1916 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1917 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1919 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1920 /* unmute pins for output (no gain on this amp) */
1921 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1928 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1929 /* Mic2 (as headphone out) for HP output */
1930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1931 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1932 /* Line In pin widget for input */
1933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1935 /* Line2 (as front mic) pin widget for input and vref at 80% */
1936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1938 /* CD pin widget for input */
1939 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1945 * W810 pin configuration:
1946 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1948 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1949 /* hphone/speaker input selector: front DAC */
1950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1966 * Z71V pin configuration:
1967 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1969 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1970 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1971 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1972 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1975 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1978 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1984 * 6-stack pin configuration:
1985 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1986 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1988 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1989 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1992 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1996 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1997 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2002 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2003 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2004 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2005 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2014 * Uniwill pin configuration:
2015 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2018 static struct hda_verb alc880_uniwill_init_verbs[] = {
2019 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2021 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2022 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2023 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2024 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2025 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2026 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2027 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2028 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2030 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2032 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2036 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2038 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2039 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2040 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2042 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2043 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2044 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2046 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2054 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2056 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2057 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2064 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2067 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2068 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2069 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2070 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2072 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2074 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2076 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2080 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2085 static struct hda_verb alc880_beep_init_verbs[] = {
2086 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2090 /* toggle speaker-output according to the hp-jack state */
2091 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
2093 unsigned int present;
2096 present = snd_hda_codec_read(codec, 0x14, 0,
2097 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2098 bits = present ? HDA_AMP_MUTE : 0;
2099 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2100 HDA_AMP_MUTE, bits);
2101 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2102 HDA_AMP_MUTE, bits);
2105 /* auto-toggle front mic */
2106 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2108 unsigned int present;
2111 present = snd_hda_codec_read(codec, 0x18, 0,
2112 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2113 bits = present ? HDA_AMP_MUTE : 0;
2114 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2117 static void alc880_uniwill_automute(struct hda_codec *codec)
2119 alc880_uniwill_hp_automute(codec);
2120 alc880_uniwill_mic_automute(codec);
2123 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2126 /* Looks like the unsol event is incompatible with the standard
2127 * definition. 4bit tag is placed at 28 bit!
2129 switch (res >> 28) {
2130 case ALC880_HP_EVENT:
2131 alc880_uniwill_hp_automute(codec);
2133 case ALC880_MIC_EVENT:
2134 alc880_uniwill_mic_automute(codec);
2139 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2141 unsigned int present;
2144 present = snd_hda_codec_read(codec, 0x14, 0,
2145 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2146 bits = present ? HDA_AMP_MUTE : 0;
2147 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2150 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2152 unsigned int present;
2154 present = snd_hda_codec_read(codec, 0x21, 0,
2155 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2156 present &= HDA_AMP_VOLMASK;
2157 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2158 HDA_AMP_VOLMASK, present);
2159 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2160 HDA_AMP_VOLMASK, present);
2163 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2166 /* Looks like the unsol event is incompatible with the standard
2167 * definition. 4bit tag is placed at 28 bit!
2169 if ((res >> 28) == ALC880_HP_EVENT)
2170 alc880_uniwill_p53_hp_automute(codec);
2171 if ((res >> 28) == ALC880_DCVOL_EVENT)
2172 alc880_uniwill_p53_dcvol_automute(codec);
2176 * F1734 pin configuration:
2177 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2179 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2180 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2181 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2182 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2183 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2184 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2186 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2187 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2192 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2194 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2195 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2196 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2197 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2198 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2199 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2201 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2202 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2208 * ASUS pin configuration:
2209 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2211 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2212 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2213 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2214 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2215 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2227 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2228 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2231 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2233 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2239 /* Enable GPIO mask and set output */
2240 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2241 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2243 /* Clevo m520g init */
2244 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2245 /* headphone output */
2246 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2251 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2255 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2256 /* Mic1 (rear panel) */
2257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2258 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259 /* Mic2 (front panel) */
2260 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2263 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2265 /* change to EAPD mode */
2266 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2267 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2272 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2273 /* change to EAPD mode */
2274 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2275 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2277 /* Headphone output */
2278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2280 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2281 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2283 /* Line In pin widget for input */
2284 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2285 /* CD pin widget for input */
2286 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2287 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2288 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2290 /* change to EAPD mode */
2291 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2292 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2298 * LG m1 express dual
2301 * Rear Line-In/Out (blue): 0x14
2302 * Build-in Mic-In: 0x15
2304 * HP-Out (green): 0x1b
2305 * Mic-In/Out (red): 0x19
2309 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2310 static hda_nid_t alc880_lg_dac_nids[3] = {
2314 /* seems analog CD is not working */
2315 static struct hda_input_mux alc880_lg_capture_source = {
2320 { "Internal Mic", 0x6 },
2324 /* 2,4,6 channel modes */
2325 static struct hda_verb alc880_lg_ch2_init[] = {
2326 /* set line-in and mic-in to input */
2327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2332 static struct hda_verb alc880_lg_ch4_init[] = {
2333 /* set line-in to out and mic-in to input */
2334 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2335 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2339 static struct hda_verb alc880_lg_ch6_init[] = {
2340 /* set line-in and mic-in to output */
2341 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2342 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2346 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2347 { 2, alc880_lg_ch2_init },
2348 { 4, alc880_lg_ch4_init },
2349 { 6, alc880_lg_ch6_init },
2352 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2354 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2355 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2356 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2357 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2358 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2359 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2360 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2361 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2362 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2363 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2364 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2365 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2366 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2368 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2369 .name = "Channel Mode",
2370 .info = alc_ch_mode_info,
2371 .get = alc_ch_mode_get,
2372 .put = alc_ch_mode_put,
2377 static struct hda_verb alc880_lg_init_verbs[] = {
2378 /* set capture source to mic-in */
2379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2380 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2381 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2382 /* mute all amp mixer inputs */
2383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2386 /* line-in to input */
2387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2388 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2390 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2391 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2393 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2394 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2395 /* mic-in to input */
2396 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2397 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2398 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2400 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2404 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2408 /* toggle speaker-output according to the hp-jack state */
2409 static void alc880_lg_automute(struct hda_codec *codec)
2411 unsigned int present;
2414 present = snd_hda_codec_read(codec, 0x1b, 0,
2415 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2416 bits = present ? HDA_AMP_MUTE : 0;
2417 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2418 HDA_AMP_MUTE, bits);
2421 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2423 /* Looks like the unsol event is incompatible with the standard
2424 * definition. 4bit tag is placed at 28 bit!
2426 if ((res >> 28) == 0x01)
2427 alc880_lg_automute(codec);
2436 * Built-in Mic-In: 0x19
2442 static struct hda_input_mux alc880_lg_lw_capture_source = {
2446 { "Internal Mic", 0x1 },
2451 #define alc880_lg_lw_modes alc880_threestack_modes
2453 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2454 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2456 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2457 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2458 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2459 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2460 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2461 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2462 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2463 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2466 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2467 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2469 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2470 .name = "Channel Mode",
2471 .info = alc_ch_mode_info,
2472 .get = alc_ch_mode_get,
2473 .put = alc_ch_mode_put,
2478 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2479 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2480 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2481 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2483 /* set capture source to mic-in */
2484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2489 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2492 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2493 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2494 /* mic-in to input */
2495 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2498 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2499 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2501 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2505 /* toggle speaker-output according to the hp-jack state */
2506 static void alc880_lg_lw_automute(struct hda_codec *codec)
2508 unsigned int present;
2511 present = snd_hda_codec_read(codec, 0x1b, 0,
2512 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2513 bits = present ? HDA_AMP_MUTE : 0;
2514 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2515 HDA_AMP_MUTE, bits);
2518 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2520 /* Looks like the unsol event is incompatible with the standard
2521 * definition. 4bit tag is placed at 28 bit!
2523 if ((res >> 28) == 0x01)
2524 alc880_lg_lw_automute(codec);
2527 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2528 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2530 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2531 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2533 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2537 static struct hda_input_mux alc880_medion_rim_capture_source = {
2541 { "Internal Mic", 0x1 },
2545 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2546 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2549 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2551 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2554 /* Mic2 (as headphone out) for HP output */
2555 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2557 /* Internal Speaker */
2558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2561 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2562 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2564 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2568 /* toggle speaker-output according to the hp-jack state */
2569 static void alc880_medion_rim_automute(struct hda_codec *codec)
2571 unsigned int present;
2574 present = snd_hda_codec_read(codec, 0x14, 0,
2575 AC_VERB_GET_PIN_SENSE, 0)
2576 & AC_PINSENSE_PRESENCE;
2577 bits = present ? HDA_AMP_MUTE : 0;
2578 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2579 HDA_AMP_MUTE, bits);
2581 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2583 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2586 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2589 /* Looks like the unsol event is incompatible with the standard
2590 * definition. 4bit tag is placed at 28 bit!
2592 if ((res >> 28) == ALC880_HP_EVENT)
2593 alc880_medion_rim_automute(codec);
2596 #ifdef CONFIG_SND_HDA_POWER_SAVE
2597 static struct hda_amp_list alc880_loopbacks[] = {
2598 { 0x0b, HDA_INPUT, 0 },
2599 { 0x0b, HDA_INPUT, 1 },
2600 { 0x0b, HDA_INPUT, 2 },
2601 { 0x0b, HDA_INPUT, 3 },
2602 { 0x0b, HDA_INPUT, 4 },
2606 static struct hda_amp_list alc880_lg_loopbacks[] = {
2607 { 0x0b, HDA_INPUT, 1 },
2608 { 0x0b, HDA_INPUT, 6 },
2609 { 0x0b, HDA_INPUT, 7 },
2618 static int alc_init(struct hda_codec *codec)
2620 struct alc_spec *spec = codec->spec;
2624 if (codec->vendor_id == 0x10ec0888)
2625 alc888_coef_init(codec);
2627 for (i = 0; i < spec->num_init_verbs; i++)
2628 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2630 if (spec->init_hook)
2631 spec->init_hook(codec);
2636 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2638 struct alc_spec *spec = codec->spec;
2640 if (spec->unsol_event)
2641 spec->unsol_event(codec, res);
2644 #ifdef CONFIG_SND_HDA_POWER_SAVE
2645 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2647 struct alc_spec *spec = codec->spec;
2648 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2653 * Analog playback callbacks
2655 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2656 struct hda_codec *codec,
2657 struct snd_pcm_substream *substream)
2659 struct alc_spec *spec = codec->spec;
2660 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2664 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2665 struct hda_codec *codec,
2666 unsigned int stream_tag,
2667 unsigned int format,
2668 struct snd_pcm_substream *substream)
2670 struct alc_spec *spec = codec->spec;
2671 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2672 stream_tag, format, substream);
2675 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2676 struct hda_codec *codec,
2677 struct snd_pcm_substream *substream)
2679 struct alc_spec *spec = codec->spec;
2680 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2686 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2687 struct hda_codec *codec,
2688 struct snd_pcm_substream *substream)
2690 struct alc_spec *spec = codec->spec;
2691 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2694 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2695 struct hda_codec *codec,
2696 unsigned int stream_tag,
2697 unsigned int format,
2698 struct snd_pcm_substream *substream)
2700 struct alc_spec *spec = codec->spec;
2701 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2702 stream_tag, format, substream);
2705 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2706 struct hda_codec *codec,
2707 struct snd_pcm_substream *substream)
2709 struct alc_spec *spec = codec->spec;
2710 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2716 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2717 struct hda_codec *codec,
2718 unsigned int stream_tag,
2719 unsigned int format,
2720 struct snd_pcm_substream *substream)
2722 struct alc_spec *spec = codec->spec;
2724 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2725 stream_tag, 0, format);
2729 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2730 struct hda_codec *codec,
2731 struct snd_pcm_substream *substream)
2733 struct alc_spec *spec = codec->spec;
2735 snd_hda_codec_cleanup_stream(codec,
2736 spec->adc_nids[substream->number + 1]);
2743 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2747 /* NID is set in alc_build_pcms */
2749 .open = alc880_playback_pcm_open,
2750 .prepare = alc880_playback_pcm_prepare,
2751 .cleanup = alc880_playback_pcm_cleanup
2755 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2759 /* NID is set in alc_build_pcms */
2762 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2766 /* NID is set in alc_build_pcms */
2769 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2770 .substreams = 2, /* can be overridden */
2773 /* NID is set in alc_build_pcms */
2775 .prepare = alc880_alt_capture_pcm_prepare,
2776 .cleanup = alc880_alt_capture_pcm_cleanup
2780 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2784 /* NID is set in alc_build_pcms */
2786 .open = alc880_dig_playback_pcm_open,
2787 .close = alc880_dig_playback_pcm_close,
2788 .prepare = alc880_dig_playback_pcm_prepare
2792 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2796 /* NID is set in alc_build_pcms */
2799 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2800 static struct hda_pcm_stream alc_pcm_null_stream = {
2806 static int alc_build_pcms(struct hda_codec *codec)
2808 struct alc_spec *spec = codec->spec;
2809 struct hda_pcm *info = spec->pcm_rec;
2812 codec->num_pcms = 1;
2813 codec->pcm_info = info;
2815 info->name = spec->stream_name_analog;
2816 if (spec->stream_analog_playback) {
2817 if (snd_BUG_ON(!spec->multiout.dac_nids))
2819 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2820 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2822 if (spec->stream_analog_capture) {
2823 if (snd_BUG_ON(!spec->adc_nids))
2825 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2826 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2829 if (spec->channel_mode) {
2830 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2831 for (i = 0; i < spec->num_channel_mode; i++) {
2832 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2833 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2838 /* SPDIF for stream index #1 */
2839 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2840 codec->num_pcms = 2;
2841 info = spec->pcm_rec + 1;
2842 info->name = spec->stream_name_digital;
2843 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2844 if (spec->multiout.dig_out_nid &&
2845 spec->stream_digital_playback) {
2846 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2847 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2849 if (spec->dig_in_nid &&
2850 spec->stream_digital_capture) {
2851 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2852 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2854 /* FIXME: do we need this for all Realtek codec models? */
2855 codec->spdif_status_reset = 1;
2858 /* If the use of more than one ADC is requested for the current
2859 * model, configure a second analog capture-only PCM.
2861 /* Additional Analaog capture for index #2 */
2862 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2863 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2864 codec->num_pcms = 3;
2865 info = spec->pcm_rec + 2;
2866 info->name = spec->stream_name_analog;
2867 if (spec->alt_dac_nid) {
2868 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2869 *spec->stream_analog_alt_playback;
2870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2873 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2874 alc_pcm_null_stream;
2875 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2877 if (spec->num_adc_nids > 1) {
2878 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2879 *spec->stream_analog_alt_capture;
2880 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2882 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2883 spec->num_adc_nids - 1;
2885 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2886 alc_pcm_null_stream;
2887 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2894 static void alc_free_kctls(struct hda_codec *codec)
2896 struct alc_spec *spec = codec->spec;
2898 if (spec->kctls.list) {
2899 struct snd_kcontrol_new *kctl = spec->kctls.list;
2901 for (i = 0; i < spec->kctls.used; i++)
2902 kfree(kctl[i].name);
2904 snd_array_free(&spec->kctls);
2907 static void alc_free(struct hda_codec *codec)
2909 struct alc_spec *spec = codec->spec;
2914 alc_free_kctls(codec);
2916 codec->spec = NULL; /* to be sure */
2919 #ifdef SND_HDA_NEEDS_RESUME
2920 static void store_pin_configs(struct hda_codec *codec)
2922 struct alc_spec *spec = codec->spec;
2923 hda_nid_t nid, end_nid;
2925 end_nid = codec->start_nid + codec->num_nodes;
2926 for (nid = codec->start_nid; nid < end_nid; nid++) {
2927 unsigned int wid_caps = get_wcaps(codec, nid);
2928 unsigned int wid_type =
2929 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2930 if (wid_type != AC_WID_PIN)
2932 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2934 spec->pin_nids[spec->num_pins] = nid;
2935 spec->pin_cfgs[spec->num_pins] =
2936 snd_hda_codec_read(codec, nid, 0,
2937 AC_VERB_GET_CONFIG_DEFAULT, 0);
2942 static void resume_pin_configs(struct hda_codec *codec)
2944 struct alc_spec *spec = codec->spec;
2947 for (i = 0; i < spec->num_pins; i++) {
2948 hda_nid_t pin_nid = spec->pin_nids[i];
2949 unsigned int pin_config = spec->pin_cfgs[i];
2950 snd_hda_codec_write(codec, pin_nid, 0,
2951 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2952 pin_config & 0x000000ff);
2953 snd_hda_codec_write(codec, pin_nid, 0,
2954 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2955 (pin_config & 0x0000ff00) >> 8);
2956 snd_hda_codec_write(codec, pin_nid, 0,
2957 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2958 (pin_config & 0x00ff0000) >> 16);
2959 snd_hda_codec_write(codec, pin_nid, 0,
2960 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2965 static int alc_resume(struct hda_codec *codec)
2967 resume_pin_configs(codec);
2968 codec->patch_ops.init(codec);
2969 snd_hda_codec_resume_amp(codec);
2970 snd_hda_codec_resume_cache(codec);
2974 #define store_pin_configs(codec)
2979 static struct hda_codec_ops alc_patch_ops = {
2980 .build_controls = alc_build_controls,
2981 .build_pcms = alc_build_pcms,
2984 .unsol_event = alc_unsol_event,
2985 #ifdef SND_HDA_NEEDS_RESUME
2986 .resume = alc_resume,
2988 #ifdef CONFIG_SND_HDA_POWER_SAVE
2989 .check_power_status = alc_check_power_status,
2995 * Test configuration for debugging
2997 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3000 #ifdef CONFIG_SND_DEBUG
3001 static hda_nid_t alc880_test_dac_nids[4] = {
3002 0x02, 0x03, 0x04, 0x05
3005 static struct hda_input_mux alc880_test_capture_source = {
3014 { "Surround", 0x6 },
3018 static struct hda_channel_mode alc880_test_modes[4] = {
3025 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3026 struct snd_ctl_elem_info *uinfo)
3028 static char *texts[] = {
3029 "N/A", "Line Out", "HP Out",
3030 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3032 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3034 uinfo->value.enumerated.items = 8;
3035 if (uinfo->value.enumerated.item >= 8)
3036 uinfo->value.enumerated.item = 7;
3037 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3041 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3042 struct snd_ctl_elem_value *ucontrol)
3044 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3045 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3046 unsigned int pin_ctl, item = 0;
3048 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3049 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3050 if (pin_ctl & AC_PINCTL_OUT_EN) {
3051 if (pin_ctl & AC_PINCTL_HP_EN)
3055 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3056 switch (pin_ctl & AC_PINCTL_VREFEN) {
3057 case AC_PINCTL_VREF_HIZ: item = 3; break;
3058 case AC_PINCTL_VREF_50: item = 4; break;
3059 case AC_PINCTL_VREF_GRD: item = 5; break;
3060 case AC_PINCTL_VREF_80: item = 6; break;
3061 case AC_PINCTL_VREF_100: item = 7; break;
3064 ucontrol->value.enumerated.item[0] = item;
3068 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3069 struct snd_ctl_elem_value *ucontrol)
3071 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3072 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3073 static unsigned int ctls[] = {
3074 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3075 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3076 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3077 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3078 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3079 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3081 unsigned int old_ctl, new_ctl;
3083 old_ctl = snd_hda_codec_read(codec, nid, 0,
3084 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3085 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3086 if (old_ctl != new_ctl) {
3088 snd_hda_codec_write_cache(codec, nid, 0,
3089 AC_VERB_SET_PIN_WIDGET_CONTROL,
3091 val = ucontrol->value.enumerated.item[0] >= 3 ?
3093 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3100 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3101 struct snd_ctl_elem_info *uinfo)
3103 static char *texts[] = {
3104 "Front", "Surround", "CLFE", "Side"
3106 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3108 uinfo->value.enumerated.items = 4;
3109 if (uinfo->value.enumerated.item >= 4)
3110 uinfo->value.enumerated.item = 3;
3111 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3115 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3116 struct snd_ctl_elem_value *ucontrol)
3118 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3119 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3122 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3123 ucontrol->value.enumerated.item[0] = sel & 3;
3127 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3128 struct snd_ctl_elem_value *ucontrol)
3130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3131 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3134 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3135 if (ucontrol->value.enumerated.item[0] != sel) {
3136 sel = ucontrol->value.enumerated.item[0] & 3;
3137 snd_hda_codec_write_cache(codec, nid, 0,
3138 AC_VERB_SET_CONNECT_SEL, sel);
3144 #define PIN_CTL_TEST(xname,nid) { \
3145 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3147 .info = alc_test_pin_ctl_info, \
3148 .get = alc_test_pin_ctl_get, \
3149 .put = alc_test_pin_ctl_put, \
3150 .private_value = nid \
3153 #define PIN_SRC_TEST(xname,nid) { \
3154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3156 .info = alc_test_pin_src_info, \
3157 .get = alc_test_pin_src_get, \
3158 .put = alc_test_pin_src_put, \
3159 .private_value = nid \
3162 static struct snd_kcontrol_new alc880_test_mixer[] = {
3163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3164 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3165 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3166 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3167 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3169 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3170 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3171 PIN_CTL_TEST("Front Pin Mode", 0x14),
3172 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3173 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3174 PIN_CTL_TEST("Side Pin Mode", 0x17),
3175 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3176 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3177 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3178 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3179 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3180 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3181 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3182 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3183 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3184 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3185 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3186 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3187 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3188 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3189 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3190 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3191 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3192 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3194 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3195 .name = "Channel Mode",
3196 .info = alc_ch_mode_info,
3197 .get = alc_ch_mode_get,
3198 .put = alc_ch_mode_put,
3203 static struct hda_verb alc880_test_init_verbs[] = {
3204 /* Unmute inputs of 0x0c - 0x0f */
3205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3206 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3207 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3208 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3209 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3210 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3211 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3212 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3213 /* Vol output for 0x0c-0x0f */
3214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3216 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3218 /* Set output pins 0x14-0x17 */
3219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3221 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3222 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3223 /* Unmute output pins 0x14-0x17 */
3224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3226 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3227 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3228 /* Set input pins 0x18-0x1c */
3229 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3230 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3231 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3232 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3233 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3234 /* Mute input pins 0x18-0x1b */
3235 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3238 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3241 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3243 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3245 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3246 /* Analog input/passthru */
3247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3259 static const char *alc880_models[ALC880_MODEL_LAST] = {
3260 [ALC880_3ST] = "3stack",
3261 [ALC880_TCL_S700] = "tcl",
3262 [ALC880_3ST_DIG] = "3stack-digout",
3263 [ALC880_CLEVO] = "clevo",
3264 [ALC880_5ST] = "5stack",
3265 [ALC880_5ST_DIG] = "5stack-digout",
3266 [ALC880_W810] = "w810",
3267 [ALC880_Z71V] = "z71v",
3268 [ALC880_6ST] = "6stack",
3269 [ALC880_6ST_DIG] = "6stack-digout",
3270 [ALC880_ASUS] = "asus",
3271 [ALC880_ASUS_W1V] = "asus-w1v",
3272 [ALC880_ASUS_DIG] = "asus-dig",
3273 [ALC880_ASUS_DIG2] = "asus-dig2",
3274 [ALC880_UNIWILL_DIG] = "uniwill",
3275 [ALC880_UNIWILL_P53] = "uniwill-p53",
3276 [ALC880_FUJITSU] = "fujitsu",
3277 [ALC880_F1734] = "F1734",
3279 [ALC880_LG_LW] = "lg-lw",
3280 [ALC880_MEDION_RIM] = "medion",
3281 #ifdef CONFIG_SND_DEBUG
3282 [ALC880_TEST] = "test",
3284 [ALC880_AUTO] = "auto",
3287 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3288 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3289 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3290 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3291 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3292 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3293 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3294 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3295 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3296 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3297 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3298 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3299 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3300 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3301 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3302 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3303 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3304 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3305 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3306 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3307 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3308 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3309 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3310 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3311 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3312 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3313 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3314 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3315 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3316 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3317 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3318 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3319 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3320 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3321 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3322 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3323 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3324 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3325 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3326 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3327 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3328 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3329 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3330 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3331 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3332 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3333 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3334 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3335 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3336 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3337 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3338 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3339 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3340 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3341 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3342 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3343 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3344 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3345 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3346 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3347 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3348 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3349 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3350 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3351 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3352 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3353 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3354 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3355 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3356 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3357 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3358 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3363 * ALC880 codec presets
3365 static struct alc_config_preset alc880_presets[] = {
3367 .mixers = { alc880_three_stack_mixer },
3368 .init_verbs = { alc880_volume_init_verbs,
3369 alc880_pin_3stack_init_verbs },
3370 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3371 .dac_nids = alc880_dac_nids,
3372 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3373 .channel_mode = alc880_threestack_modes,
3375 .input_mux = &alc880_capture_source,
3377 [ALC880_3ST_DIG] = {
3378 .mixers = { alc880_three_stack_mixer },
3379 .init_verbs = { alc880_volume_init_verbs,
3380 alc880_pin_3stack_init_verbs },
3381 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3382 .dac_nids = alc880_dac_nids,
3383 .dig_out_nid = ALC880_DIGOUT_NID,
3384 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3385 .channel_mode = alc880_threestack_modes,
3387 .input_mux = &alc880_capture_source,
3389 [ALC880_TCL_S700] = {
3390 .mixers = { alc880_tcl_s700_mixer },
3391 .init_verbs = { alc880_volume_init_verbs,
3392 alc880_pin_tcl_S700_init_verbs,
3393 alc880_gpio2_init_verbs },
3394 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3395 .dac_nids = alc880_dac_nids,
3396 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3397 .num_adc_nids = 1, /* single ADC */
3399 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3400 .channel_mode = alc880_2_jack_modes,
3401 .input_mux = &alc880_capture_source,
3404 .mixers = { alc880_three_stack_mixer,
3405 alc880_five_stack_mixer},
3406 .init_verbs = { alc880_volume_init_verbs,
3407 alc880_pin_5stack_init_verbs },
3408 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3409 .dac_nids = alc880_dac_nids,
3410 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3411 .channel_mode = alc880_fivestack_modes,
3412 .input_mux = &alc880_capture_source,
3414 [ALC880_5ST_DIG] = {
3415 .mixers = { alc880_three_stack_mixer,
3416 alc880_five_stack_mixer },
3417 .init_verbs = { alc880_volume_init_verbs,
3418 alc880_pin_5stack_init_verbs },
3419 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3420 .dac_nids = alc880_dac_nids,
3421 .dig_out_nid = ALC880_DIGOUT_NID,
3422 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3423 .channel_mode = alc880_fivestack_modes,
3424 .input_mux = &alc880_capture_source,
3427 .mixers = { alc880_six_stack_mixer },
3428 .init_verbs = { alc880_volume_init_verbs,
3429 alc880_pin_6stack_init_verbs },
3430 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3431 .dac_nids = alc880_6st_dac_nids,
3432 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3433 .channel_mode = alc880_sixstack_modes,
3434 .input_mux = &alc880_6stack_capture_source,
3436 [ALC880_6ST_DIG] = {
3437 .mixers = { alc880_six_stack_mixer },
3438 .init_verbs = { alc880_volume_init_verbs,
3439 alc880_pin_6stack_init_verbs },
3440 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3441 .dac_nids = alc880_6st_dac_nids,
3442 .dig_out_nid = ALC880_DIGOUT_NID,
3443 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3444 .channel_mode = alc880_sixstack_modes,
3445 .input_mux = &alc880_6stack_capture_source,
3448 .mixers = { alc880_w810_base_mixer },
3449 .init_verbs = { alc880_volume_init_verbs,
3450 alc880_pin_w810_init_verbs,
3451 alc880_gpio2_init_verbs },
3452 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3453 .dac_nids = alc880_w810_dac_nids,
3454 .dig_out_nid = ALC880_DIGOUT_NID,
3455 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3456 .channel_mode = alc880_w810_modes,
3457 .input_mux = &alc880_capture_source,
3460 .mixers = { alc880_z71v_mixer },
3461 .init_verbs = { alc880_volume_init_verbs,
3462 alc880_pin_z71v_init_verbs },
3463 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3464 .dac_nids = alc880_z71v_dac_nids,
3465 .dig_out_nid = ALC880_DIGOUT_NID,
3467 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3468 .channel_mode = alc880_2_jack_modes,
3469 .input_mux = &alc880_capture_source,
3472 .mixers = { alc880_f1734_mixer },
3473 .init_verbs = { alc880_volume_init_verbs,
3474 alc880_pin_f1734_init_verbs },
3475 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3476 .dac_nids = alc880_f1734_dac_nids,
3478 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3479 .channel_mode = alc880_2_jack_modes,
3480 .input_mux = &alc880_f1734_capture_source,
3481 .unsol_event = alc880_uniwill_p53_unsol_event,
3482 .init_hook = alc880_uniwill_p53_hp_automute,
3485 .mixers = { alc880_asus_mixer },
3486 .init_verbs = { alc880_volume_init_verbs,
3487 alc880_pin_asus_init_verbs,
3488 alc880_gpio1_init_verbs },
3489 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3490 .dac_nids = alc880_asus_dac_nids,
3491 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3492 .channel_mode = alc880_asus_modes,
3494 .input_mux = &alc880_capture_source,
3496 [ALC880_ASUS_DIG] = {
3497 .mixers = { alc880_asus_mixer },
3498 .init_verbs = { alc880_volume_init_verbs,
3499 alc880_pin_asus_init_verbs,
3500 alc880_gpio1_init_verbs },
3501 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3502 .dac_nids = alc880_asus_dac_nids,
3503 .dig_out_nid = ALC880_DIGOUT_NID,
3504 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3505 .channel_mode = alc880_asus_modes,
3507 .input_mux = &alc880_capture_source,
3509 [ALC880_ASUS_DIG2] = {
3510 .mixers = { alc880_asus_mixer },
3511 .init_verbs = { alc880_volume_init_verbs,
3512 alc880_pin_asus_init_verbs,
3513 alc880_gpio2_init_verbs }, /* use GPIO2 */
3514 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3515 .dac_nids = alc880_asus_dac_nids,
3516 .dig_out_nid = ALC880_DIGOUT_NID,
3517 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3518 .channel_mode = alc880_asus_modes,
3520 .input_mux = &alc880_capture_source,
3522 [ALC880_ASUS_W1V] = {
3523 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3524 .init_verbs = { alc880_volume_init_verbs,
3525 alc880_pin_asus_init_verbs,
3526 alc880_gpio1_init_verbs },
3527 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3528 .dac_nids = alc880_asus_dac_nids,
3529 .dig_out_nid = ALC880_DIGOUT_NID,
3530 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3531 .channel_mode = alc880_asus_modes,
3533 .input_mux = &alc880_capture_source,
3535 [ALC880_UNIWILL_DIG] = {
3536 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3537 .init_verbs = { alc880_volume_init_verbs,
3538 alc880_pin_asus_init_verbs },
3539 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3540 .dac_nids = alc880_asus_dac_nids,
3541 .dig_out_nid = ALC880_DIGOUT_NID,
3542 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3543 .channel_mode = alc880_asus_modes,
3545 .input_mux = &alc880_capture_source,
3547 [ALC880_UNIWILL] = {
3548 .mixers = { alc880_uniwill_mixer },
3549 .init_verbs = { alc880_volume_init_verbs,
3550 alc880_uniwill_init_verbs },
3551 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3552 .dac_nids = alc880_asus_dac_nids,
3553 .dig_out_nid = ALC880_DIGOUT_NID,
3554 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3555 .channel_mode = alc880_threestack_modes,
3557 .input_mux = &alc880_capture_source,
3558 .unsol_event = alc880_uniwill_unsol_event,
3559 .init_hook = alc880_uniwill_automute,
3561 [ALC880_UNIWILL_P53] = {
3562 .mixers = { alc880_uniwill_p53_mixer },
3563 .init_verbs = { alc880_volume_init_verbs,
3564 alc880_uniwill_p53_init_verbs },
3565 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3566 .dac_nids = alc880_asus_dac_nids,
3567 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3568 .channel_mode = alc880_threestack_modes,
3569 .input_mux = &alc880_capture_source,
3570 .unsol_event = alc880_uniwill_p53_unsol_event,
3571 .init_hook = alc880_uniwill_p53_hp_automute,
3573 [ALC880_FUJITSU] = {
3574 .mixers = { alc880_fujitsu_mixer,
3575 alc880_pcbeep_mixer, },
3576 .init_verbs = { alc880_volume_init_verbs,
3577 alc880_uniwill_p53_init_verbs,
3578 alc880_beep_init_verbs },
3579 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3580 .dac_nids = alc880_dac_nids,
3581 .dig_out_nid = ALC880_DIGOUT_NID,
3582 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3583 .channel_mode = alc880_2_jack_modes,
3584 .input_mux = &alc880_capture_source,
3585 .unsol_event = alc880_uniwill_p53_unsol_event,
3586 .init_hook = alc880_uniwill_p53_hp_automute,
3589 .mixers = { alc880_three_stack_mixer },
3590 .init_verbs = { alc880_volume_init_verbs,
3591 alc880_pin_clevo_init_verbs },
3592 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3593 .dac_nids = alc880_dac_nids,
3595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3596 .channel_mode = alc880_threestack_modes,
3598 .input_mux = &alc880_capture_source,
3601 .mixers = { alc880_lg_mixer },
3602 .init_verbs = { alc880_volume_init_verbs,
3603 alc880_lg_init_verbs },
3604 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3605 .dac_nids = alc880_lg_dac_nids,
3606 .dig_out_nid = ALC880_DIGOUT_NID,
3607 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3608 .channel_mode = alc880_lg_ch_modes,
3610 .input_mux = &alc880_lg_capture_source,
3611 .unsol_event = alc880_lg_unsol_event,
3612 .init_hook = alc880_lg_automute,
3613 #ifdef CONFIG_SND_HDA_POWER_SAVE
3614 .loopbacks = alc880_lg_loopbacks,
3618 .mixers = { alc880_lg_lw_mixer },
3619 .init_verbs = { alc880_volume_init_verbs,
3620 alc880_lg_lw_init_verbs },
3621 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3622 .dac_nids = alc880_dac_nids,
3623 .dig_out_nid = ALC880_DIGOUT_NID,
3624 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3625 .channel_mode = alc880_lg_lw_modes,
3626 .input_mux = &alc880_lg_lw_capture_source,
3627 .unsol_event = alc880_lg_lw_unsol_event,
3628 .init_hook = alc880_lg_lw_automute,
3630 [ALC880_MEDION_RIM] = {
3631 .mixers = { alc880_medion_rim_mixer },
3632 .init_verbs = { alc880_volume_init_verbs,
3633 alc880_medion_rim_init_verbs,
3634 alc_gpio2_init_verbs },
3635 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3636 .dac_nids = alc880_dac_nids,
3637 .dig_out_nid = ALC880_DIGOUT_NID,
3638 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3639 .channel_mode = alc880_2_jack_modes,
3640 .input_mux = &alc880_medion_rim_capture_source,
3641 .unsol_event = alc880_medion_rim_unsol_event,
3642 .init_hook = alc880_medion_rim_automute,
3644 #ifdef CONFIG_SND_DEBUG
3646 .mixers = { alc880_test_mixer },
3647 .init_verbs = { alc880_test_init_verbs },
3648 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3649 .dac_nids = alc880_test_dac_nids,
3650 .dig_out_nid = ALC880_DIGOUT_NID,
3651 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3652 .channel_mode = alc880_test_modes,
3653 .input_mux = &alc880_test_capture_source,
3659 * Automatic parse of I/O pins from the BIOS configuration
3664 ALC_CTL_WIDGET_MUTE,
3667 static struct snd_kcontrol_new alc880_control_templates[] = {
3668 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3669 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3670 HDA_BIND_MUTE(NULL, 0, 0, 0),
3673 /* add dynamic controls */
3674 static int add_control(struct alc_spec *spec, int type, const char *name,
3677 struct snd_kcontrol_new *knew;
3679 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3680 knew = snd_array_new(&spec->kctls);
3683 *knew = alc880_control_templates[type];
3684 knew->name = kstrdup(name, GFP_KERNEL);
3687 knew->private_value = val;
3691 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3692 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3693 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3694 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3695 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3696 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3697 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3698 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3699 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3700 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3701 #define ALC880_PIN_CD_NID 0x1c
3703 /* fill in the dac_nids table from the parsed pin configuration */
3704 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3705 const struct auto_pin_cfg *cfg)
3711 memset(assigned, 0, sizeof(assigned));
3712 spec->multiout.dac_nids = spec->private_dac_nids;
3714 /* check the pins hardwired to audio widget */
3715 for (i = 0; i < cfg->line_outs; i++) {
3716 nid = cfg->line_out_pins[i];
3717 if (alc880_is_fixed_pin(nid)) {
3718 int idx = alc880_fixed_pin_idx(nid);
3719 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3723 /* left pins can be connect to any audio widget */
3724 for (i = 0; i < cfg->line_outs; i++) {
3725 nid = cfg->line_out_pins[i];
3726 if (alc880_is_fixed_pin(nid))
3728 /* search for an empty channel */
3729 for (j = 0; j < cfg->line_outs; j++) {
3731 spec->multiout.dac_nids[i] =
3732 alc880_idx_to_dac(j);
3738 spec->multiout.num_dacs = cfg->line_outs;
3742 /* add playback controls from the parsed DAC table */
3743 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3744 const struct auto_pin_cfg *cfg)
3747 static const char *chname[4] = {
3748 "Front", "Surround", NULL /*CLFE*/, "Side"
3753 for (i = 0; i < cfg->line_outs; i++) {
3754 if (!spec->multiout.dac_nids[i])
3756 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3759 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3760 "Center Playback Volume",
3761 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3765 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3766 "LFE Playback Volume",
3767 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3771 err = add_control(spec, ALC_CTL_BIND_MUTE,
3772 "Center Playback Switch",
3773 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3777 err = add_control(spec, ALC_CTL_BIND_MUTE,
3778 "LFE Playback Switch",
3779 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3784 sprintf(name, "%s Playback Volume", chname[i]);
3785 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3786 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3790 sprintf(name, "%s Playback Switch", chname[i]);
3791 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3792 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3801 /* add playback controls for speaker and HP outputs */
3802 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3812 if (alc880_is_fixed_pin(pin)) {
3813 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3814 /* specify the DAC as the extra output */
3815 if (!spec->multiout.hp_nid)
3816 spec->multiout.hp_nid = nid;
3818 spec->multiout.extra_out_nid[0] = nid;
3819 /* control HP volume/switch on the output mixer amp */
3820 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3821 sprintf(name, "%s Playback Volume", pfx);
3822 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3823 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3826 sprintf(name, "%s Playback Switch", pfx);
3827 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3828 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3831 } else if (alc880_is_multi_pin(pin)) {
3832 /* set manual connection */
3833 /* we have only a switch on HP-out PIN */
3834 sprintf(name, "%s Playback Switch", pfx);
3835 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3836 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3843 /* create input playback/capture controls for the given pin */
3844 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3845 const char *ctlname,
3846 int idx, hda_nid_t mix_nid)
3851 sprintf(name, "%s Playback Volume", ctlname);
3852 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3853 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3856 sprintf(name, "%s Playback Switch", ctlname);
3857 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3858 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3864 /* create playback/capture controls for input pins */
3865 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3866 const struct auto_pin_cfg *cfg)
3868 struct hda_input_mux *imux = &spec->private_imux;
3871 for (i = 0; i < AUTO_PIN_LAST; i++) {
3872 if (alc880_is_input_pin(cfg->input_pins[i])) {
3873 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3874 err = new_analog_input(spec, cfg->input_pins[i],
3875 auto_pin_cfg_labels[i],
3879 imux->items[imux->num_items].label =
3880 auto_pin_cfg_labels[i];
3881 imux->items[imux->num_items].index =
3882 alc880_input_pin_idx(cfg->input_pins[i]);
3889 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3890 unsigned int pin_type)
3892 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3895 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3899 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3900 hda_nid_t nid, int pin_type,
3903 alc_set_pin_output(codec, nid, pin_type);
3904 /* need the manual connection? */
3905 if (alc880_is_multi_pin(nid)) {
3906 struct alc_spec *spec = codec->spec;
3907 int idx = alc880_multi_pin_idx(nid);
3908 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3909 AC_VERB_SET_CONNECT_SEL,
3910 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3914 static int get_pin_type(int line_out_type)
3916 if (line_out_type == AUTO_PIN_HP_OUT)
3922 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3924 struct alc_spec *spec = codec->spec;
3927 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3928 for (i = 0; i < spec->autocfg.line_outs; i++) {
3929 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3930 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3931 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3935 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3937 struct alc_spec *spec = codec->spec;
3940 pin = spec->autocfg.speaker_pins[0];
3941 if (pin) /* connect to front */
3942 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3943 pin = spec->autocfg.hp_pins[0];
3944 if (pin) /* connect to front */
3945 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3948 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3950 struct alc_spec *spec = codec->spec;
3953 for (i = 0; i < AUTO_PIN_LAST; i++) {
3954 hda_nid_t nid = spec->autocfg.input_pins[i];
3955 if (alc880_is_input_pin(nid)) {
3956 snd_hda_codec_write(codec, nid, 0,
3957 AC_VERB_SET_PIN_WIDGET_CONTROL,
3958 i <= AUTO_PIN_FRONT_MIC ?
3959 PIN_VREF80 : PIN_IN);
3960 if (nid != ALC880_PIN_CD_NID)
3961 snd_hda_codec_write(codec, nid, 0,
3962 AC_VERB_SET_AMP_GAIN_MUTE,
3968 /* parse the BIOS configuration and set up the alc_spec */
3969 /* return 1 if successful, 0 if the proper config is not found,
3970 * or a negative error code
3972 static int alc880_parse_auto_config(struct hda_codec *codec)
3974 struct alc_spec *spec = codec->spec;
3976 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3978 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3982 if (!spec->autocfg.line_outs)
3983 return 0; /* can't find valid BIOS pin config */
3985 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3988 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3991 err = alc880_auto_create_extra_out(spec,
3992 spec->autocfg.speaker_pins[0],
3996 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4000 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4004 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4006 if (spec->autocfg.dig_out_pin)
4007 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
4008 if (spec->autocfg.dig_in_pin)
4009 spec->dig_in_nid = ALC880_DIGIN_NID;
4011 if (spec->kctls.list)
4012 add_mixer(spec, spec->kctls.list);
4014 add_verb(spec, alc880_volume_init_verbs);
4016 spec->num_mux_defs = 1;
4017 spec->input_mux = &spec->private_imux;
4019 store_pin_configs(codec);
4023 /* additional initialization for auto-configuration model */
4024 static void alc880_auto_init(struct hda_codec *codec)
4026 struct alc_spec *spec = codec->spec;
4027 alc880_auto_init_multi_out(codec);
4028 alc880_auto_init_extra_out(codec);
4029 alc880_auto_init_analog_input(codec);
4030 if (spec->unsol_event)
4031 alc_inithook(codec);
4035 * OK, here we have finally the patch for ALC880
4038 static void set_capture_mixer(struct alc_spec *spec)
4040 static struct snd_kcontrol_new *caps[3] = {
4045 if (spec->num_adc_nids > 0 && spec->num_adc_nids < 3)
4046 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4049 static int patch_alc880(struct hda_codec *codec)
4051 struct alc_spec *spec;
4055 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4061 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4064 if (board_config < 0) {
4065 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
4066 "trying auto-probe from BIOS...\n");
4067 board_config = ALC880_AUTO;
4070 if (board_config == ALC880_AUTO) {
4071 /* automatic parse from the BIOS config */
4072 err = alc880_parse_auto_config(codec);
4078 "hda_codec: Cannot set up configuration "
4079 "from BIOS. Using 3-stack mode...\n");
4080 board_config = ALC880_3ST;
4084 if (board_config != ALC880_AUTO)
4085 setup_preset(spec, &alc880_presets[board_config]);
4087 spec->stream_name_analog = "ALC880 Analog";
4088 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4089 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4090 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4092 spec->stream_name_digital = "ALC880 Digital";
4093 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4094 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4096 if (!spec->adc_nids && spec->input_mux) {
4097 /* check whether NID 0x07 is valid */
4098 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4100 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4101 if (wcap != AC_WID_AUD_IN) {
4102 spec->adc_nids = alc880_adc_nids_alt;
4103 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4105 spec->adc_nids = alc880_adc_nids;
4106 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4109 set_capture_mixer(spec);
4111 spec->vmaster_nid = 0x0c;
4113 codec->patch_ops = alc_patch_ops;
4114 if (board_config == ALC880_AUTO)
4115 spec->init_hook = alc880_auto_init;
4116 #ifdef CONFIG_SND_HDA_POWER_SAVE
4117 if (!spec->loopback.amplist)
4118 spec->loopback.amplist = alc880_loopbacks;
4129 static hda_nid_t alc260_dac_nids[1] = {
4134 static hda_nid_t alc260_adc_nids[1] = {
4139 static hda_nid_t alc260_adc_nids_alt[1] = {
4144 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4145 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4147 static hda_nid_t alc260_dual_adc_nids[2] = {
4152 #define ALC260_DIGOUT_NID 0x03
4153 #define ALC260_DIGIN_NID 0x06
4155 static struct hda_input_mux alc260_capture_source = {
4159 { "Front Mic", 0x1 },
4165 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4166 * headphone jack and the internal CD lines since these are the only pins at
4167 * which audio can appear. For flexibility, also allow the option of
4168 * recording the mixer output on the second ADC (ADC0 doesn't have a
4169 * connection to the mixer output).
4171 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4175 { "Mic/Line", 0x0 },
4177 { "Headphone", 0x2 },
4183 { "Mic/Line", 0x0 },
4185 { "Headphone", 0x2 },
4192 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4193 * the Fujitsu S702x, but jacks are marked differently.
4195 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4202 { "Headphone", 0x5 },
4211 { "Headphone", 0x6 },
4217 * This is just place-holder, so there's something for alc_build_pcms to look
4218 * at when it calculates the maximum number of channels. ALC260 has no mixer
4219 * element which allows changing the channel mode, so the verb list is
4222 static struct hda_channel_mode alc260_modes[1] = {
4227 /* Mixer combinations
4229 * basic: base_output + input + pc_beep + capture
4230 * HP: base_output + input + capture_alt
4231 * HP_3013: hp_3013 + input + capture
4232 * fujitsu: fujitsu + capture
4233 * acer: acer + capture
4236 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4237 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4238 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4239 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4240 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4241 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4242 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4246 static struct snd_kcontrol_new alc260_input_mixer[] = {
4247 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4248 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4249 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4250 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4252 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4253 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4254 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4258 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4259 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4260 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4264 /* update HP, line and mono out pins according to the master switch */
4265 static void alc260_hp_master_update(struct hda_codec *codec,
4266 hda_nid_t hp, hda_nid_t line,
4269 struct alc_spec *spec = codec->spec;
4270 unsigned int val = spec->master_sw ? PIN_HP : 0;
4271 /* change HP and line-out pins */
4272 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4274 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4276 /* mono (speaker) depending on the HP jack sense */
4277 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4278 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4282 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4283 struct snd_ctl_elem_value *ucontrol)
4285 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4286 struct alc_spec *spec = codec->spec;
4287 *ucontrol->value.integer.value = spec->master_sw;
4291 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4292 struct snd_ctl_elem_value *ucontrol)
4294 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4295 struct alc_spec *spec = codec->spec;
4296 int val = !!*ucontrol->value.integer.value;
4297 hda_nid_t hp, line, mono;
4299 if (val == spec->master_sw)
4301 spec->master_sw = val;
4302 hp = (kcontrol->private_value >> 16) & 0xff;
4303 line = (kcontrol->private_value >> 8) & 0xff;
4304 mono = kcontrol->private_value & 0xff;
4305 alc260_hp_master_update(codec, hp, line, mono);
4309 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4312 .name = "Master Playback Switch",
4313 .info = snd_ctl_boolean_mono_info,
4314 .get = alc260_hp_master_sw_get,
4315 .put = alc260_hp_master_sw_put,
4316 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4318 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4319 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4320 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4321 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4322 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4324 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4328 static struct hda_verb alc260_hp_unsol_verbs[] = {
4329 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4333 static void alc260_hp_automute(struct hda_codec *codec)
4335 struct alc_spec *spec = codec->spec;
4336 unsigned int present;
4338 present = snd_hda_codec_read(codec, 0x10, 0,
4339 AC_VERB_GET_PIN_SENSE, 0);
4340 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4341 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4344 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4346 if ((res >> 26) == ALC880_HP_EVENT)
4347 alc260_hp_automute(codec);
4350 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4353 .name = "Master Playback Switch",
4354 .info = snd_ctl_boolean_mono_info,
4355 .get = alc260_hp_master_sw_get,
4356 .put = alc260_hp_master_sw_put,
4357 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4359 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4360 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4361 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4362 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4365 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4366 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4370 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4371 .ops = &snd_hda_bind_vol,
4373 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4374 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4375 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4380 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4381 .ops = &snd_hda_bind_sw,
4383 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4384 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4389 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4390 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4391 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4392 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4393 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4397 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4402 static void alc260_hp_3013_automute(struct hda_codec *codec)
4404 struct alc_spec *spec = codec->spec;
4405 unsigned int present;
4407 present = snd_hda_codec_read(codec, 0x15, 0,
4408 AC_VERB_GET_PIN_SENSE, 0);
4409 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4410 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4413 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4416 if ((res >> 26) == ALC880_HP_EVENT)
4417 alc260_hp_3013_automute(codec);
4420 static void alc260_hp_3012_automute(struct hda_codec *codec)
4422 unsigned int present, bits;
4424 present = snd_hda_codec_read(codec, 0x10, 0,
4425 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4427 bits = present ? 0 : PIN_OUT;
4428 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4430 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4432 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4436 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4439 if ((res >> 26) == ALC880_HP_EVENT)
4440 alc260_hp_3012_automute(codec);
4443 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4444 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4446 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4448 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4449 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4450 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4451 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4452 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4453 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4454 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4455 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4456 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4458 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4462 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4463 * versions of the ALC260 don't act on requests to enable mic bias from NID
4464 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4465 * datasheet doesn't mention this restriction. At this stage it's not clear
4466 * whether this behaviour is intentional or is a hardware bug in chip
4467 * revisions available in early 2006. Therefore for now allow the
4468 * "Headphone Jack Mode" control to span all choices, but if it turns out
4469 * that the lack of mic bias for this NID is intentional we could change the
4470 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4472 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4473 * don't appear to make the mic bias available from the "line" jack, even
4474 * though the NID used for this jack (0x14) can supply it. The theory is
4475 * that perhaps Acer have included blocking capacitors between the ALC260
4476 * and the output jack. If this turns out to be the case for all such
4477 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4478 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4480 * The C20x Tablet series have a mono internal speaker which is controlled
4481 * via the chip's Mono sum widget and pin complex, so include the necessary
4482 * controls for such models. On models without a "mono speaker" the control
4483 * won't do anything.
4485 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4486 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4487 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4488 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4489 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4491 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4493 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4494 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4496 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4497 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4498 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4499 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4500 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4501 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4502 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4506 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4507 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4509 static struct snd_kcontrol_new alc260_will_mixer[] = {
4510 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4511 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4513 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4514 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4515 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4516 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4517 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4518 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4519 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4520 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4521 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4525 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4526 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4528 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4529 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4530 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4532 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4533 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4534 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4535 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4536 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4537 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4538 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4543 * initialization verbs
4545 static struct hda_verb alc260_init_verbs[] = {
4546 /* Line In pin widget for input */
4547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4548 /* CD pin widget for input */
4549 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4550 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4551 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4552 /* Mic2 (front panel) pin widget for input and vref at 80% */
4553 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4554 /* LINE-2 is used for line-out in rear */
4555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4556 /* select line-out */
4557 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4559 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4561 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4563 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4564 /* mute capture amp left and right */
4565 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4566 /* set connection select to line in (default select for this ADC) */
4567 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4568 /* mute capture amp left and right */
4569 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4570 /* set connection select to line in (default select for this ADC) */
4571 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4572 /* set vol=0 Line-Out mixer amp left and right */
4573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4574 /* unmute pin widget amp left and right (no gain on this amp) */
4575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4576 /* set vol=0 HP mixer amp left and right */
4577 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4578 /* unmute pin widget amp left and right (no gain on this amp) */
4579 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4580 /* set vol=0 Mono mixer amp left and right */
4581 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4582 /* unmute pin widget amp left and right (no gain on this amp) */
4583 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4584 /* unmute LINE-2 out pin */
4585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4589 /* mute analog inputs */
4590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4592 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4593 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4594 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4595 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4596 /* mute Front out path */
4597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4598 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4599 /* mute Headphone out path */
4600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4601 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4602 /* mute Mono out path */
4603 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4604 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4608 #if 0 /* should be identical with alc260_init_verbs? */
4609 static struct hda_verb alc260_hp_init_verbs[] = {
4610 /* Headphone and output */
4611 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4613 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4614 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4615 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4616 /* Mic2 (front panel) pin widget for input and vref at 80% */
4617 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4618 /* Line In pin widget for input */
4619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4620 /* Line-2 pin widget for output */
4621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4622 /* CD pin widget for input */
4623 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4624 /* unmute amp left and right */
4625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4626 /* set connection select to line in (default select for this ADC) */
4627 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4628 /* unmute Line-Out mixer amp left and right (volume = 0) */
4629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4630 /* mute pin widget amp left and right (no gain on this amp) */
4631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4632 /* unmute HP mixer amp left and right (volume = 0) */
4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4634 /* mute pin widget amp left and right (no gain on this amp) */
4635 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4636 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4639 /* mute analog inputs */
4640 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4641 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4645 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4646 /* Unmute Front out path */
4647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4648 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4649 /* Unmute Headphone out path */
4650 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4651 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4652 /* Unmute Mono out path */
4653 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4654 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4659 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4660 /* Line out and output */
4661 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4663 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4664 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4665 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4666 /* Mic2 (front panel) pin widget for input and vref at 80% */
4667 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4668 /* Line In pin widget for input */
4669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4670 /* Headphone pin widget for output */
4671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4672 /* CD pin widget for input */
4673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4674 /* unmute amp left and right */
4675 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4676 /* set connection select to line in (default select for this ADC) */
4677 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4678 /* unmute Line-Out mixer amp left and right (volume = 0) */
4679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4680 /* mute pin widget amp left and right (no gain on this amp) */
4681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4682 /* unmute HP mixer amp left and right (volume = 0) */
4683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4684 /* mute pin widget amp left and right (no gain on this amp) */
4685 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4686 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4689 /* mute analog inputs */
4690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4695 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4696 /* Unmute Front out path */
4697 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4699 /* Unmute Headphone out path */
4700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4701 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4702 /* Unmute Mono out path */
4703 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4704 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4708 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4709 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4710 * audio = 0x16, internal speaker = 0x10.
4712 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4713 /* Disable all GPIOs */
4714 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4715 /* Internal speaker is connected to headphone pin */
4716 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4717 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4719 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4720 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4721 /* Ensure all other unused pins are disabled and muted. */
4722 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4723 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4724 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4725 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4726 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4727 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4731 /* Disable digital (SPDIF) pins */
4732 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4733 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4735 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4736 * when acting as an output.
4738 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4740 /* Start with output sum widgets muted and their output gains at min */
4741 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4742 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4743 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4744 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4745 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4746 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4747 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4748 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4749 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4751 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4752 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4753 /* Unmute Line1 pin widget output buffer since it starts as an output.
4754 * If the pin mode is changed by the user the pin mode control will
4755 * take care of enabling the pin's input/output buffers as needed.
4756 * Therefore there's no need to enable the input buffer at this
4759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4760 /* Unmute input buffer of pin widget used for Line-in (no equiv
4763 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4765 /* Mute capture amp left and right */
4766 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4767 /* Set ADC connection select to match default mixer setting - line
4770 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4772 /* Do the same for the second ADC: mute capture input amp and
4773 * set ADC connection to line in (on mic1 pin)
4775 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4776 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4778 /* Mute all inputs to mixer widget (even unconnected ones) */
4779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4785 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4791 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4792 * similar laptops (adapted from Fujitsu init verbs).
4794 static struct hda_verb alc260_acer_init_verbs[] = {
4795 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4796 * the headphone jack. Turn this on and rely on the standard mute
4797 * methods whenever the user wants to turn these outputs off.
4799 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4800 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4801 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4802 /* Internal speaker/Headphone jack is connected to Line-out pin */
4803 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4804 /* Internal microphone/Mic jack is connected to Mic1 pin */
4805 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4806 /* Line In jack is connected to Line1 pin */
4807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4808 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4809 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4810 /* Ensure all other unused pins are disabled and muted. */
4811 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4812 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4813 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4814 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4817 /* Disable digital (SPDIF) pins */
4818 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4819 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4821 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4822 * bus when acting as outputs.
4824 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4825 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4827 /* Start with output sum widgets muted and their output gains at min */
4828 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4833 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4834 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4835 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4836 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4838 /* Unmute Line-out pin widget amp left and right
4839 * (no equiv mixer ctrl)
4841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4842 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4843 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4844 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4845 * inputs. If the pin mode is changed by the user the pin mode control
4846 * will take care of enabling the pin's input/output buffers as needed.
4847 * Therefore there's no need to enable the input buffer at this
4850 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4853 /* Mute capture amp left and right */
4854 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4855 /* Set ADC connection select to match default mixer setting - mic
4858 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4860 /* Do similar with the second ADC: mute capture input amp and
4861 * set ADC connection to mic to match ALSA's default state.
4863 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4864 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4866 /* Mute all inputs to mixer widget (even unconnected ones) */
4867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4879 static struct hda_verb alc260_will_verbs[] = {
4880 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4881 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4882 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4883 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4884 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4885 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4889 static struct hda_verb alc260_replacer_672v_verbs[] = {
4890 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4891 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4892 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4894 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4895 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4896 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4898 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4902 /* toggle speaker-output according to the hp-jack state */
4903 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4905 unsigned int present;
4907 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4908 present = snd_hda_codec_read(codec, 0x0f, 0,
4909 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4911 snd_hda_codec_write_cache(codec, 0x01, 0,
4912 AC_VERB_SET_GPIO_DATA, 1);
4913 snd_hda_codec_write_cache(codec, 0x0f, 0,
4914 AC_VERB_SET_PIN_WIDGET_CONTROL,
4917 snd_hda_codec_write_cache(codec, 0x01, 0,
4918 AC_VERB_SET_GPIO_DATA, 0);
4919 snd_hda_codec_write_cache(codec, 0x0f, 0,
4920 AC_VERB_SET_PIN_WIDGET_CONTROL,
4925 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4928 if ((res >> 26) == ALC880_HP_EVENT)
4929 alc260_replacer_672v_automute(codec);
4932 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4933 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4934 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4935 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4937 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4938 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4939 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4940 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4941 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4946 /* Test configuration for debugging, modelled after the ALC880 test
4949 #ifdef CONFIG_SND_DEBUG
4950 static hda_nid_t alc260_test_dac_nids[1] = {
4953 static hda_nid_t alc260_test_adc_nids[2] = {
4956 /* For testing the ALC260, each input MUX needs its own definition since
4957 * the signal assignments are different. This assumes that the first ADC
4960 static struct hda_input_mux alc260_test_capture_sources[2] = {
4964 { "MIC1 pin", 0x0 },
4965 { "MIC2 pin", 0x1 },
4966 { "LINE1 pin", 0x2 },
4967 { "LINE2 pin", 0x3 },
4969 { "LINE-OUT pin", 0x5 },
4970 { "HP-OUT pin", 0x6 },
4976 { "MIC1 pin", 0x0 },
4977 { "MIC2 pin", 0x1 },
4978 { "LINE1 pin", 0x2 },
4979 { "LINE2 pin", 0x3 },
4982 { "LINE-OUT pin", 0x6 },
4983 { "HP-OUT pin", 0x7 },
4987 static struct snd_kcontrol_new alc260_test_mixer[] = {
4988 /* Output driver widgets */
4989 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4990 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4991 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4992 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4993 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4994 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4996 /* Modes for retasking pin widgets
4997 * Note: the ALC260 doesn't seem to act on requests to enable mic
4998 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4999 * mention this restriction. At this stage it's not clear whether
5000 * this behaviour is intentional or is a hardware bug in chip
5001 * revisions available at least up until early 2006. Therefore for
5002 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5003 * choices, but if it turns out that the lack of mic bias for these
5004 * NIDs is intentional we could change their modes from
5005 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5007 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5008 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5009 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5010 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5011 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5012 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5014 /* Loopback mixer controls */
5015 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5016 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5017 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5018 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5019 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5020 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5021 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5022 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5023 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5024 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5025 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
5026 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
5027 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5028 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5029 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5030 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5032 /* Controls for GPIO pins, assuming they are configured as outputs */
5033 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5034 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5035 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5036 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5038 /* Switches to allow the digital IO pins to be enabled. The datasheet
5039 * is ambigious as to which NID is which; testing on laptops which
5040 * make this output available should provide clarification.
5042 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5043 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5045 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5046 * this output to turn on an external amplifier.
5048 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5049 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5053 static struct hda_verb alc260_test_init_verbs[] = {
5054 /* Enable all GPIOs as outputs with an initial value of 0 */
5055 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5056 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5057 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5059 /* Enable retasking pins as output, initially without power amp */
5060 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5061 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5064 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5065 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5067 /* Disable digital (SPDIF) pins initially, but users can enable
5068 * them via a mixer switch. In the case of SPDIF-out, this initverb
5069 * payload also sets the generation to 0, output to be in "consumer"
5070 * PCM format, copyright asserted, no pre-emphasis and no validity
5073 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5074 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5076 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5077 * OUT1 sum bus when acting as an output.
5079 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5080 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5081 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5082 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5084 /* Start with output sum widgets muted and their output gains at min */
5085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5086 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5091 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5092 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5093 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5095 /* Unmute retasking pin widget output buffers since the default
5096 * state appears to be output. As the pin mode is changed by the
5097 * user the pin mode control will take care of enabling the pin's
5098 * input/output buffers as needed.
5100 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5101 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5103 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5104 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5105 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5106 /* Also unmute the mono-out pin widget */
5107 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5109 /* Mute capture amp left and right */
5110 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5111 /* Set ADC connection select to match default mixer setting (mic1
5114 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5116 /* Do the same for the second ADC: mute capture input amp and
5117 * set ADC connection to mic1 pin
5119 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5120 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5122 /* Mute all inputs to mixer widget (even unconnected ones) */
5123 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5124 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5125 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5126 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5128 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5136 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5137 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5139 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5140 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5143 * for BIOS auto-configuration
5146 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5147 const char *pfx, int *vol_bits)
5150 unsigned long vol_val, sw_val;
5154 if (nid >= 0x0f && nid < 0x11) {
5155 nid_vol = nid - 0x7;
5156 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5157 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5158 } else if (nid == 0x11) {
5159 nid_vol = nid - 0x7;
5160 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5161 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5162 } else if (nid >= 0x12 && nid <= 0x15) {
5164 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5165 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5169 if (!(*vol_bits & (1 << nid_vol))) {
5170 /* first control for the volume widget */
5171 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5172 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5175 *vol_bits |= (1 << nid_vol);
5177 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5178 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5184 /* add playback controls from the parsed DAC table */
5185 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5186 const struct auto_pin_cfg *cfg)
5192 spec->multiout.num_dacs = 1;
5193 spec->multiout.dac_nids = spec->private_dac_nids;
5194 spec->multiout.dac_nids[0] = 0x02;
5196 nid = cfg->line_out_pins[0];
5198 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5203 nid = cfg->speaker_pins[0];
5205 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5210 nid = cfg->hp_pins[0];
5212 err = alc260_add_playback_controls(spec, nid, "Headphone",
5220 /* create playback/capture controls for input pins */
5221 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5222 const struct auto_pin_cfg *cfg)
5224 struct hda_input_mux *imux = &spec->private_imux;
5227 for (i = 0; i < AUTO_PIN_LAST; i++) {
5228 if (cfg->input_pins[i] >= 0x12) {
5229 idx = cfg->input_pins[i] - 0x12;
5230 err = new_analog_input(spec, cfg->input_pins[i],
5231 auto_pin_cfg_labels[i], idx,
5235 imux->items[imux->num_items].label =
5236 auto_pin_cfg_labels[i];
5237 imux->items[imux->num_items].index = idx;
5240 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5241 idx = cfg->input_pins[i] - 0x09;
5242 err = new_analog_input(spec, cfg->input_pins[i],
5243 auto_pin_cfg_labels[i], idx,
5247 imux->items[imux->num_items].label =
5248 auto_pin_cfg_labels[i];
5249 imux->items[imux->num_items].index = idx;
5256 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5257 hda_nid_t nid, int pin_type,
5260 alc_set_pin_output(codec, nid, pin_type);
5261 /* need the manual connection? */
5263 int idx = nid - 0x12;
5264 snd_hda_codec_write(codec, idx + 0x0b, 0,
5265 AC_VERB_SET_CONNECT_SEL, sel_idx);
5269 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5271 struct alc_spec *spec = codec->spec;
5274 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5275 nid = spec->autocfg.line_out_pins[0];
5277 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5278 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5281 nid = spec->autocfg.speaker_pins[0];
5283 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5285 nid = spec->autocfg.hp_pins[0];
5287 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5290 #define ALC260_PIN_CD_NID 0x16
5291 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5293 struct alc_spec *spec = codec->spec;
5296 for (i = 0; i < AUTO_PIN_LAST; i++) {
5297 hda_nid_t nid = spec->autocfg.input_pins[i];
5299 snd_hda_codec_write(codec, nid, 0,
5300 AC_VERB_SET_PIN_WIDGET_CONTROL,
5301 i <= AUTO_PIN_FRONT_MIC ?
5302 PIN_VREF80 : PIN_IN);
5303 if (nid != ALC260_PIN_CD_NID)
5304 snd_hda_codec_write(codec, nid, 0,
5305 AC_VERB_SET_AMP_GAIN_MUTE,
5312 * generic initialization of ADC, input mixers and output mixers
5314 static struct hda_verb alc260_volume_init_verbs[] = {
5316 * Unmute ADC0-1 and set the default input to mic-in
5318 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5319 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5320 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5321 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5323 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5325 * Note: PASD motherboards uses the Line In 2 as the input for
5326 * front panel mic (mic 2)
5328 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5329 /* mute analog inputs */
5330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5337 * Set up output mixers (0x08 - 0x0a)
5339 /* set vol=0 to output mixers */
5340 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5342 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5343 /* set up input amps for analog loopback */
5344 /* Amp Indices: DAC = 0, mixer = 1 */
5345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5346 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5347 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5348 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5349 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5350 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5355 static int alc260_parse_auto_config(struct hda_codec *codec)
5357 struct alc_spec *spec = codec->spec;
5359 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5365 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5368 if (!spec->kctls.list)
5369 return 0; /* can't find valid BIOS pin config */
5370 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5374 spec->multiout.max_channels = 2;
5376 if (spec->autocfg.dig_out_pin)
5377 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5378 if (spec->kctls.list)
5379 add_mixer(spec, spec->kctls.list);
5381 add_verb(spec, alc260_volume_init_verbs);
5383 spec->num_mux_defs = 1;
5384 spec->input_mux = &spec->private_imux;
5386 store_pin_configs(codec);
5390 /* additional initialization for auto-configuration model */
5391 static void alc260_auto_init(struct hda_codec *codec)
5393 struct alc_spec *spec = codec->spec;
5394 alc260_auto_init_multi_out(codec);
5395 alc260_auto_init_analog_input(codec);
5396 if (spec->unsol_event)
5397 alc_inithook(codec);
5400 #ifdef CONFIG_SND_HDA_POWER_SAVE
5401 static struct hda_amp_list alc260_loopbacks[] = {
5402 { 0x07, HDA_INPUT, 0 },
5403 { 0x07, HDA_INPUT, 1 },
5404 { 0x07, HDA_INPUT, 2 },
5405 { 0x07, HDA_INPUT, 3 },
5406 { 0x07, HDA_INPUT, 4 },
5412 * ALC260 configurations
5414 static const char *alc260_models[ALC260_MODEL_LAST] = {
5415 [ALC260_BASIC] = "basic",
5417 [ALC260_HP_3013] = "hp-3013",
5418 [ALC260_HP_DC7600] = "hp-dc7600",
5419 [ALC260_FUJITSU_S702X] = "fujitsu",
5420 [ALC260_ACER] = "acer",
5421 [ALC260_WILL] = "will",
5422 [ALC260_REPLACER_672V] = "replacer",
5423 #ifdef CONFIG_SND_DEBUG
5424 [ALC260_TEST] = "test",
5426 [ALC260_AUTO] = "auto",
5429 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5430 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5431 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5432 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5433 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5434 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5435 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5436 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5437 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5438 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5439 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5440 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5441 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5442 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5443 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5444 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5445 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5446 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5447 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5451 static struct alc_config_preset alc260_presets[] = {
5453 .mixers = { alc260_base_output_mixer,
5455 alc260_pc_beep_mixer },
5456 .init_verbs = { alc260_init_verbs },
5457 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5458 .dac_nids = alc260_dac_nids,
5459 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5460 .adc_nids = alc260_adc_nids,
5461 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5462 .channel_mode = alc260_modes,
5463 .input_mux = &alc260_capture_source,
5466 .mixers = { alc260_hp_output_mixer,
5467 alc260_input_mixer },
5468 .init_verbs = { alc260_init_verbs,
5469 alc260_hp_unsol_verbs },
5470 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5471 .dac_nids = alc260_dac_nids,
5472 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5473 .adc_nids = alc260_adc_nids_alt,
5474 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5475 .channel_mode = alc260_modes,
5476 .input_mux = &alc260_capture_source,
5477 .unsol_event = alc260_hp_unsol_event,
5478 .init_hook = alc260_hp_automute,
5480 [ALC260_HP_DC7600] = {
5481 .mixers = { alc260_hp_dc7600_mixer,
5482 alc260_input_mixer },
5483 .init_verbs = { alc260_init_verbs,
5484 alc260_hp_dc7600_verbs },
5485 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5486 .dac_nids = alc260_dac_nids,
5487 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5488 .adc_nids = alc260_adc_nids_alt,
5489 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5490 .channel_mode = alc260_modes,
5491 .input_mux = &alc260_capture_source,
5492 .unsol_event = alc260_hp_3012_unsol_event,
5493 .init_hook = alc260_hp_3012_automute,
5495 [ALC260_HP_3013] = {
5496 .mixers = { alc260_hp_3013_mixer,
5497 alc260_input_mixer },
5498 .init_verbs = { alc260_hp_3013_init_verbs,
5499 alc260_hp_3013_unsol_verbs },
5500 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5501 .dac_nids = alc260_dac_nids,
5502 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5503 .adc_nids = alc260_adc_nids_alt,
5504 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5505 .channel_mode = alc260_modes,
5506 .input_mux = &alc260_capture_source,
5507 .unsol_event = alc260_hp_3013_unsol_event,
5508 .init_hook = alc260_hp_3013_automute,
5510 [ALC260_FUJITSU_S702X] = {
5511 .mixers = { alc260_fujitsu_mixer },
5512 .init_verbs = { alc260_fujitsu_init_verbs },
5513 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5514 .dac_nids = alc260_dac_nids,
5515 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5516 .adc_nids = alc260_dual_adc_nids,
5517 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5518 .channel_mode = alc260_modes,
5519 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5520 .input_mux = alc260_fujitsu_capture_sources,
5523 .mixers = { alc260_acer_mixer },
5524 .init_verbs = { alc260_acer_init_verbs },
5525 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5526 .dac_nids = alc260_dac_nids,
5527 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5528 .adc_nids = alc260_dual_adc_nids,
5529 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5530 .channel_mode = alc260_modes,
5531 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5532 .input_mux = alc260_acer_capture_sources,
5535 .mixers = { alc260_will_mixer },
5536 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5537 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5538 .dac_nids = alc260_dac_nids,
5539 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5540 .adc_nids = alc260_adc_nids,
5541 .dig_out_nid = ALC260_DIGOUT_NID,
5542 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5543 .channel_mode = alc260_modes,
5544 .input_mux = &alc260_capture_source,
5546 [ALC260_REPLACER_672V] = {
5547 .mixers = { alc260_replacer_672v_mixer },
5548 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5549 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5550 .dac_nids = alc260_dac_nids,
5551 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5552 .adc_nids = alc260_adc_nids,
5553 .dig_out_nid = ALC260_DIGOUT_NID,
5554 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5555 .channel_mode = alc260_modes,
5556 .input_mux = &alc260_capture_source,
5557 .unsol_event = alc260_replacer_672v_unsol_event,
5558 .init_hook = alc260_replacer_672v_automute,
5560 #ifdef CONFIG_SND_DEBUG
5562 .mixers = { alc260_test_mixer },
5563 .init_verbs = { alc260_test_init_verbs },
5564 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5565 .dac_nids = alc260_test_dac_nids,
5566 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5567 .adc_nids = alc260_test_adc_nids,
5568 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5569 .channel_mode = alc260_modes,
5570 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5571 .input_mux = alc260_test_capture_sources,
5576 static int patch_alc260(struct hda_codec *codec)
5578 struct alc_spec *spec;
5579 int err, board_config;
5581 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5587 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5590 if (board_config < 0) {
5591 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5592 "trying auto-probe from BIOS...\n");
5593 board_config = ALC260_AUTO;
5596 if (board_config == ALC260_AUTO) {
5597 /* automatic parse from the BIOS config */
5598 err = alc260_parse_auto_config(codec);
5604 "hda_codec: Cannot set up configuration "
5605 "from BIOS. Using base mode...\n");
5606 board_config = ALC260_BASIC;
5610 if (board_config != ALC260_AUTO)
5611 setup_preset(spec, &alc260_presets[board_config]);
5613 spec->stream_name_analog = "ALC260 Analog";
5614 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5615 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5617 spec->stream_name_digital = "ALC260 Digital";
5618 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5619 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5621 set_capture_mixer(spec);
5623 spec->vmaster_nid = 0x08;
5625 codec->patch_ops = alc_patch_ops;
5626 if (board_config == ALC260_AUTO)
5627 spec->init_hook = alc260_auto_init;
5628 #ifdef CONFIG_SND_HDA_POWER_SAVE
5629 if (!spec->loopback.amplist)
5630 spec->loopback.amplist = alc260_loopbacks;
5640 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5641 * configuration. Each pin widget can choose any input DACs and a mixer.
5642 * Each ADC is connected from a mixer of all inputs. This makes possible
5643 * 6-channel independent captures.
5645 * In addition, an independent DAC for the multi-playback (not used in this
5648 #define ALC882_DIGOUT_NID 0x06
5649 #define ALC882_DIGIN_NID 0x0a
5651 static struct hda_channel_mode alc882_ch_modes[1] = {
5655 static hda_nid_t alc882_dac_nids[4] = {
5656 /* front, rear, clfe, rear_surr */
5657 0x02, 0x03, 0x04, 0x05
5660 /* identical with ALC880 */
5661 #define alc882_adc_nids alc880_adc_nids
5662 #define alc882_adc_nids_alt alc880_adc_nids_alt
5664 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5665 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5668 /* FIXME: should be a matrix-type input source selection */
5670 static struct hda_input_mux alc882_capture_source = {
5674 { "Front Mic", 0x1 },
5682 static struct hda_verb alc882_3ST_ch2_init[] = {
5683 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5684 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5685 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5686 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5693 static struct hda_verb alc882_3ST_ch6_init[] = {
5694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5696 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5697 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5699 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5703 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5704 { 2, alc882_3ST_ch2_init },
5705 { 6, alc882_3ST_ch6_init },
5711 static struct hda_verb alc882_sixstack_ch6_init[] = {
5712 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5713 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5714 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5715 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5722 static struct hda_verb alc882_sixstack_ch8_init[] = {
5723 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5724 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5725 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5726 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5730 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5731 { 6, alc882_sixstack_ch6_init },
5732 { 8, alc882_sixstack_ch8_init },
5736 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5742 static struct hda_verb alc885_mbp_ch2_init[] = {
5743 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5744 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5745 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5752 static struct hda_verb alc885_mbp_ch6_init[] = {
5753 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5754 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5755 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5756 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5757 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5761 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5762 { 2, alc885_mbp_ch2_init },
5763 { 6, alc885_mbp_ch6_init },
5767 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5768 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5770 static struct snd_kcontrol_new alc882_base_mixer[] = {
5771 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5772 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5773 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5774 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5775 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5776 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5777 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5778 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5779 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5780 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5784 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5785 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5787 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5789 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5790 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5791 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5792 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5793 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5797 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5798 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5799 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5800 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5801 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5802 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5803 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5804 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5805 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5806 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5807 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5810 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5812 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5813 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5814 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5815 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5816 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5817 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5819 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5820 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5821 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5825 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5826 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5827 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5828 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5831 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5832 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5835 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5836 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5838 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5842 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5843 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5845 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5847 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5849 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5850 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5851 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5852 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5853 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5854 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5855 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5858 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5862 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5864 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5868 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5869 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5873 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5874 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5878 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5880 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5881 .name = "Channel Mode",
5882 .info = alc_ch_mode_info,
5883 .get = alc_ch_mode_get,
5884 .put = alc_ch_mode_put,
5889 static struct hda_verb alc882_init_verbs[] = {
5890 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5896 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5897 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5899 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5901 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5903 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5904 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5905 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5907 /* Front Pin: output 0 (0x0c) */
5908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5910 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5911 /* Rear Pin: output 1 (0x0d) */
5912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5913 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5914 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5915 /* CLFE Pin: output 2 (0x0e) */
5916 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5917 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5918 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5919 /* Side Pin: output 3 (0x0f) */
5920 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5921 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5922 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5923 /* Mic (rear) pin: input vref at 80% */
5924 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5925 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5926 /* Front Mic pin: input vref at 80% */
5927 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5928 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5929 /* Line In pin: input */
5930 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5932 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5934 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5935 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5936 /* CD pin widget for input */
5937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5939 /* FIXME: use matrix-type input source selection */
5940 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5941 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5942 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5943 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5944 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5945 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5948 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5950 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5952 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5956 /* ADC1: mute amp left and right */
5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5958 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5959 /* ADC2: mute amp left and right */
5960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5961 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5962 /* ADC3: mute amp left and right */
5963 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5964 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5969 static struct hda_verb alc882_eapd_verbs[] = {
5970 /* change to EAPD mode */
5971 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5972 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5977 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5978 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5979 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5982 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5983 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5984 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5988 static struct hda_verb alc882_macpro_init_verbs[] = {
5989 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5992 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5993 /* Front Pin: output 0 (0x0c) */
5994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5996 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5997 /* Front Mic pin: input vref at 80% */
5998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6000 /* Speaker: output */
6001 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6003 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6004 /* Headphone output (output 0 - 0x0c) */
6005 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6007 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6009 /* FIXME: use matrix-type input source selection */
6010 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6011 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6026 /* ADC1: mute amp left and right */
6027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6028 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6029 /* ADC2: mute amp left and right */
6030 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6031 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6032 /* ADC3: mute amp left and right */
6033 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6034 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6039 /* Macbook Pro rev3 */
6040 static struct hda_verb alc885_mbp3_init_verbs[] = {
6041 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6046 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6047 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6049 /* Front Pin: output 0 (0x0c) */
6050 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6051 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6052 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6053 /* HP Pin: output 0 (0x0d) */
6054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6057 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6058 /* Mic (rear) pin: input vref at 80% */
6059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6061 /* Front Mic pin: input vref at 80% */
6062 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6063 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6064 /* Line In pin: use output 1 when in LineOut mode */
6065 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6066 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6067 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6069 /* FIXME: use matrix-type input source selection */
6070 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6071 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6078 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6079 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6080 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6086 /* ADC1: mute amp left and right */
6087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6088 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6089 /* ADC2: mute amp left and right */
6090 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6091 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6092 /* ADC3: mute amp left and right */
6093 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6094 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6099 /* iMac 24 mixer. */
6100 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6101 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6102 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6106 /* iMac 24 init verbs. */
6107 static struct hda_verb alc885_imac24_init_verbs[] = {
6108 /* Internal speakers: output 0 (0x0c) */
6109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6111 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6112 /* Internal speakers: output 0 (0x0c) */
6113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6115 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6116 /* Headphone: output 0 (0x0c) */
6117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6119 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6120 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6121 /* Front Mic: input vref at 80% */
6122 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6127 /* Toggle speaker-output according to the hp-jack state */
6128 static void alc885_imac24_automute(struct hda_codec *codec)
6130 unsigned int present;
6132 present = snd_hda_codec_read(codec, 0x14, 0,
6133 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6134 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6135 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6136 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6137 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6140 /* Processes unsolicited events. */
6141 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6144 /* Headphone insertion or removal. */
6145 if ((res >> 26) == ALC880_HP_EVENT)
6146 alc885_imac24_automute(codec);
6149 static void alc885_mbp3_automute(struct hda_codec *codec)
6151 unsigned int present;
6153 present = snd_hda_codec_read(codec, 0x15, 0,
6154 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6155 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6156 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6157 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6158 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6161 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6164 /* Headphone insertion or removal. */
6165 if ((res >> 26) == ALC880_HP_EVENT)
6166 alc885_mbp3_automute(codec);
6170 static struct hda_verb alc882_targa_verbs[] = {
6171 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6174 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6177 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6179 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6182 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6183 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6184 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6188 /* toggle speaker-output according to the hp-jack state */
6189 static void alc882_targa_automute(struct hda_codec *codec)
6191 unsigned int present;
6193 present = snd_hda_codec_read(codec, 0x14, 0,
6194 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6195 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6196 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6197 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6201 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6203 /* Looks like the unsol event is incompatible with the standard
6204 * definition. 4bit tag is placed at 26 bit!
6206 if (((res >> 26) == ALC880_HP_EVENT)) {
6207 alc882_targa_automute(codec);
6211 static struct hda_verb alc882_asus_a7j_verbs[] = {
6212 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6215 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6217 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6219 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6221 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6223 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6224 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6229 static struct hda_verb alc882_asus_a7m_verbs[] = {
6230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6233 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6235 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6237 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6239 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6241 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6242 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6243 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6247 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6249 unsigned int gpiostate, gpiomask, gpiodir;
6251 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6252 AC_VERB_GET_GPIO_DATA, 0);
6255 gpiostate |= (1 << pin);
6257 gpiostate &= ~(1 << pin);
6259 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6260 AC_VERB_GET_GPIO_MASK, 0);
6261 gpiomask |= (1 << pin);
6263 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6264 AC_VERB_GET_GPIO_DIRECTION, 0);
6265 gpiodir |= (1 << pin);
6268 snd_hda_codec_write(codec, codec->afg, 0,
6269 AC_VERB_SET_GPIO_MASK, gpiomask);
6270 snd_hda_codec_write(codec, codec->afg, 0,
6271 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6275 snd_hda_codec_write(codec, codec->afg, 0,
6276 AC_VERB_SET_GPIO_DATA, gpiostate);
6279 /* set up GPIO at initialization */
6280 static void alc885_macpro_init_hook(struct hda_codec *codec)
6282 alc882_gpio_mute(codec, 0, 0);
6283 alc882_gpio_mute(codec, 1, 0);
6286 /* set up GPIO and update auto-muting at initialization */
6287 static void alc885_imac24_init_hook(struct hda_codec *codec)
6289 alc885_macpro_init_hook(codec);
6290 alc885_imac24_automute(codec);
6294 * generic initialization of ADC, input mixers and output mixers
6296 static struct hda_verb alc882_auto_init_verbs[] = {
6298 * Unmute ADC0-2 and set the default input to mic-in
6300 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6301 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6302 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6304 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6307 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6309 * Note: PASD motherboards uses the Line In 2 as the input for
6310 * front panel mic (mic 2)
6312 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6313 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6314 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6315 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6316 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6317 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6320 * Set up output mixers (0x0c - 0x0f)
6322 /* set vol=0 to output mixers */
6323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6324 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6325 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6326 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6327 /* set up input amps for analog loopback */
6328 /* Amp Indices: DAC = 0, mixer = 1 */
6329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6332 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6335 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6336 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6337 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6338 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6340 /* FIXME: use matrix-type input source selection */
6341 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6342 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6343 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6345 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6348 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6349 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6350 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6351 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6353 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6354 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6355 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6356 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6361 #ifdef CONFIG_SND_HDA_POWER_SAVE
6362 #define alc882_loopbacks alc880_loopbacks
6365 /* pcm configuration: identiacal with ALC880 */
6366 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6367 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6368 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6369 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6372 * configuration and preset
6374 static const char *alc882_models[ALC882_MODEL_LAST] = {
6375 [ALC882_3ST_DIG] = "3stack-dig",
6376 [ALC882_6ST_DIG] = "6stack-dig",
6377 [ALC882_ARIMA] = "arima",
6378 [ALC882_W2JC] = "w2jc",
6379 [ALC882_TARGA] = "targa",
6380 [ALC882_ASUS_A7J] = "asus-a7j",
6381 [ALC882_ASUS_A7M] = "asus-a7m",
6382 [ALC885_MACPRO] = "macpro",
6383 [ALC885_MBP3] = "mbp3",
6384 [ALC885_IMAC24] = "imac24",
6385 [ALC882_AUTO] = "auto",
6388 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6389 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6390 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6391 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6392 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6393 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6394 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6395 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6396 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6397 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6398 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6399 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6400 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6404 static struct alc_config_preset alc882_presets[] = {
6405 [ALC882_3ST_DIG] = {
6406 .mixers = { alc882_base_mixer },
6407 .init_verbs = { alc882_init_verbs },
6408 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6409 .dac_nids = alc882_dac_nids,
6410 .dig_out_nid = ALC882_DIGOUT_NID,
6411 .dig_in_nid = ALC882_DIGIN_NID,
6412 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6413 .channel_mode = alc882_ch_modes,
6415 .input_mux = &alc882_capture_source,
6417 [ALC882_6ST_DIG] = {
6418 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6419 .init_verbs = { alc882_init_verbs },
6420 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6421 .dac_nids = alc882_dac_nids,
6422 .dig_out_nid = ALC882_DIGOUT_NID,
6423 .dig_in_nid = ALC882_DIGIN_NID,
6424 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6425 .channel_mode = alc882_sixstack_modes,
6426 .input_mux = &alc882_capture_source,
6429 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6430 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6431 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6432 .dac_nids = alc882_dac_nids,
6433 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6434 .channel_mode = alc882_sixstack_modes,
6435 .input_mux = &alc882_capture_source,
6438 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6439 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6440 alc880_gpio1_init_verbs },
6441 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6442 .dac_nids = alc882_dac_nids,
6443 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6444 .channel_mode = alc880_threestack_modes,
6446 .input_mux = &alc882_capture_source,
6447 .dig_out_nid = ALC882_DIGOUT_NID,
6450 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6451 .init_verbs = { alc885_mbp3_init_verbs,
6452 alc880_gpio1_init_verbs },
6453 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6454 .dac_nids = alc882_dac_nids,
6455 .channel_mode = alc885_mbp_6ch_modes,
6456 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6457 .input_mux = &alc882_capture_source,
6458 .dig_out_nid = ALC882_DIGOUT_NID,
6459 .dig_in_nid = ALC882_DIGIN_NID,
6460 .unsol_event = alc885_mbp3_unsol_event,
6461 .init_hook = alc885_mbp3_automute,
6464 .mixers = { alc882_macpro_mixer },
6465 .init_verbs = { alc882_macpro_init_verbs },
6466 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6467 .dac_nids = alc882_dac_nids,
6468 .dig_out_nid = ALC882_DIGOUT_NID,
6469 .dig_in_nid = ALC882_DIGIN_NID,
6470 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6471 .channel_mode = alc882_ch_modes,
6472 .input_mux = &alc882_capture_source,
6473 .init_hook = alc885_macpro_init_hook,
6476 .mixers = { alc885_imac24_mixer },
6477 .init_verbs = { alc885_imac24_init_verbs },
6478 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6479 .dac_nids = alc882_dac_nids,
6480 .dig_out_nid = ALC882_DIGOUT_NID,
6481 .dig_in_nid = ALC882_DIGIN_NID,
6482 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6483 .channel_mode = alc882_ch_modes,
6484 .input_mux = &alc882_capture_source,
6485 .unsol_event = alc885_imac24_unsol_event,
6486 .init_hook = alc885_imac24_init_hook,
6489 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6490 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6491 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6492 .dac_nids = alc882_dac_nids,
6493 .dig_out_nid = ALC882_DIGOUT_NID,
6494 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6495 .adc_nids = alc882_adc_nids,
6496 .capsrc_nids = alc882_capsrc_nids,
6497 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6498 .channel_mode = alc882_3ST_6ch_modes,
6500 .input_mux = &alc882_capture_source,
6501 .unsol_event = alc882_targa_unsol_event,
6502 .init_hook = alc882_targa_automute,
6504 [ALC882_ASUS_A7J] = {
6505 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6506 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6507 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6508 .dac_nids = alc882_dac_nids,
6509 .dig_out_nid = ALC882_DIGOUT_NID,
6510 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6511 .adc_nids = alc882_adc_nids,
6512 .capsrc_nids = alc882_capsrc_nids,
6513 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6514 .channel_mode = alc882_3ST_6ch_modes,
6516 .input_mux = &alc882_capture_source,
6518 [ALC882_ASUS_A7M] = {
6519 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6520 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6521 alc880_gpio1_init_verbs,
6522 alc882_asus_a7m_verbs },
6523 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6524 .dac_nids = alc882_dac_nids,
6525 .dig_out_nid = ALC882_DIGOUT_NID,
6526 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6527 .channel_mode = alc880_threestack_modes,
6529 .input_mux = &alc882_capture_source,
6538 PINFIX_ABIT_AW9D_MAX
6541 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6542 { 0x15, 0x01080104 }, /* side */
6543 { 0x16, 0x01011012 }, /* rear */
6544 { 0x17, 0x01016011 }, /* clfe */
6548 static const struct alc_pincfg *alc882_pin_fixes[] = {
6549 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6552 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6553 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6558 * BIOS auto configuration
6560 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6561 hda_nid_t nid, int pin_type,
6565 struct alc_spec *spec = codec->spec;
6568 alc_set_pin_output(codec, nid, pin_type);
6569 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6572 idx = spec->multiout.dac_nids[dac_idx] - 2;
6573 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6577 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6579 struct alc_spec *spec = codec->spec;
6582 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6583 for (i = 0; i <= HDA_SIDE; i++) {
6584 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6585 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6587 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6592 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6594 struct alc_spec *spec = codec->spec;
6597 pin = spec->autocfg.hp_pins[0];
6598 if (pin) /* connect to front */
6600 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6601 pin = spec->autocfg.speaker_pins[0];
6603 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6606 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6607 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6609 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6611 struct alc_spec *spec = codec->spec;
6614 for (i = 0; i < AUTO_PIN_LAST; i++) {
6615 hda_nid_t nid = spec->autocfg.input_pins[i];
6620 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6621 unsigned int pincap;
6622 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6623 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6627 snd_hda_codec_write(codec, nid, 0,
6628 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6629 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6630 snd_hda_codec_write(codec, nid, 0,
6631 AC_VERB_SET_AMP_GAIN_MUTE,
6636 static void alc882_auto_init_input_src(struct hda_codec *codec)
6638 struct alc_spec *spec = codec->spec;
6639 const struct hda_input_mux *imux = spec->input_mux;
6642 for (c = 0; c < spec->num_adc_nids; c++) {
6643 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6644 hda_nid_t nid = spec->capsrc_nids[c];
6645 int conns, mute, idx, item;
6647 conns = snd_hda_get_connections(codec, nid, conn_list,
6648 ARRAY_SIZE(conn_list));
6651 for (idx = 0; idx < conns; idx++) {
6652 /* if the current connection is the selected one,
6653 * unmute it as default - otherwise mute it
6655 mute = AMP_IN_MUTE(idx);
6656 for (item = 0; item < imux->num_items; item++) {
6657 if (imux->items[item].index == idx) {
6658 if (spec->cur_mux[c] == item)
6659 mute = AMP_IN_UNMUTE(idx);
6663 snd_hda_codec_write(codec, nid, 0,
6664 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6669 /* add mic boosts if needed */
6670 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6672 struct alc_spec *spec = codec->spec;
6676 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6677 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6678 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6680 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6684 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6685 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6686 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6688 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6695 /* almost identical with ALC880 parser... */
6696 static int alc882_parse_auto_config(struct hda_codec *codec)
6698 struct alc_spec *spec = codec->spec;
6699 int err = alc880_parse_auto_config(codec);
6704 return 0; /* no config found */
6706 err = alc_auto_add_mic_boost(codec);
6710 /* hack - override the init verbs */
6711 spec->init_verbs[0] = alc882_auto_init_verbs;
6713 return 1; /* config found */
6716 /* additional initialization for auto-configuration model */
6717 static void alc882_auto_init(struct hda_codec *codec)
6719 struct alc_spec *spec = codec->spec;
6720 alc882_auto_init_multi_out(codec);
6721 alc882_auto_init_hp_out(codec);
6722 alc882_auto_init_analog_input(codec);
6723 alc882_auto_init_input_src(codec);
6724 if (spec->unsol_event)
6725 alc_inithook(codec);
6728 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6730 static int patch_alc882(struct hda_codec *codec)
6732 struct alc_spec *spec;
6733 int err, board_config;
6735 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6741 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6745 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6746 /* Pick up systems that don't supply PCI SSID */
6747 switch (codec->subsystem_id) {
6748 case 0x106b0c00: /* Mac Pro */
6749 board_config = ALC885_MACPRO;
6751 case 0x106b1000: /* iMac 24 */
6752 case 0x106b2800: /* AppleTV */
6753 board_config = ALC885_IMAC24;
6755 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6756 case 0x106b00a4: /* MacbookPro4,1 */
6757 case 0x106b2c00: /* Macbook Pro rev3 */
6758 case 0x106b3600: /* Macbook 3.1 */
6759 board_config = ALC885_MBP3;
6762 /* ALC889A is handled better as ALC888-compatible */
6763 if (codec->revision_id == 0x100101 ||
6764 codec->revision_id == 0x100103) {
6766 return patch_alc883(codec);
6768 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6769 "trying auto-probe from BIOS...\n");
6770 board_config = ALC882_AUTO;
6774 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6776 if (board_config == ALC882_AUTO) {
6777 /* automatic parse from the BIOS config */
6778 err = alc882_parse_auto_config(codec);
6784 "hda_codec: Cannot set up configuration "
6785 "from BIOS. Using base mode...\n");
6786 board_config = ALC882_3ST_DIG;
6790 if (board_config != ALC882_AUTO)
6791 setup_preset(spec, &alc882_presets[board_config]);
6793 if (codec->vendor_id == 0x10ec0885) {
6794 spec->stream_name_analog = "ALC885 Analog";
6795 spec->stream_name_digital = "ALC885 Digital";
6797 spec->stream_name_analog = "ALC882 Analog";
6798 spec->stream_name_digital = "ALC882 Digital";
6801 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6802 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6803 /* FIXME: setup DAC5 */
6804 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6805 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6807 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6808 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6810 spec->is_mix_capture = 1; /* matrix-style capture */
6811 if (!spec->adc_nids && spec->input_mux) {
6812 /* check whether NID 0x07 is valid */
6813 unsigned int wcap = get_wcaps(codec, 0x07);
6815 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6816 if (wcap != AC_WID_AUD_IN) {
6817 spec->adc_nids = alc882_adc_nids_alt;
6818 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6819 spec->capsrc_nids = alc882_capsrc_nids_alt;
6821 spec->adc_nids = alc882_adc_nids;
6822 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6823 spec->capsrc_nids = alc882_capsrc_nids;
6826 set_capture_mixer(spec);
6828 spec->vmaster_nid = 0x0c;
6830 codec->patch_ops = alc_patch_ops;
6831 if (board_config == ALC882_AUTO)
6832 spec->init_hook = alc882_auto_init;
6833 #ifdef CONFIG_SND_HDA_POWER_SAVE
6834 if (!spec->loopback.amplist)
6835 spec->loopback.amplist = alc882_loopbacks;
6844 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6845 * configuration. Each pin widget can choose any input DACs and a mixer.
6846 * Each ADC is connected from a mixer of all inputs. This makes possible
6847 * 6-channel independent captures.
6849 * In addition, an independent DAC for the multi-playback (not used in this
6852 #define ALC883_DIGOUT_NID 0x06
6853 #define ALC883_DIGIN_NID 0x0a
6855 static hda_nid_t alc883_dac_nids[4] = {
6856 /* front, rear, clfe, rear_surr */
6857 0x02, 0x03, 0x04, 0x05
6860 static hda_nid_t alc883_adc_nids[2] = {
6865 static hda_nid_t alc883_adc_nids_alt[1] = {
6870 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6873 /* FIXME: should be a matrix-type input source selection */
6875 static struct hda_input_mux alc883_capture_source = {
6879 { "Front Mic", 0x1 },
6885 static struct hda_input_mux alc883_3stack_6ch_intel = {
6889 { "Front Mic", 0x0 },
6895 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6903 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6913 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6921 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6925 { "Front Mic", 0x1 },
6930 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6941 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6948 static struct hda_verb alc883_3ST_ch2_init[] = {
6949 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6950 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6951 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6952 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6959 static struct hda_verb alc883_3ST_ch4_init[] = {
6960 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6961 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6962 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6963 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6964 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6971 static struct hda_verb alc883_3ST_ch6_init[] = {
6972 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6973 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6974 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6981 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6982 { 2, alc883_3ST_ch2_init },
6983 { 4, alc883_3ST_ch4_init },
6984 { 6, alc883_3ST_ch6_init },
6990 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6991 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6992 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6993 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6994 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7001 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7002 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7003 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7004 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7005 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7006 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7013 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7014 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7015 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7016 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7017 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7018 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7019 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7023 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7024 { 2, alc883_3ST_ch2_intel_init },
7025 { 4, alc883_3ST_ch4_intel_init },
7026 { 6, alc883_3ST_ch6_intel_init },
7032 static struct hda_verb alc883_sixstack_ch6_init[] = {
7033 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7034 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7035 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7036 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7043 static struct hda_verb alc883_sixstack_ch8_init[] = {
7044 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7045 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7047 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7051 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7052 { 6, alc883_sixstack_ch6_init },
7053 { 8, alc883_sixstack_ch8_init },
7056 static struct hda_verb alc883_medion_eapd_verbs[] = {
7057 /* eanable EAPD on medion laptop */
7058 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7059 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7063 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7064 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7067 static struct snd_kcontrol_new alc883_base_mixer[] = {
7068 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7070 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7071 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7072 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7073 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7074 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7075 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7076 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7077 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7078 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7079 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7080 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7086 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7087 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7088 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7089 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7090 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7094 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7096 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7097 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7098 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7099 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7100 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7103 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7106 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7107 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7111 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7112 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7113 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7115 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7117 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7120 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7121 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7125 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7127 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7128 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7129 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7130 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7131 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7133 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7134 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7135 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7139 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7140 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7141 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7143 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7144 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7148 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7150 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7151 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7153 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7154 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7158 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7159 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7160 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7161 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7162 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7163 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7164 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7165 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7166 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7175 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7177 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7178 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7179 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7183 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7184 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7185 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7186 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7187 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7188 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7190 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7191 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7192 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7194 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7195 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7199 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7202 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7203 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7204 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7205 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7209 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7224 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7227 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7229 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7230 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7234 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7235 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7236 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7237 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7238 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7239 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7240 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7241 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7242 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7243 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7244 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7245 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7248 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7249 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7254 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7257 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7258 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7259 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7261 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7263 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7264 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7265 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7269 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7272 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7273 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7281 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7282 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7283 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7288 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7289 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7290 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7294 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7296 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7297 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7307 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7309 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7314 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7319 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7322 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7323 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7324 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7325 0x0d, 1, 0x0, HDA_OUTPUT),
7326 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7327 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7328 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7329 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7330 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7331 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7332 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7333 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7334 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7335 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7336 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7339 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7340 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7341 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7342 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7346 static struct hda_bind_ctls alc883_bind_cap_vol = {
7347 .ops = &snd_hda_bind_vol,
7349 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7350 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7355 static struct hda_bind_ctls alc883_bind_cap_switch = {
7356 .ops = &snd_hda_bind_sw,
7358 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7359 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7364 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7365 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7366 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7371 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7376 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7377 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7378 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7381 /* .name = "Capture Source", */
7382 .name = "Input Source",
7384 .info = alc_mux_enum_info,
7385 .get = alc_mux_enum_get,
7386 .put = alc_mux_enum_put,
7391 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7394 .name = "Channel Mode",
7395 .info = alc_ch_mode_info,
7396 .get = alc_ch_mode_get,
7397 .put = alc_ch_mode_put,
7402 static struct hda_verb alc883_init_verbs[] = {
7403 /* ADC1: mute amp left and right */
7404 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7405 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7406 /* ADC2: mute amp left and right */
7407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7408 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7409 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7422 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7423 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7426 /* mute analog input loopbacks */
7427 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7428 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7429 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7430 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7431 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7433 /* Front Pin: output 0 (0x0c) */
7434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7437 /* Rear Pin: output 1 (0x0d) */
7438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7441 /* CLFE Pin: output 2 (0x0e) */
7442 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7444 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7445 /* Side Pin: output 3 (0x0f) */
7446 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7447 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7448 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7449 /* Mic (rear) pin: input vref at 80% */
7450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7452 /* Front Mic pin: input vref at 80% */
7453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7455 /* Line In pin: input */
7456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7458 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7459 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7460 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7461 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7462 /* CD pin widget for input */
7463 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7465 /* FIXME: use matrix-type input source selection */
7466 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7480 /* toggle speaker-output according to the hp-jack state */
7481 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7483 unsigned int present;
7485 present = snd_hda_codec_read(codec, 0x15, 0,
7486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7487 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7488 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7489 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7490 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7493 /* auto-toggle front mic */
7495 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7497 unsigned int present;
7500 present = snd_hda_codec_read(codec, 0x18, 0,
7501 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7502 bits = present ? HDA_AMP_MUTE : 0;
7503 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7507 static void alc883_mitac_automute(struct hda_codec *codec)
7509 alc883_mitac_hp_automute(codec);
7510 /* alc883_mitac_mic_automute(codec); */
7513 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7516 switch (res >> 26) {
7517 case ALC880_HP_EVENT:
7518 alc883_mitac_hp_automute(codec);
7520 case ALC880_MIC_EVENT:
7521 /* alc883_mitac_mic_automute(codec); */
7526 static struct hda_verb alc883_mitac_verbs[] = {
7528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7531 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7532 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7534 /* enable unsolicited event */
7535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7536 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7541 static struct hda_verb alc883_clevo_m720_verbs[] = {
7543 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7546 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7549 /* enable unsolicited event */
7550 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7551 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7556 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7558 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7561 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7564 /* enable unsolicited event */
7565 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7570 static struct hda_verb alc883_tagra_verbs[] = {
7571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7577 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7578 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7579 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7581 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7582 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7583 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7584 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7589 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7591 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7592 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7596 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7599 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7604 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7607 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7609 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7613 static struct hda_verb alc883_haier_w66_verbs[] = {
7614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7619 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7621 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7626 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7630 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7634 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7638 static struct hda_verb alc888_3st_hp_verbs[] = {
7639 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7640 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7641 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7645 static struct hda_verb alc888_6st_dell_verbs[] = {
7646 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7650 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7651 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7652 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7653 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7654 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7658 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7661 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7662 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7666 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7667 { 2, alc888_3st_hp_2ch_init },
7668 { 6, alc888_3st_hp_6ch_init },
7671 /* toggle front-jack and RCA according to the hp-jack state */
7672 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7674 unsigned int present;
7676 present = snd_hda_codec_read(codec, 0x1b, 0,
7677 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7678 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7679 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7680 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7681 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7684 /* toggle RCA according to the front-jack state */
7685 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7687 unsigned int present;
7689 present = snd_hda_codec_read(codec, 0x14, 0,
7690 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7691 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7692 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7695 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7698 if ((res >> 26) == ALC880_HP_EVENT)
7699 alc888_lenovo_ms7195_front_automute(codec);
7700 if ((res >> 26) == ALC880_FRONT_EVENT)
7701 alc888_lenovo_ms7195_rca_automute(codec);
7704 static struct hda_verb alc883_medion_md2_verbs[] = {
7705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7714 /* toggle speaker-output according to the hp-jack state */
7715 static void alc883_medion_md2_automute(struct hda_codec *codec)
7717 unsigned int present;
7719 present = snd_hda_codec_read(codec, 0x14, 0,
7720 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7721 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7722 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7725 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7728 if ((res >> 26) == ALC880_HP_EVENT)
7729 alc883_medion_md2_automute(codec);
7732 /* toggle speaker-output according to the hp-jack state */
7733 static void alc883_tagra_automute(struct hda_codec *codec)
7735 unsigned int present;
7738 present = snd_hda_codec_read(codec, 0x14, 0,
7739 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7740 bits = present ? HDA_AMP_MUTE : 0;
7741 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7742 HDA_AMP_MUTE, bits);
7743 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7747 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7749 if ((res >> 26) == ALC880_HP_EVENT)
7750 alc883_tagra_automute(codec);
7753 /* toggle speaker-output according to the hp-jack state */
7754 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7756 unsigned int present;
7759 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7760 & AC_PINSENSE_PRESENCE;
7761 bits = present ? HDA_AMP_MUTE : 0;
7762 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7763 HDA_AMP_MUTE, bits);
7766 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7768 unsigned int present;
7770 present = snd_hda_codec_read(codec, 0x18, 0,
7771 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7772 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7773 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7776 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7778 alc883_clevo_m720_hp_automute(codec);
7779 alc883_clevo_m720_mic_automute(codec);
7782 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7785 switch (res >> 26) {
7786 case ALC880_HP_EVENT:
7787 alc883_clevo_m720_hp_automute(codec);
7789 case ALC880_MIC_EVENT:
7790 alc883_clevo_m720_mic_automute(codec);
7795 /* toggle speaker-output according to the hp-jack state */
7796 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7798 unsigned int present;
7801 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7802 & AC_PINSENSE_PRESENCE;
7803 bits = present ? HDA_AMP_MUTE : 0;
7804 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7805 HDA_AMP_MUTE, bits);
7808 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7811 if ((res >> 26) == ALC880_HP_EVENT)
7812 alc883_2ch_fujitsu_pi2515_automute(codec);
7815 static void alc883_haier_w66_automute(struct hda_codec *codec)
7817 unsigned int present;
7820 present = snd_hda_codec_read(codec, 0x1b, 0,
7821 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7822 bits = present ? 0x80 : 0;
7823 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7827 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7830 if ((res >> 26) == ALC880_HP_EVENT)
7831 alc883_haier_w66_automute(codec);
7834 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7836 unsigned int present;
7839 present = snd_hda_codec_read(codec, 0x14, 0,
7840 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7841 bits = present ? HDA_AMP_MUTE : 0;
7842 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7843 HDA_AMP_MUTE, bits);
7846 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7848 unsigned int present;
7851 present = snd_hda_codec_read(codec, 0x1b, 0,
7852 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7853 bits = present ? HDA_AMP_MUTE : 0;
7854 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7855 HDA_AMP_MUTE, bits);
7856 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7857 HDA_AMP_MUTE, bits);
7860 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7863 if ((res >> 26) == ALC880_HP_EVENT)
7864 alc883_lenovo_101e_all_automute(codec);
7865 if ((res >> 26) == ALC880_FRONT_EVENT)
7866 alc883_lenovo_101e_ispeaker_automute(codec);
7869 /* toggle speaker-output according to the hp-jack state */
7870 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7872 unsigned int present;
7874 present = snd_hda_codec_read(codec, 0x14, 0,
7875 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7876 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7877 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7878 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7879 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7882 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7885 if ((res >> 26) == ALC880_HP_EVENT)
7886 alc883_acer_aspire_automute(codec);
7889 static struct hda_verb alc883_acer_eapd_verbs[] = {
7890 /* HP Pin: output 0 (0x0c) */
7891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7894 /* Front Pin: output 0 (0x0c) */
7895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7896 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7897 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7898 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7899 /* eanable EAPD on medion laptop */
7900 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7901 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7902 /* enable unsolicited event */
7903 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7907 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7909 unsigned int present;
7911 present = snd_hda_codec_read(codec, 0x1b, 0,
7912 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7913 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7914 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7915 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7917 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7918 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7919 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7920 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7923 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7926 switch (res >> 26) {
7927 case ALC880_HP_EVENT:
7928 printk("hp_event\n");
7929 alc888_6st_dell_front_automute(codec);
7934 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
7937 unsigned int present;
7939 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7940 present = snd_hda_codec_read(codec, 0x1b, 0,
7941 AC_VERB_GET_PIN_SENSE, 0);
7942 present = (present & 0x80000000) != 0;
7944 /* mute internal speaker */
7945 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7946 HDA_AMP_MUTE, HDA_AMP_MUTE);
7947 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7948 HDA_AMP_MUTE, HDA_AMP_MUTE);
7949 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7950 HDA_AMP_MUTE, HDA_AMP_MUTE);
7951 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7952 HDA_AMP_MUTE, HDA_AMP_MUTE);
7953 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7954 HDA_AMP_MUTE, HDA_AMP_MUTE);
7956 /* unmute internal speaker if necessary */
7957 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7958 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7959 HDA_AMP_MUTE, mute);
7960 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7961 HDA_AMP_MUTE, mute);
7962 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7963 HDA_AMP_MUTE, mute);
7964 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7965 HDA_AMP_MUTE, mute);
7966 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7967 HDA_AMP_MUTE, mute);
7971 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
7974 if ((res >> 26) == ALC880_HP_EVENT)
7975 alc888_lenovo_sky_front_automute(codec);
7979 * generic initialization of ADC, input mixers and output mixers
7981 static struct hda_verb alc883_auto_init_verbs[] = {
7983 * Unmute ADC0-2 and set the default input to mic-in
7985 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7986 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7987 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7988 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7990 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7992 * Note: PASD motherboards uses the Line In 2 as the input for
7993 * front panel mic (mic 2)
7995 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7996 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8000 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8003 * Set up output mixers (0x0c - 0x0f)
8005 /* set vol=0 to output mixers */
8006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8007 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8008 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8009 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8010 /* set up input amps for analog loopback */
8011 /* Amp Indices: DAC = 0, mixer = 1 */
8012 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8013 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8014 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8015 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8017 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8020 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8021 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8023 /* FIXME: use matrix-type input source selection */
8024 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8026 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8027 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8029 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8034 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8035 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8041 static struct hda_verb alc888_asus_m90v_verbs[] = {
8042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8043 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8044 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8045 /* enable unsolicited event */
8046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8047 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8051 static void alc883_nb_mic_automute(struct hda_codec *codec)
8053 unsigned int present;
8055 present = snd_hda_codec_read(codec, 0x18, 0,
8056 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8057 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8058 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8059 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8060 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8063 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8065 unsigned int present;
8068 present = snd_hda_codec_read(codec, 0x1b, 0,
8069 AC_VERB_GET_PIN_SENSE, 0)
8070 & AC_PINSENSE_PRESENCE;
8071 bits = present ? 0 : PIN_OUT;
8072 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8074 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8076 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8080 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8083 switch (res >> 26) {
8084 case ALC880_HP_EVENT:
8085 alc883_M90V_speaker_automute(codec);
8087 case ALC880_MIC_EVENT:
8088 alc883_nb_mic_automute(codec);
8093 static void alc883_mode2_inithook(struct hda_codec *codec)
8095 alc883_M90V_speaker_automute(codec);
8096 alc883_nb_mic_automute(codec);
8099 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8101 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8105 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8106 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8107 /* enable unsolicited event */
8108 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8112 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8114 unsigned int present;
8117 present = snd_hda_codec_read(codec, 0x14, 0,
8118 AC_VERB_GET_PIN_SENSE, 0)
8119 & AC_PINSENSE_PRESENCE;
8120 bits = present ? 0 : PIN_OUT;
8121 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8125 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8128 switch (res >> 26) {
8129 case ALC880_HP_EVENT:
8130 alc883_eee1601_speaker_automute(codec);
8135 static void alc883_eee1601_inithook(struct hda_codec *codec)
8137 alc883_eee1601_speaker_automute(codec);
8140 #ifdef CONFIG_SND_HDA_POWER_SAVE
8141 #define alc883_loopbacks alc880_loopbacks
8144 /* pcm configuration: identiacal with ALC880 */
8145 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8146 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8147 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8148 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8149 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8152 * configuration and preset
8154 static const char *alc883_models[ALC883_MODEL_LAST] = {
8155 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8156 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8157 [ALC883_3ST_6ch] = "3stack-6ch",
8158 [ALC883_6ST_DIG] = "6stack-dig",
8159 [ALC883_TARGA_DIG] = "targa-dig",
8160 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8161 [ALC883_ACER] = "acer",
8162 [ALC883_ACER_ASPIRE] = "acer-aspire",
8163 [ALC883_MEDION] = "medion",
8164 [ALC883_MEDION_MD2] = "medion-md2",
8165 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8166 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8167 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8168 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8169 [ALC888_LENOVO_SKY] = "lenovo-sky",
8170 [ALC883_HAIER_W66] = "haier-w66",
8171 [ALC888_3ST_HP] = "3stack-hp",
8172 [ALC888_6ST_DELL] = "6stack-dell",
8173 [ALC883_MITAC] = "mitac",
8174 [ALC883_CLEVO_M720] = "clevo-m720",
8175 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8176 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8177 [ALC883_AUTO] = "auto",
8180 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8181 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8182 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8183 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8184 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8185 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8186 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8187 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8188 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8189 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8190 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8191 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8192 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8193 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8194 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8195 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8196 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8197 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8198 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8199 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8200 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8201 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8202 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8203 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8204 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8205 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8206 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8207 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8208 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8209 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8210 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8211 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8212 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8213 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8214 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8215 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8216 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8217 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8218 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8219 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8220 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8221 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8222 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8223 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8224 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8225 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8226 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8227 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8228 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8229 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8230 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8231 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8232 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8233 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8234 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8235 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8236 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8237 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8238 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8239 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8240 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8241 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8245 static struct alc_config_preset alc883_presets[] = {
8246 [ALC883_3ST_2ch_DIG] = {
8247 .mixers = { alc883_3ST_2ch_mixer },
8248 .init_verbs = { alc883_init_verbs },
8249 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8250 .dac_nids = alc883_dac_nids,
8251 .dig_out_nid = ALC883_DIGOUT_NID,
8252 .dig_in_nid = ALC883_DIGIN_NID,
8253 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8254 .channel_mode = alc883_3ST_2ch_modes,
8255 .input_mux = &alc883_capture_source,
8257 [ALC883_3ST_6ch_DIG] = {
8258 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8259 .init_verbs = { alc883_init_verbs },
8260 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8261 .dac_nids = alc883_dac_nids,
8262 .dig_out_nid = ALC883_DIGOUT_NID,
8263 .dig_in_nid = ALC883_DIGIN_NID,
8264 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8265 .channel_mode = alc883_3ST_6ch_modes,
8267 .input_mux = &alc883_capture_source,
8269 [ALC883_3ST_6ch] = {
8270 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8271 .init_verbs = { alc883_init_verbs },
8272 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8273 .dac_nids = alc883_dac_nids,
8274 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8275 .channel_mode = alc883_3ST_6ch_modes,
8277 .input_mux = &alc883_capture_source,
8279 [ALC883_3ST_6ch_INTEL] = {
8280 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8281 .init_verbs = { alc883_init_verbs },
8282 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8283 .dac_nids = alc883_dac_nids,
8284 .dig_out_nid = ALC883_DIGOUT_NID,
8285 .dig_in_nid = ALC883_DIGIN_NID,
8286 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8287 .channel_mode = alc883_3ST_6ch_intel_modes,
8289 .input_mux = &alc883_3stack_6ch_intel,
8291 [ALC883_6ST_DIG] = {
8292 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8293 .init_verbs = { alc883_init_verbs },
8294 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8295 .dac_nids = alc883_dac_nids,
8296 .dig_out_nid = ALC883_DIGOUT_NID,
8297 .dig_in_nid = ALC883_DIGIN_NID,
8298 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8299 .channel_mode = alc883_sixstack_modes,
8300 .input_mux = &alc883_capture_source,
8302 [ALC883_TARGA_DIG] = {
8303 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8304 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8305 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8306 .dac_nids = alc883_dac_nids,
8307 .dig_out_nid = ALC883_DIGOUT_NID,
8308 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8309 .channel_mode = alc883_3ST_6ch_modes,
8311 .input_mux = &alc883_capture_source,
8312 .unsol_event = alc883_tagra_unsol_event,
8313 .init_hook = alc883_tagra_automute,
8315 [ALC883_TARGA_2ch_DIG] = {
8316 .mixers = { alc883_tagra_2ch_mixer},
8317 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8319 .dac_nids = alc883_dac_nids,
8320 .adc_nids = alc883_adc_nids_alt,
8321 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8322 .dig_out_nid = ALC883_DIGOUT_NID,
8323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8324 .channel_mode = alc883_3ST_2ch_modes,
8325 .input_mux = &alc883_capture_source,
8326 .unsol_event = alc883_tagra_unsol_event,
8327 .init_hook = alc883_tagra_automute,
8330 .mixers = { alc883_base_mixer },
8331 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8332 * and the headphone jack. Turn this on and rely on the
8333 * standard mute methods whenever the user wants to turn
8334 * these outputs off.
8336 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8337 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8338 .dac_nids = alc883_dac_nids,
8339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8340 .channel_mode = alc883_3ST_2ch_modes,
8341 .input_mux = &alc883_capture_source,
8343 [ALC883_ACER_ASPIRE] = {
8344 .mixers = { alc883_acer_aspire_mixer },
8345 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8346 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8347 .dac_nids = alc883_dac_nids,
8348 .dig_out_nid = ALC883_DIGOUT_NID,
8349 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8350 .channel_mode = alc883_3ST_2ch_modes,
8351 .input_mux = &alc883_capture_source,
8352 .unsol_event = alc883_acer_aspire_unsol_event,
8353 .init_hook = alc883_acer_aspire_automute,
8356 .mixers = { alc883_fivestack_mixer,
8357 alc883_chmode_mixer },
8358 .init_verbs = { alc883_init_verbs,
8359 alc883_medion_eapd_verbs },
8360 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8361 .dac_nids = alc883_dac_nids,
8362 .adc_nids = alc883_adc_nids_alt,
8363 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8364 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8365 .channel_mode = alc883_sixstack_modes,
8366 .input_mux = &alc883_capture_source,
8368 [ALC883_MEDION_MD2] = {
8369 .mixers = { alc883_medion_md2_mixer},
8370 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8371 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8372 .dac_nids = alc883_dac_nids,
8373 .dig_out_nid = ALC883_DIGOUT_NID,
8374 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8375 .channel_mode = alc883_3ST_2ch_modes,
8376 .input_mux = &alc883_capture_source,
8377 .unsol_event = alc883_medion_md2_unsol_event,
8378 .init_hook = alc883_medion_md2_automute,
8380 [ALC883_LAPTOP_EAPD] = {
8381 .mixers = { alc883_base_mixer },
8382 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8383 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8384 .dac_nids = alc883_dac_nids,
8385 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8386 .channel_mode = alc883_3ST_2ch_modes,
8387 .input_mux = &alc883_capture_source,
8389 [ALC883_CLEVO_M720] = {
8390 .mixers = { alc883_clevo_m720_mixer },
8391 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8392 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8393 .dac_nids = alc883_dac_nids,
8394 .dig_out_nid = ALC883_DIGOUT_NID,
8395 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8396 .channel_mode = alc883_3ST_2ch_modes,
8397 .input_mux = &alc883_capture_source,
8398 .unsol_event = alc883_clevo_m720_unsol_event,
8399 .init_hook = alc883_clevo_m720_automute,
8401 [ALC883_LENOVO_101E_2ch] = {
8402 .mixers = { alc883_lenovo_101e_2ch_mixer},
8403 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8405 .dac_nids = alc883_dac_nids,
8406 .adc_nids = alc883_adc_nids_alt,
8407 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8408 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8409 .channel_mode = alc883_3ST_2ch_modes,
8410 .input_mux = &alc883_lenovo_101e_capture_source,
8411 .unsol_event = alc883_lenovo_101e_unsol_event,
8412 .init_hook = alc883_lenovo_101e_all_automute,
8414 [ALC883_LENOVO_NB0763] = {
8415 .mixers = { alc883_lenovo_nb0763_mixer },
8416 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8418 .dac_nids = alc883_dac_nids,
8419 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8420 .channel_mode = alc883_3ST_2ch_modes,
8422 .input_mux = &alc883_lenovo_nb0763_capture_source,
8423 .unsol_event = alc883_medion_md2_unsol_event,
8424 .init_hook = alc883_medion_md2_automute,
8426 [ALC888_LENOVO_MS7195_DIG] = {
8427 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8428 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8429 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8430 .dac_nids = alc883_dac_nids,
8431 .dig_out_nid = ALC883_DIGOUT_NID,
8432 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8433 .channel_mode = alc883_3ST_6ch_modes,
8435 .input_mux = &alc883_capture_source,
8436 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8437 .init_hook = alc888_lenovo_ms7195_front_automute,
8439 [ALC883_HAIER_W66] = {
8440 .mixers = { alc883_tagra_2ch_mixer},
8441 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8442 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8443 .dac_nids = alc883_dac_nids,
8444 .dig_out_nid = ALC883_DIGOUT_NID,
8445 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8446 .channel_mode = alc883_3ST_2ch_modes,
8447 .input_mux = &alc883_capture_source,
8448 .unsol_event = alc883_haier_w66_unsol_event,
8449 .init_hook = alc883_haier_w66_automute,
8452 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8453 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8454 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8455 .dac_nids = alc883_dac_nids,
8456 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8457 .channel_mode = alc888_3st_hp_modes,
8459 .input_mux = &alc883_capture_source,
8461 [ALC888_6ST_DELL] = {
8462 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8463 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8464 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8465 .dac_nids = alc883_dac_nids,
8466 .dig_out_nid = ALC883_DIGOUT_NID,
8467 .dig_in_nid = ALC883_DIGIN_NID,
8468 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8469 .channel_mode = alc883_sixstack_modes,
8470 .input_mux = &alc883_capture_source,
8471 .unsol_event = alc888_6st_dell_unsol_event,
8472 .init_hook = alc888_6st_dell_front_automute,
8475 .mixers = { alc883_mitac_mixer },
8476 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8478 .dac_nids = alc883_dac_nids,
8479 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8480 .channel_mode = alc883_3ST_2ch_modes,
8481 .input_mux = &alc883_capture_source,
8482 .unsol_event = alc883_mitac_unsol_event,
8483 .init_hook = alc883_mitac_automute,
8485 [ALC883_FUJITSU_PI2515] = {
8486 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8487 .init_verbs = { alc883_init_verbs,
8488 alc883_2ch_fujitsu_pi2515_verbs},
8489 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8490 .dac_nids = alc883_dac_nids,
8491 .dig_out_nid = ALC883_DIGOUT_NID,
8492 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8493 .channel_mode = alc883_3ST_2ch_modes,
8494 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8495 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8496 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8498 [ALC888_LENOVO_SKY] = {
8499 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8500 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8502 .dac_nids = alc883_dac_nids,
8503 .dig_out_nid = ALC883_DIGOUT_NID,
8504 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8505 .channel_mode = alc883_sixstack_modes,
8507 .input_mux = &alc883_lenovo_sky_capture_source,
8508 .unsol_event = alc883_lenovo_sky_unsol_event,
8509 .init_hook = alc888_lenovo_sky_front_automute,
8511 [ALC888_ASUS_M90V] = {
8512 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8513 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8514 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8515 .dac_nids = alc883_dac_nids,
8516 .dig_out_nid = ALC883_DIGOUT_NID,
8517 .dig_in_nid = ALC883_DIGIN_NID,
8518 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8519 .channel_mode = alc883_3ST_6ch_modes,
8521 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8522 .unsol_event = alc883_mode2_unsol_event,
8523 .init_hook = alc883_mode2_inithook,
8525 [ALC888_ASUS_EEE1601] = {
8526 .mixers = { alc883_asus_eee1601_mixer },
8527 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8528 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8529 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8530 .dac_nids = alc883_dac_nids,
8531 .dig_out_nid = ALC883_DIGOUT_NID,
8532 .dig_in_nid = ALC883_DIGIN_NID,
8533 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8534 .channel_mode = alc883_3ST_2ch_modes,
8536 .input_mux = &alc883_asus_eee1601_capture_source,
8537 .unsol_event = alc883_eee1601_unsol_event,
8538 .init_hook = alc883_eee1601_inithook,
8544 * BIOS auto configuration
8546 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8547 hda_nid_t nid, int pin_type,
8551 struct alc_spec *spec = codec->spec;
8554 alc_set_pin_output(codec, nid, pin_type);
8555 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8558 idx = spec->multiout.dac_nids[dac_idx] - 2;
8559 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8563 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8565 struct alc_spec *spec = codec->spec;
8568 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8569 for (i = 0; i <= HDA_SIDE; i++) {
8570 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8571 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8573 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8578 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8580 struct alc_spec *spec = codec->spec;
8583 pin = spec->autocfg.hp_pins[0];
8584 if (pin) /* connect to front */
8586 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8587 pin = spec->autocfg.speaker_pins[0];
8589 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8592 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8593 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8595 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8597 struct alc_spec *spec = codec->spec;
8600 for (i = 0; i < AUTO_PIN_LAST; i++) {
8601 hda_nid_t nid = spec->autocfg.input_pins[i];
8602 if (alc883_is_input_pin(nid)) {
8603 snd_hda_codec_write(codec, nid, 0,
8604 AC_VERB_SET_PIN_WIDGET_CONTROL,
8605 (i <= AUTO_PIN_FRONT_MIC ?
8606 PIN_VREF80 : PIN_IN));
8607 if (nid != ALC883_PIN_CD_NID)
8608 snd_hda_codec_write(codec, nid, 0,
8609 AC_VERB_SET_AMP_GAIN_MUTE,
8615 #define alc883_auto_init_input_src alc882_auto_init_input_src
8617 /* almost identical with ALC880 parser... */
8618 static int alc883_parse_auto_config(struct hda_codec *codec)
8620 struct alc_spec *spec = codec->spec;
8621 int err = alc880_parse_auto_config(codec);
8626 return 0; /* no config found */
8628 err = alc_auto_add_mic_boost(codec);
8632 /* hack - override the init verbs */
8633 spec->init_verbs[0] = alc883_auto_init_verbs;
8635 return 1; /* config found */
8638 /* additional initialization for auto-configuration model */
8639 static void alc883_auto_init(struct hda_codec *codec)
8641 struct alc_spec *spec = codec->spec;
8642 alc883_auto_init_multi_out(codec);
8643 alc883_auto_init_hp_out(codec);
8644 alc883_auto_init_analog_input(codec);
8645 alc883_auto_init_input_src(codec);
8646 if (spec->unsol_event)
8647 alc_inithook(codec);
8650 static int patch_alc883(struct hda_codec *codec)
8652 struct alc_spec *spec;
8653 int err, board_config;
8655 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8661 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8663 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8666 if (board_config < 0) {
8667 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8668 "trying auto-probe from BIOS...\n");
8669 board_config = ALC883_AUTO;
8672 if (board_config == ALC883_AUTO) {
8673 /* automatic parse from the BIOS config */
8674 err = alc883_parse_auto_config(codec);
8680 "hda_codec: Cannot set up configuration "
8681 "from BIOS. Using base mode...\n");
8682 board_config = ALC883_3ST_2ch_DIG;
8686 if (board_config != ALC883_AUTO)
8687 setup_preset(spec, &alc883_presets[board_config]);
8689 switch (codec->vendor_id) {
8691 if (codec->revision_id == 0x100101) {
8692 spec->stream_name_analog = "ALC1200 Analog";
8693 spec->stream_name_digital = "ALC1200 Digital";
8695 spec->stream_name_analog = "ALC888 Analog";
8696 spec->stream_name_digital = "ALC888 Digital";
8700 spec->stream_name_analog = "ALC889 Analog";
8701 spec->stream_name_digital = "ALC889 Digital";
8704 spec->stream_name_analog = "ALC883 Analog";
8705 spec->stream_name_digital = "ALC883 Digital";
8709 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8710 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8711 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8713 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8714 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8716 if (!spec->num_adc_nids) {
8717 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8718 spec->adc_nids = alc883_adc_nids;
8720 if (!spec->capsrc_nids)
8721 spec->capsrc_nids = alc883_capsrc_nids;
8722 spec->is_mix_capture = 1; /* matrix-style capture */
8723 if (!spec->cap_mixer)
8724 set_capture_mixer(spec);
8726 spec->vmaster_nid = 0x0c;
8728 codec->patch_ops = alc_patch_ops;
8729 if (board_config == ALC883_AUTO)
8730 spec->init_hook = alc883_auto_init;
8732 #ifdef CONFIG_SND_HDA_POWER_SAVE
8733 if (!spec->loopback.amplist)
8734 spec->loopback.amplist = alc883_loopbacks;
8744 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8745 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8747 #define alc262_dac_nids alc260_dac_nids
8748 #define alc262_adc_nids alc882_adc_nids
8749 #define alc262_adc_nids_alt alc882_adc_nids_alt
8750 #define alc262_capsrc_nids alc882_capsrc_nids
8751 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8753 #define alc262_modes alc260_modes
8754 #define alc262_capture_source alc882_capture_source
8756 static hda_nid_t alc262_dmic_adc_nids[1] = {
8761 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8763 static struct snd_kcontrol_new alc262_base_mixer[] = {
8764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8765 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8766 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8767 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8768 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8769 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8770 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8772 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8773 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8775 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8776 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8777 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8778 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8780 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8781 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8785 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8786 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8787 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8796 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8797 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8798 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8799 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8800 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8801 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8805 /* update HP, line and mono-out pins according to the master switch */
8806 static void alc262_hp_master_update(struct hda_codec *codec)
8808 struct alc_spec *spec = codec->spec;
8809 int val = spec->master_sw;
8812 snd_hda_codec_write_cache(codec, 0x1b, 0,
8813 AC_VERB_SET_PIN_WIDGET_CONTROL,
8815 snd_hda_codec_write_cache(codec, 0x15, 0,
8816 AC_VERB_SET_PIN_WIDGET_CONTROL,
8818 /* mono (speaker) depending on the HP jack sense */
8819 val = val && !spec->jack_present;
8820 snd_hda_codec_write_cache(codec, 0x16, 0,
8821 AC_VERB_SET_PIN_WIDGET_CONTROL,
8825 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8827 struct alc_spec *spec = codec->spec;
8828 unsigned int presence;
8829 presence = snd_hda_codec_read(codec, 0x1b, 0,
8830 AC_VERB_GET_PIN_SENSE, 0);
8831 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8832 alc262_hp_master_update(codec);
8835 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8837 if ((res >> 26) != ALC880_HP_EVENT)
8839 alc262_hp_bpc_automute(codec);
8842 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8844 struct alc_spec *spec = codec->spec;
8845 unsigned int presence;
8846 presence = snd_hda_codec_read(codec, 0x15, 0,
8847 AC_VERB_GET_PIN_SENSE, 0);
8848 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8849 alc262_hp_master_update(codec);
8852 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8855 if ((res >> 26) != ALC880_HP_EVENT)
8857 alc262_hp_wildwest_automute(codec);
8860 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8861 struct snd_ctl_elem_value *ucontrol)
8863 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8864 struct alc_spec *spec = codec->spec;
8865 *ucontrol->value.integer.value = spec->master_sw;
8869 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8870 struct snd_ctl_elem_value *ucontrol)
8872 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8873 struct alc_spec *spec = codec->spec;
8874 int val = !!*ucontrol->value.integer.value;
8876 if (val == spec->master_sw)
8878 spec->master_sw = val;
8879 alc262_hp_master_update(codec);
8883 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8886 .name = "Master Playback Switch",
8887 .info = snd_ctl_boolean_mono_info,
8888 .get = alc262_hp_master_sw_get,
8889 .put = alc262_hp_master_sw_put,
8891 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8892 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8896 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8901 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8902 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8905 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8906 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8907 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8908 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8909 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8910 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8911 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8915 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8918 .name = "Master Playback Switch",
8919 .info = snd_ctl_boolean_mono_info,
8920 .get = alc262_hp_master_sw_get,
8921 .put = alc262_hp_master_sw_put,
8923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8924 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8925 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8926 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8927 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8929 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8933 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8936 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8937 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8938 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8939 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8943 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8944 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8945 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8946 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8950 /* mute/unmute internal speaker according to the hp jack and mute state */
8951 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8953 struct alc_spec *spec = codec->spec;
8955 if (force || !spec->sense_updated) {
8956 unsigned int present;
8957 present = snd_hda_codec_read(codec, 0x15, 0,
8958 AC_VERB_GET_PIN_SENSE, 0);
8959 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8960 spec->sense_updated = 1;
8962 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8963 spec->jack_present ? HDA_AMP_MUTE : 0);
8966 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8969 if ((res >> 26) != ALC880_HP_EVENT)
8971 alc262_hp_t5735_automute(codec, 1);
8974 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8976 alc262_hp_t5735_automute(codec, 1);
8979 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8980 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8981 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8982 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8986 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8990 static struct hda_verb alc262_hp_t5735_verbs[] = {
8991 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8992 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8994 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8998 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8999 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9001 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9002 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9008 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9009 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9010 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9013 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9014 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9016 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9022 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9029 /* bind hp and internal speaker mute (with plug check) */
9030 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9031 struct snd_ctl_elem_value *ucontrol)
9033 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9034 long *valp = ucontrol->value.integer.value;
9037 /* change hp mute */
9038 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9040 valp[0] ? 0 : HDA_AMP_MUTE);
9041 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9043 valp[1] ? 0 : HDA_AMP_MUTE);
9045 /* change speaker according to HP jack state */
9046 struct alc_spec *spec = codec->spec;
9048 if (spec->jack_present)
9049 mute = HDA_AMP_MUTE;
9051 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9053 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9054 HDA_AMP_MUTE, mute);
9059 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9060 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9063 .name = "Master Playback Switch",
9064 .info = snd_hda_mixer_amp_switch_info,
9065 .get = snd_hda_mixer_amp_switch_get,
9066 .put = alc262_sony_master_sw_put,
9067 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9069 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9071 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9072 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9076 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9078 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9080 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9081 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9082 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9083 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9087 #define alc262_capture_mixer alc882_capture_mixer
9088 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9091 * generic initialization of ADC, input mixers and output mixers
9093 static struct hda_verb alc262_init_verbs[] = {
9095 * Unmute ADC0-2 and set the default input to mic-in
9097 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9099 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9100 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9101 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9102 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9104 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9106 * Note: PASD motherboards uses the Line In 2 as the input for
9107 * front panel mic (mic 2)
9109 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9110 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9117 * Set up output mixers (0x0c - 0x0e)
9119 /* set vol=0 to output mixers */
9120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9123 /* set up input amps for analog loopback */
9124 /* Amp Indices: DAC = 0, mixer = 1 */
9125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9127 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9129 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9130 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9132 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9134 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9135 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9136 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9137 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9141 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9142 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9143 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9145 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9146 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9148 /* FIXME: use matrix-type input source selection */
9149 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9150 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9154 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9156 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9161 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9164 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9169 static struct hda_verb alc262_eapd_verbs[] = {
9170 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9171 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9175 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9181 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9183 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9184 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9186 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9187 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9191 static struct hda_verb alc262_sony_unsol_verbs[] = {
9192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9193 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9194 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9196 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9197 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9201 static struct hda_input_mux alc262_dmic_capture_source = {
9204 { "Int DMic", 0x9 },
9209 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9211 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9214 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9218 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9219 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9222 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9223 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9224 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9225 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9226 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9230 static void alc262_dmic_automute(struct hda_codec *codec)
9232 unsigned int present;
9234 present = snd_hda_codec_read(codec, 0x18, 0,
9235 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9236 snd_hda_codec_write(codec, 0x22, 0,
9237 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9240 /* toggle speaker-output according to the hp-jack state */
9241 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9243 unsigned int present;
9246 present = snd_hda_codec_read(codec, 0x15, 0,
9247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9248 bits = present ? 0 : PIN_OUT;
9249 snd_hda_codec_write(codec, 0x14, 0,
9250 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9255 /* unsolicited event for HP jack sensing */
9256 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9259 if ((res >> 26) == ALC880_HP_EVENT)
9260 alc262_toshiba_s06_speaker_automute(codec);
9261 if ((res >> 26) == ALC880_MIC_EVENT)
9262 alc262_dmic_automute(codec);
9266 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9268 alc262_toshiba_s06_speaker_automute(codec);
9269 alc262_dmic_automute(codec);
9272 /* mute/unmute internal speaker according to the hp jack and mute state */
9273 static void alc262_hippo_automute(struct hda_codec *codec)
9275 struct alc_spec *spec = codec->spec;
9277 unsigned int present;
9279 /* need to execute and sync at first */
9280 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9281 present = snd_hda_codec_read(codec, 0x15, 0,
9282 AC_VERB_GET_PIN_SENSE, 0);
9283 spec->jack_present = (present & 0x80000000) != 0;
9284 if (spec->jack_present) {
9285 /* mute internal speaker */
9286 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9287 HDA_AMP_MUTE, HDA_AMP_MUTE);
9289 /* unmute internal speaker if necessary */
9290 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9291 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9292 HDA_AMP_MUTE, mute);
9296 /* unsolicited event for HP jack sensing */
9297 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9300 if ((res >> 26) != ALC880_HP_EVENT)
9302 alc262_hippo_automute(codec);
9305 static void alc262_hippo1_automute(struct hda_codec *codec)
9308 unsigned int present;
9310 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9311 present = snd_hda_codec_read(codec, 0x1b, 0,
9312 AC_VERB_GET_PIN_SENSE, 0);
9313 present = (present & 0x80000000) != 0;
9315 /* mute internal speaker */
9316 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9317 HDA_AMP_MUTE, HDA_AMP_MUTE);
9319 /* unmute internal speaker if necessary */
9320 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9321 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9322 HDA_AMP_MUTE, mute);
9326 /* unsolicited event for HP jack sensing */
9327 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9330 if ((res >> 26) != ALC880_HP_EVENT)
9332 alc262_hippo1_automute(codec);
9338 * 0x16 = internal speaker
9339 * 0x18 = external mic
9342 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9343 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9344 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9348 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9355 static struct hda_verb alc262_nec_verbs[] = {
9356 /* Unmute Speaker */
9357 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9360 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9363 /* External mic to headphone */
9364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9365 /* External mic to speaker */
9366 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9372 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9373 * 0x1b = port replicator headphone out
9376 #define ALC_HP_EVENT 0x37
9378 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9379 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9381 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9382 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9386 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9387 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9388 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9392 static struct hda_input_mux alc262_fujitsu_capture_source = {
9401 static struct hda_input_mux alc262_HP_capture_source = {
9405 { "Front Mic", 0x1 },
9412 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9416 { "Front Mic", 0x2 },
9422 /* mute/unmute internal speaker according to the hp jacks and mute state */
9423 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9425 struct alc_spec *spec = codec->spec;
9428 if (force || !spec->sense_updated) {
9429 unsigned int present;
9430 /* need to execute and sync at first */
9431 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9432 /* check laptop HP jack */
9433 present = snd_hda_codec_read(codec, 0x14, 0,
9434 AC_VERB_GET_PIN_SENSE, 0);
9435 /* need to execute and sync at first */
9436 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9437 /* check docking HP jack */
9438 present |= snd_hda_codec_read(codec, 0x1b, 0,
9439 AC_VERB_GET_PIN_SENSE, 0);
9440 if (present & AC_PINSENSE_PRESENCE)
9441 spec->jack_present = 1;
9443 spec->jack_present = 0;
9444 spec->sense_updated = 1;
9446 /* unmute internal speaker only if both HPs are unplugged and
9447 * master switch is on
9449 if (spec->jack_present)
9450 mute = HDA_AMP_MUTE;
9452 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9453 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9454 HDA_AMP_MUTE, mute);
9457 /* unsolicited event for HP jack sensing */
9458 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9461 if ((res >> 26) != ALC_HP_EVENT)
9463 alc262_fujitsu_automute(codec, 1);
9466 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9468 alc262_fujitsu_automute(codec, 1);
9471 /* bind volumes of both NID 0x0c and 0x0d */
9472 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9473 .ops = &snd_hda_bind_vol,
9475 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9476 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9481 /* mute/unmute internal speaker according to the hp jack and mute state */
9482 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9484 struct alc_spec *spec = codec->spec;
9487 if (force || !spec->sense_updated) {
9488 unsigned int present_int_hp;
9489 /* need to execute and sync at first */
9490 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9491 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9492 AC_VERB_GET_PIN_SENSE, 0);
9493 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9494 spec->sense_updated = 1;
9496 if (spec->jack_present) {
9497 /* mute internal speaker */
9498 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9499 HDA_AMP_MUTE, HDA_AMP_MUTE);
9500 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9501 HDA_AMP_MUTE, HDA_AMP_MUTE);
9503 /* unmute internal speaker if necessary */
9504 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9505 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9506 HDA_AMP_MUTE, mute);
9507 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9508 HDA_AMP_MUTE, mute);
9512 /* unsolicited event for HP jack sensing */
9513 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9516 if ((res >> 26) != ALC_HP_EVENT)
9518 alc262_lenovo_3000_automute(codec, 1);
9521 /* bind hp and internal speaker mute (with plug check) */
9522 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9523 struct snd_ctl_elem_value *ucontrol)
9525 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9526 long *valp = ucontrol->value.integer.value;
9529 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9531 valp ? 0 : HDA_AMP_MUTE);
9532 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9534 valp ? 0 : HDA_AMP_MUTE);
9537 alc262_fujitsu_automute(codec, 0);
9541 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9542 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9544 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9545 .name = "Master Playback Switch",
9546 .info = snd_hda_mixer_amp_switch_info,
9547 .get = snd_hda_mixer_amp_switch_get,
9548 .put = alc262_fujitsu_master_sw_put,
9549 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9551 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9552 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9553 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9554 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9555 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9557 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9558 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9559 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9560 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9564 /* bind hp and internal speaker mute (with plug check) */
9565 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9566 struct snd_ctl_elem_value *ucontrol)
9568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9569 long *valp = ucontrol->value.integer.value;
9572 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9574 valp ? 0 : HDA_AMP_MUTE);
9577 alc262_lenovo_3000_automute(codec, 0);
9581 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9582 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9584 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9585 .name = "Master Playback Switch",
9586 .info = snd_hda_mixer_amp_switch_info,
9587 .get = snd_hda_mixer_amp_switch_get,
9588 .put = alc262_lenovo_3000_master_sw_put,
9589 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9593 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9594 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9595 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9596 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9597 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9598 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9602 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9606 .name = "Master Playback Switch",
9607 .info = snd_hda_mixer_amp_switch_info,
9608 .get = snd_hda_mixer_amp_switch_get,
9609 .put = alc262_sony_master_sw_put,
9610 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9612 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9613 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9614 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9615 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9616 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9617 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9621 /* additional init verbs for Benq laptops */
9622 static struct hda_verb alc262_EAPD_verbs[] = {
9623 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9624 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9628 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9629 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9630 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9632 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9633 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9637 /* Samsung Q1 Ultra Vista model setup */
9638 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9639 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9640 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9641 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9643 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9644 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9648 static struct hda_verb alc262_ultra_verbs[] = {
9650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9651 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9652 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9656 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9657 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9662 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9663 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9665 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9666 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9667 /* ADC, choose mic */
9668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9670 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9671 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9677 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9681 /* mute/unmute internal speaker according to the hp jack and mute state */
9682 static void alc262_ultra_automute(struct hda_codec *codec)
9684 struct alc_spec *spec = codec->spec;
9688 /* auto-mute only when HP is used as HP */
9689 if (!spec->cur_mux[0]) {
9690 unsigned int present;
9691 /* need to execute and sync at first */
9692 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9693 present = snd_hda_codec_read(codec, 0x15, 0,
9694 AC_VERB_GET_PIN_SENSE, 0);
9695 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9696 if (spec->jack_present)
9697 mute = HDA_AMP_MUTE;
9699 /* mute/unmute internal speaker */
9700 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9701 HDA_AMP_MUTE, mute);
9702 /* mute/unmute HP */
9703 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9704 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9707 /* unsolicited event for HP jack sensing */
9708 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9711 if ((res >> 26) != ALC880_HP_EVENT)
9713 alc262_ultra_automute(codec);
9716 static struct hda_input_mux alc262_ultra_capture_source = {
9720 { "Headphone", 0x7 },
9724 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9725 struct snd_ctl_elem_value *ucontrol)
9727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9728 struct alc_spec *spec = codec->spec;
9731 ret = alc_mux_enum_put(kcontrol, ucontrol);
9734 /* reprogram the HP pin as mic or HP according to the input source */
9735 snd_hda_codec_write_cache(codec, 0x15, 0,
9736 AC_VERB_SET_PIN_WIDGET_CONTROL,
9737 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9738 alc262_ultra_automute(codec); /* mute/unmute HP */
9742 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9743 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9744 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9747 .name = "Capture Source",
9748 .info = alc_mux_enum_info,
9749 .get = alc_mux_enum_get,
9750 .put = alc262_ultra_mux_enum_put,
9755 /* add playback controls from the parsed DAC table */
9756 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9757 const struct auto_pin_cfg *cfg)
9762 spec->multiout.num_dacs = 1; /* only use one dac */
9763 spec->multiout.dac_nids = spec->private_dac_nids;
9764 spec->multiout.dac_nids[0] = 2;
9766 nid = cfg->line_out_pins[0];
9768 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9769 "Front Playback Volume",
9770 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9773 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9774 "Front Playback Switch",
9775 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9780 nid = cfg->speaker_pins[0];
9783 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9784 "Speaker Playback Volume",
9785 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9789 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9790 "Speaker Playback Switch",
9791 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9796 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9797 "Speaker Playback Switch",
9798 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9804 nid = cfg->hp_pins[0];
9806 /* spec->multiout.hp_nid = 2; */
9808 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9809 "Headphone Playback Volume",
9810 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9814 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9815 "Headphone Playback Switch",
9816 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9821 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9822 "Headphone Playback Switch",
9823 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9832 /* identical with ALC880 */
9833 #define alc262_auto_create_analog_input_ctls \
9834 alc880_auto_create_analog_input_ctls
9837 * generic initialization of ADC, input mixers and output mixers
9839 static struct hda_verb alc262_volume_init_verbs[] = {
9841 * Unmute ADC0-2 and set the default input to mic-in
9843 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9844 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9845 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9847 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9848 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9850 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9852 * Note: PASD motherboards uses the Line In 2 as the input for
9853 * front panel mic (mic 2)
9855 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9860 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9863 * Set up output mixers (0x0c - 0x0f)
9865 /* set vol=0 to output mixers */
9866 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9867 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9868 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9870 /* set up input amps for analog loopback */
9871 /* Amp Indices: DAC = 0, mixer = 1 */
9872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9874 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9875 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9876 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9877 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9879 /* FIXME: use matrix-type input source selection */
9880 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9881 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9884 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9885 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9900 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9902 * Unmute ADC0-2 and set the default input to mic-in
9904 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9906 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9907 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9908 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9909 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9911 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9913 * Note: PASD motherboards uses the Line In 2 as the input for
9914 * front panel mic (mic 2)
9916 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9917 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9918 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9926 * Set up output mixers (0x0c - 0x0e)
9928 /* set vol=0 to output mixers */
9929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9933 /* set up input amps for analog loopback */
9934 /* Amp Indices: DAC = 0, mixer = 1 */
9935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9937 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9939 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9940 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9944 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9947 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9949 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9953 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9955 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9956 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9959 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9961 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9962 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9963 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9966 /* FIXME: use matrix-type input source selection */
9967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9968 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9969 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9970 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9971 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9974 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9975 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9976 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9980 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9989 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9991 * Unmute ADC0-2 and set the default input to mic-in
9993 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9995 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9996 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9997 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10000 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10002 * Note: PASD motherboards uses the Line In 2 as the input for front
10003 * panel mic (mic 2)
10005 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10015 * Set up output mixers (0x0c - 0x0e)
10017 /* set vol=0 to output mixers */
10018 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10020 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10022 /* set up input amps for analog loopback */
10023 /* Amp Indices: DAC = 0, mixer = 1 */
10024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10033 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10036 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10037 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10038 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10040 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10041 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10043 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10046 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10047 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10048 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10050 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10051 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10053 /* FIXME: use matrix-type input source selection */
10054 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10055 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10061 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10066 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10069 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10077 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10085 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10089 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10092 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10098 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10103 #ifdef CONFIG_SND_HDA_POWER_SAVE
10104 #define alc262_loopbacks alc880_loopbacks
10107 /* pcm configuration: identiacal with ALC880 */
10108 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10109 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10110 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10111 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10114 * BIOS auto configuration
10116 static int alc262_parse_auto_config(struct hda_codec *codec)
10118 struct alc_spec *spec = codec->spec;
10120 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10122 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10126 if (!spec->autocfg.line_outs)
10127 return 0; /* can't find valid BIOS pin config */
10128 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10131 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10135 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10137 if (spec->autocfg.dig_out_pin)
10138 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10139 if (spec->autocfg.dig_in_pin)
10140 spec->dig_in_nid = ALC262_DIGIN_NID;
10142 if (spec->kctls.list)
10143 add_mixer(spec, spec->kctls.list);
10145 add_verb(spec, alc262_volume_init_verbs);
10146 spec->num_mux_defs = 1;
10147 spec->input_mux = &spec->private_imux;
10149 err = alc_auto_add_mic_boost(codec);
10153 store_pin_configs(codec);
10157 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10158 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10159 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10160 #define alc262_auto_init_input_src alc882_auto_init_input_src
10163 /* init callback for auto-configuration model -- overriding the default init */
10164 static void alc262_auto_init(struct hda_codec *codec)
10166 struct alc_spec *spec = codec->spec;
10167 alc262_auto_init_multi_out(codec);
10168 alc262_auto_init_hp_out(codec);
10169 alc262_auto_init_analog_input(codec);
10170 alc262_auto_init_input_src(codec);
10171 if (spec->unsol_event)
10172 alc_inithook(codec);
10176 * configuration and preset
10178 static const char *alc262_models[ALC262_MODEL_LAST] = {
10179 [ALC262_BASIC] = "basic",
10180 [ALC262_HIPPO] = "hippo",
10181 [ALC262_HIPPO_1] = "hippo_1",
10182 [ALC262_FUJITSU] = "fujitsu",
10183 [ALC262_HP_BPC] = "hp-bpc",
10184 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10185 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10186 [ALC262_HP_RP5700] = "hp-rp5700",
10187 [ALC262_BENQ_ED8] = "benq",
10188 [ALC262_BENQ_T31] = "benq-t31",
10189 [ALC262_SONY_ASSAMD] = "sony-assamd",
10190 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10191 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10192 [ALC262_ULTRA] = "ultra",
10193 [ALC262_LENOVO_3000] = "lenovo-3000",
10194 [ALC262_NEC] = "nec",
10195 [ALC262_AUTO] = "auto",
10198 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10199 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10200 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10201 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10202 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10203 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10204 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10205 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10206 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10207 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10208 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10209 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10210 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10211 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10212 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10213 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10214 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10215 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10216 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10217 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10218 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10219 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10220 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10221 ALC262_HP_TC_T5735),
10222 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10223 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10224 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10225 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10226 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10227 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10228 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10229 ALC262_TOSHIBA_RX1),
10230 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10231 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10232 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10233 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10234 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10235 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10236 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10237 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10238 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10242 static struct alc_config_preset alc262_presets[] = {
10244 .mixers = { alc262_base_mixer },
10245 .init_verbs = { alc262_init_verbs },
10246 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10247 .dac_nids = alc262_dac_nids,
10249 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10250 .channel_mode = alc262_modes,
10251 .input_mux = &alc262_capture_source,
10254 .mixers = { alc262_base_mixer },
10255 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10256 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10257 .dac_nids = alc262_dac_nids,
10259 .dig_out_nid = ALC262_DIGOUT_NID,
10260 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10261 .channel_mode = alc262_modes,
10262 .input_mux = &alc262_capture_source,
10263 .unsol_event = alc262_hippo_unsol_event,
10264 .init_hook = alc262_hippo_automute,
10266 [ALC262_HIPPO_1] = {
10267 .mixers = { alc262_hippo1_mixer },
10268 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10269 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10270 .dac_nids = alc262_dac_nids,
10272 .dig_out_nid = ALC262_DIGOUT_NID,
10273 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10274 .channel_mode = alc262_modes,
10275 .input_mux = &alc262_capture_source,
10276 .unsol_event = alc262_hippo1_unsol_event,
10277 .init_hook = alc262_hippo1_automute,
10279 [ALC262_FUJITSU] = {
10280 .mixers = { alc262_fujitsu_mixer },
10281 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10282 alc262_fujitsu_unsol_verbs },
10283 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10284 .dac_nids = alc262_dac_nids,
10286 .dig_out_nid = ALC262_DIGOUT_NID,
10287 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10288 .channel_mode = alc262_modes,
10289 .input_mux = &alc262_fujitsu_capture_source,
10290 .unsol_event = alc262_fujitsu_unsol_event,
10291 .init_hook = alc262_fujitsu_init_hook,
10293 [ALC262_HP_BPC] = {
10294 .mixers = { alc262_HP_BPC_mixer },
10295 .init_verbs = { alc262_HP_BPC_init_verbs },
10296 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10297 .dac_nids = alc262_dac_nids,
10299 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10300 .channel_mode = alc262_modes,
10301 .input_mux = &alc262_HP_capture_source,
10302 .unsol_event = alc262_hp_bpc_unsol_event,
10303 .init_hook = alc262_hp_bpc_automute,
10305 [ALC262_HP_BPC_D7000_WF] = {
10306 .mixers = { alc262_HP_BPC_WildWest_mixer },
10307 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10308 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10309 .dac_nids = alc262_dac_nids,
10311 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10312 .channel_mode = alc262_modes,
10313 .input_mux = &alc262_HP_D7000_capture_source,
10314 .unsol_event = alc262_hp_wildwest_unsol_event,
10315 .init_hook = alc262_hp_wildwest_automute,
10317 [ALC262_HP_BPC_D7000_WL] = {
10318 .mixers = { alc262_HP_BPC_WildWest_mixer,
10319 alc262_HP_BPC_WildWest_option_mixer },
10320 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10321 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10322 .dac_nids = alc262_dac_nids,
10324 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10325 .channel_mode = alc262_modes,
10326 .input_mux = &alc262_HP_D7000_capture_source,
10327 .unsol_event = alc262_hp_wildwest_unsol_event,
10328 .init_hook = alc262_hp_wildwest_automute,
10330 [ALC262_HP_TC_T5735] = {
10331 .mixers = { alc262_hp_t5735_mixer },
10332 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10333 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10334 .dac_nids = alc262_dac_nids,
10336 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10337 .channel_mode = alc262_modes,
10338 .input_mux = &alc262_capture_source,
10339 .unsol_event = alc262_hp_t5735_unsol_event,
10340 .init_hook = alc262_hp_t5735_init_hook,
10342 [ALC262_HP_RP5700] = {
10343 .mixers = { alc262_hp_rp5700_mixer },
10344 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10345 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10346 .dac_nids = alc262_dac_nids,
10347 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10348 .channel_mode = alc262_modes,
10349 .input_mux = &alc262_hp_rp5700_capture_source,
10351 [ALC262_BENQ_ED8] = {
10352 .mixers = { alc262_base_mixer },
10353 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10354 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10355 .dac_nids = alc262_dac_nids,
10357 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10358 .channel_mode = alc262_modes,
10359 .input_mux = &alc262_capture_source,
10361 [ALC262_SONY_ASSAMD] = {
10362 .mixers = { alc262_sony_mixer },
10363 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10364 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10365 .dac_nids = alc262_dac_nids,
10367 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10368 .channel_mode = alc262_modes,
10369 .input_mux = &alc262_capture_source,
10370 .unsol_event = alc262_hippo_unsol_event,
10371 .init_hook = alc262_hippo_automute,
10373 [ALC262_BENQ_T31] = {
10374 .mixers = { alc262_benq_t31_mixer },
10375 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10376 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10377 .dac_nids = alc262_dac_nids,
10379 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10380 .channel_mode = alc262_modes,
10381 .input_mux = &alc262_capture_source,
10382 .unsol_event = alc262_hippo_unsol_event,
10383 .init_hook = alc262_hippo_automute,
10386 .mixers = { alc262_ultra_mixer },
10387 .cap_mixer = alc262_ultra_capture_mixer,
10388 .init_verbs = { alc262_ultra_verbs },
10389 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10390 .dac_nids = alc262_dac_nids,
10391 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10392 .channel_mode = alc262_modes,
10393 .input_mux = &alc262_ultra_capture_source,
10394 .adc_nids = alc262_adc_nids, /* ADC0 */
10395 .capsrc_nids = alc262_capsrc_nids,
10396 .num_adc_nids = 1, /* single ADC */
10397 .unsol_event = alc262_ultra_unsol_event,
10398 .init_hook = alc262_ultra_automute,
10400 [ALC262_LENOVO_3000] = {
10401 .mixers = { alc262_lenovo_3000_mixer },
10402 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10403 alc262_lenovo_3000_unsol_verbs },
10404 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10405 .dac_nids = alc262_dac_nids,
10407 .dig_out_nid = ALC262_DIGOUT_NID,
10408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10409 .channel_mode = alc262_modes,
10410 .input_mux = &alc262_fujitsu_capture_source,
10411 .unsol_event = alc262_lenovo_3000_unsol_event,
10414 .mixers = { alc262_nec_mixer },
10415 .init_verbs = { alc262_nec_verbs },
10416 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10417 .dac_nids = alc262_dac_nids,
10419 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10420 .channel_mode = alc262_modes,
10421 .input_mux = &alc262_capture_source,
10423 [ALC262_TOSHIBA_S06] = {
10424 .mixers = { alc262_toshiba_s06_mixer },
10425 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10426 alc262_eapd_verbs },
10427 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10428 .capsrc_nids = alc262_dmic_capsrc_nids,
10429 .dac_nids = alc262_dac_nids,
10430 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10431 .dig_out_nid = ALC262_DIGOUT_NID,
10432 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10433 .channel_mode = alc262_modes,
10434 .input_mux = &alc262_dmic_capture_source,
10435 .unsol_event = alc262_toshiba_s06_unsol_event,
10436 .init_hook = alc262_toshiba_s06_init_hook,
10438 [ALC262_TOSHIBA_RX1] = {
10439 .mixers = { alc262_toshiba_rx1_mixer },
10440 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10441 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10442 .dac_nids = alc262_dac_nids,
10444 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10445 .channel_mode = alc262_modes,
10446 .input_mux = &alc262_capture_source,
10447 .unsol_event = alc262_hippo_unsol_event,
10448 .init_hook = alc262_hippo_automute,
10452 static int patch_alc262(struct hda_codec *codec)
10454 struct alc_spec *spec;
10458 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10462 codec->spec = spec;
10464 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10469 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10470 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10471 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10472 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10476 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10478 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10482 if (board_config < 0) {
10483 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10484 "trying auto-probe from BIOS...\n");
10485 board_config = ALC262_AUTO;
10488 if (board_config == ALC262_AUTO) {
10489 /* automatic parse from the BIOS config */
10490 err = alc262_parse_auto_config(codec);
10496 "hda_codec: Cannot set up configuration "
10497 "from BIOS. Using base mode...\n");
10498 board_config = ALC262_BASIC;
10502 if (board_config != ALC262_AUTO)
10503 setup_preset(spec, &alc262_presets[board_config]);
10505 spec->stream_name_analog = "ALC262 Analog";
10506 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10507 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10509 spec->stream_name_digital = "ALC262 Digital";
10510 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10511 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10513 spec->is_mix_capture = 1;
10514 if (!spec->adc_nids && spec->input_mux) {
10515 /* check whether NID 0x07 is valid */
10516 unsigned int wcap = get_wcaps(codec, 0x07);
10519 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10520 if (wcap != AC_WID_AUD_IN) {
10521 spec->adc_nids = alc262_adc_nids_alt;
10522 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10523 spec->capsrc_nids = alc262_capsrc_nids_alt;
10525 spec->adc_nids = alc262_adc_nids;
10526 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10527 spec->capsrc_nids = alc262_capsrc_nids;
10530 if (!spec->cap_mixer)
10531 set_capture_mixer(spec);
10533 spec->vmaster_nid = 0x0c;
10535 codec->patch_ops = alc_patch_ops;
10536 if (board_config == ALC262_AUTO)
10537 spec->init_hook = alc262_auto_init;
10538 #ifdef CONFIG_SND_HDA_POWER_SAVE
10539 if (!spec->loopback.amplist)
10540 spec->loopback.amplist = alc262_loopbacks;
10547 * ALC268 channel source setting (2 channel)
10549 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10550 #define alc268_modes alc260_modes
10552 static hda_nid_t alc268_dac_nids[2] = {
10557 static hda_nid_t alc268_adc_nids[2] = {
10562 static hda_nid_t alc268_adc_nids_alt[1] = {
10567 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10569 static struct snd_kcontrol_new alc268_base_mixer[] = {
10570 /* output mixer control */
10571 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10572 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10575 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10576 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10577 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10581 /* bind Beep switches of both NID 0x0f and 0x10 */
10582 static struct hda_bind_ctls alc268_bind_beep_sw = {
10583 .ops = &snd_hda_bind_sw,
10585 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10586 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10591 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10592 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10593 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10597 static struct hda_verb alc268_eapd_verbs[] = {
10598 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10599 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10603 /* Toshiba specific */
10604 #define alc268_toshiba_automute alc262_hippo_automute
10606 static struct hda_verb alc268_toshiba_verbs[] = {
10607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10611 static struct hda_input_mux alc268_acer_lc_capture_source = {
10619 /* Acer specific */
10620 /* bind volumes of both NID 0x02 and 0x03 */
10621 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10622 .ops = &snd_hda_bind_vol,
10624 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10625 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10630 /* mute/unmute internal speaker according to the hp jack and mute state */
10631 static void alc268_acer_automute(struct hda_codec *codec, int force)
10633 struct alc_spec *spec = codec->spec;
10636 if (force || !spec->sense_updated) {
10637 unsigned int present;
10638 present = snd_hda_codec_read(codec, 0x14, 0,
10639 AC_VERB_GET_PIN_SENSE, 0);
10640 spec->jack_present = (present & 0x80000000) != 0;
10641 spec->sense_updated = 1;
10643 if (spec->jack_present)
10644 mute = HDA_AMP_MUTE; /* mute internal speaker */
10645 else /* unmute internal speaker if necessary */
10646 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10647 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10648 HDA_AMP_MUTE, mute);
10652 /* bind hp and internal speaker mute (with plug check) */
10653 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10654 struct snd_ctl_elem_value *ucontrol)
10656 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10657 long *valp = ucontrol->value.integer.value;
10660 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10662 valp[0] ? 0 : HDA_AMP_MUTE);
10663 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10665 valp[1] ? 0 : HDA_AMP_MUTE);
10667 alc268_acer_automute(codec, 0);
10671 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10672 /* output mixer control */
10673 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10676 .name = "Master Playback Switch",
10677 .info = snd_hda_mixer_amp_switch_info,
10678 .get = snd_hda_mixer_amp_switch_get,
10679 .put = alc268_acer_master_sw_put,
10680 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10682 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10686 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10687 /* output mixer control */
10688 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10690 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10691 .name = "Master Playback Switch",
10692 .info = snd_hda_mixer_amp_switch_info,
10693 .get = snd_hda_mixer_amp_switch_get,
10694 .put = alc268_acer_master_sw_put,
10695 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10698 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10703 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10704 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10705 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10706 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10707 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10708 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10709 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10713 static struct hda_verb alc268_acer_verbs[] = {
10714 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10715 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10717 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10720 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10724 /* unsolicited event for HP jack sensing */
10725 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10728 if ((res >> 26) != ALC880_HP_EVENT)
10730 alc268_toshiba_automute(codec);
10733 static void alc268_acer_unsol_event(struct hda_codec *codec,
10736 if ((res >> 26) != ALC880_HP_EVENT)
10738 alc268_acer_automute(codec, 1);
10741 static void alc268_acer_init_hook(struct hda_codec *codec)
10743 alc268_acer_automute(codec, 1);
10746 /* toggle speaker-output according to the hp-jack state */
10747 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10749 unsigned int present;
10750 unsigned char bits;
10752 present = snd_hda_codec_read(codec, 0x15, 0,
10753 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10754 bits = present ? AMP_IN_MUTE(0) : 0;
10755 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10756 AMP_IN_MUTE(0), bits);
10757 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10758 AMP_IN_MUTE(0), bits);
10762 static void alc268_acer_mic_automute(struct hda_codec *codec)
10764 unsigned int present;
10766 present = snd_hda_codec_read(codec, 0x18, 0,
10767 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10768 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
10769 present ? 0x0 : 0x6);
10772 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
10775 if ((res >> 26) == ALC880_HP_EVENT)
10776 alc268_aspire_one_speaker_automute(codec);
10777 if ((res >> 26) == ALC880_MIC_EVENT)
10778 alc268_acer_mic_automute(codec);
10781 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
10783 alc268_aspire_one_speaker_automute(codec);
10784 alc268_acer_mic_automute(codec);
10787 static struct snd_kcontrol_new alc268_dell_mixer[] = {
10788 /* output mixer control */
10789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10790 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10791 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10794 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10798 static struct hda_verb alc268_dell_verbs[] = {
10799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10801 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10805 /* mute/unmute internal speaker according to the hp jack and mute state */
10806 static void alc268_dell_automute(struct hda_codec *codec)
10808 unsigned int present;
10811 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
10812 if (present & 0x80000000)
10813 mute = HDA_AMP_MUTE;
10815 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
10816 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10817 HDA_AMP_MUTE, mute);
10820 static void alc268_dell_unsol_event(struct hda_codec *codec,
10823 if ((res >> 26) != ALC880_HP_EVENT)
10825 alc268_dell_automute(codec);
10828 #define alc268_dell_init_hook alc268_dell_automute
10830 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10831 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10832 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10833 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10835 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10836 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10837 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10838 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10842 static struct hda_verb alc267_quanta_il1_verbs[] = {
10843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10844 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10848 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10850 unsigned int present;
10852 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10853 & AC_PINSENSE_PRESENCE;
10854 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10855 present ? 0 : PIN_OUT);
10858 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10860 unsigned int present;
10862 present = snd_hda_codec_read(codec, 0x18, 0,
10863 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10864 snd_hda_codec_write(codec, 0x23, 0,
10865 AC_VERB_SET_CONNECT_SEL,
10866 present ? 0x00 : 0x01);
10869 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10871 alc267_quanta_il1_hp_automute(codec);
10872 alc267_quanta_il1_mic_automute(codec);
10875 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10878 switch (res >> 26) {
10879 case ALC880_HP_EVENT:
10880 alc267_quanta_il1_hp_automute(codec);
10882 case ALC880_MIC_EVENT:
10883 alc267_quanta_il1_mic_automute(codec);
10889 * generic initialization of ADC, input mixers and output mixers
10891 static struct hda_verb alc268_base_init_verbs[] = {
10892 /* Unmute DAC0-1 and set vol = 0 */
10893 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10894 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10895 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10896 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10897 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10898 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10901 * Set up output mixers (0x0c - 0x0e)
10903 /* set vol=0 to output mixers */
10904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10905 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10906 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10907 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10909 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10910 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10914 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10915 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10917 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10918 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10919 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10921 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10923 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10925 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10926 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10927 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10929 /* set PCBEEP vol = 0, mute connections */
10930 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10931 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10932 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10934 /* Unmute Selector 23h,24h and set the default input to mic-in */
10936 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10937 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10938 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10945 * generic initialization of ADC, input mixers and output mixers
10947 static struct hda_verb alc268_volume_init_verbs[] = {
10948 /* set output DAC */
10949 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10950 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10951 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10952 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10954 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10957 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10958 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10960 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10963 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10964 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10967 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10968 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10969 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10971 /* set PCBEEP vol = 0, mute connections */
10972 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10973 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10974 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10979 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10980 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10981 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10983 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10984 /* The multiple "Capture Source" controls confuse alsamixer
10985 * So call somewhat different..
10987 /* .name = "Capture Source", */
10988 .name = "Input Source",
10990 .info = alc_mux_enum_info,
10991 .get = alc_mux_enum_get,
10992 .put = alc_mux_enum_put,
10997 static struct snd_kcontrol_new alc268_capture_mixer[] = {
10998 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10999 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11000 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11001 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11004 /* The multiple "Capture Source" controls confuse alsamixer
11005 * So call somewhat different..
11007 /* .name = "Capture Source", */
11008 .name = "Input Source",
11010 .info = alc_mux_enum_info,
11011 .get = alc_mux_enum_get,
11012 .put = alc_mux_enum_put,
11017 static struct hda_input_mux alc268_capture_source = {
11021 { "Front Mic", 0x1 },
11027 static struct hda_input_mux alc268_acer_capture_source = {
11031 { "Internal Mic", 0x6 },
11036 #ifdef CONFIG_SND_DEBUG
11037 static struct snd_kcontrol_new alc268_test_mixer[] = {
11038 /* Volume widgets */
11039 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11040 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11041 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11042 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11043 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11044 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11045 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11046 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11047 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11048 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11049 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11050 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11051 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11052 /* The below appears problematic on some hardwares */
11053 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11054 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11055 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11056 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11057 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11059 /* Modes for retasking pin widgets */
11060 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11061 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11062 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11063 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11065 /* Controls for GPIO pins, assuming they are configured as outputs */
11066 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11067 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11068 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11069 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11071 /* Switches to allow the digital SPDIF output pin to be enabled.
11072 * The ALC268 does not have an SPDIF input.
11074 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11076 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11077 * this output to turn on an external amplifier.
11079 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11080 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11086 /* create input playback/capture controls for the given pin */
11087 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11088 const char *ctlname, int idx)
11093 sprintf(name, "%s Playback Volume", ctlname);
11095 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11096 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11100 } else if (nid == 0x15) {
11101 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11102 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11108 sprintf(name, "%s Playback Switch", ctlname);
11109 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11110 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11116 /* add playback controls from the parsed DAC table */
11117 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11118 const struct auto_pin_cfg *cfg)
11123 spec->multiout.num_dacs = 2; /* only use one dac */
11124 spec->multiout.dac_nids = spec->private_dac_nids;
11125 spec->multiout.dac_nids[0] = 2;
11126 spec->multiout.dac_nids[1] = 3;
11128 nid = cfg->line_out_pins[0];
11130 alc268_new_analog_output(spec, nid, "Front", 0);
11132 nid = cfg->speaker_pins[0];
11134 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11135 "Speaker Playback Volume",
11136 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11140 nid = cfg->hp_pins[0];
11142 alc268_new_analog_output(spec, nid, "Headphone", 0);
11144 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11146 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11147 "Mono Playback Switch",
11148 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11155 /* create playback/capture controls for input pins */
11156 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11157 const struct auto_pin_cfg *cfg)
11159 struct hda_input_mux *imux = &spec->private_imux;
11162 for (i = 0; i < AUTO_PIN_LAST; i++) {
11163 switch(cfg->input_pins[i]) {
11165 idx1 = 0; /* Mic 1 */
11168 idx1 = 1; /* Mic 2 */
11171 idx1 = 2; /* Line In */
11178 idx1 = 6; /* digital mics */
11183 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11184 imux->items[imux->num_items].index = idx1;
11190 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11192 struct alc_spec *spec = codec->spec;
11193 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11194 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11195 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11196 unsigned int dac_vol1, dac_vol2;
11199 snd_hda_codec_write(codec, speaker_nid, 0,
11200 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11201 snd_hda_codec_write(codec, 0x0f, 0,
11202 AC_VERB_SET_AMP_GAIN_MUTE,
11204 snd_hda_codec_write(codec, 0x10, 0,
11205 AC_VERB_SET_AMP_GAIN_MUTE,
11208 snd_hda_codec_write(codec, 0x0f, 0,
11209 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11210 snd_hda_codec_write(codec, 0x10, 0,
11211 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11214 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11215 if (line_nid == 0x14)
11216 dac_vol2 = AMP_OUT_ZERO;
11217 else if (line_nid == 0x15)
11218 dac_vol1 = AMP_OUT_ZERO;
11219 if (hp_nid == 0x14)
11220 dac_vol2 = AMP_OUT_ZERO;
11221 else if (hp_nid == 0x15)
11222 dac_vol1 = AMP_OUT_ZERO;
11223 if (line_nid != 0x16 || hp_nid != 0x16 ||
11224 spec->autocfg.line_out_pins[1] != 0x16 ||
11225 spec->autocfg.line_out_pins[2] != 0x16)
11226 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11228 snd_hda_codec_write(codec, 0x02, 0,
11229 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11230 snd_hda_codec_write(codec, 0x03, 0,
11231 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11234 /* pcm configuration: identiacal with ALC880 */
11235 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11236 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11237 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11238 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11241 * BIOS auto configuration
11243 static int alc268_parse_auto_config(struct hda_codec *codec)
11245 struct alc_spec *spec = codec->spec;
11247 static hda_nid_t alc268_ignore[] = { 0 };
11249 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11253 if (!spec->autocfg.line_outs)
11254 return 0; /* can't find valid BIOS pin config */
11256 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11259 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11263 spec->multiout.max_channels = 2;
11265 /* digital only support output */
11266 if (spec->autocfg.dig_out_pin)
11267 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11269 if (spec->kctls.list)
11270 add_mixer(spec, spec->kctls.list);
11272 if (spec->autocfg.speaker_pins[0] != 0x1d)
11273 add_mixer(spec, alc268_beep_mixer);
11275 add_verb(spec, alc268_volume_init_verbs);
11276 spec->num_mux_defs = 1;
11277 spec->input_mux = &spec->private_imux;
11279 err = alc_auto_add_mic_boost(codec);
11283 store_pin_configs(codec);
11287 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11288 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11289 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11291 /* init callback for auto-configuration model -- overriding the default init */
11292 static void alc268_auto_init(struct hda_codec *codec)
11294 struct alc_spec *spec = codec->spec;
11295 alc268_auto_init_multi_out(codec);
11296 alc268_auto_init_hp_out(codec);
11297 alc268_auto_init_mono_speaker_out(codec);
11298 alc268_auto_init_analog_input(codec);
11299 if (spec->unsol_event)
11300 alc_inithook(codec);
11304 * configuration and preset
11306 static const char *alc268_models[ALC268_MODEL_LAST] = {
11307 [ALC267_QUANTA_IL1] = "quanta-il1",
11308 [ALC268_3ST] = "3stack",
11309 [ALC268_TOSHIBA] = "toshiba",
11310 [ALC268_ACER] = "acer",
11311 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11312 [ALC268_DELL] = "dell",
11313 [ALC268_ZEPTO] = "zepto",
11314 #ifdef CONFIG_SND_DEBUG
11315 [ALC268_TEST] = "test",
11317 [ALC268_AUTO] = "auto",
11320 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11321 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11322 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11323 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11324 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11325 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11326 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11327 ALC268_ACER_ASPIRE_ONE),
11328 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11329 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11330 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11331 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11332 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11333 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11334 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11335 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11336 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11337 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11341 static struct alc_config_preset alc268_presets[] = {
11342 [ALC267_QUANTA_IL1] = {
11343 .mixers = { alc267_quanta_il1_mixer },
11344 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11345 alc267_quanta_il1_verbs },
11346 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11347 .dac_nids = alc268_dac_nids,
11348 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11349 .adc_nids = alc268_adc_nids_alt,
11351 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11352 .channel_mode = alc268_modes,
11353 .input_mux = &alc268_capture_source,
11354 .unsol_event = alc267_quanta_il1_unsol_event,
11355 .init_hook = alc267_quanta_il1_automute,
11358 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11359 alc268_beep_mixer },
11360 .init_verbs = { alc268_base_init_verbs },
11361 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11362 .dac_nids = alc268_dac_nids,
11363 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11364 .adc_nids = alc268_adc_nids_alt,
11365 .capsrc_nids = alc268_capsrc_nids,
11367 .dig_out_nid = ALC268_DIGOUT_NID,
11368 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11369 .channel_mode = alc268_modes,
11370 .input_mux = &alc268_capture_source,
11372 [ALC268_TOSHIBA] = {
11373 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11374 alc268_beep_mixer },
11375 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11376 alc268_toshiba_verbs },
11377 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11378 .dac_nids = alc268_dac_nids,
11379 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11380 .adc_nids = alc268_adc_nids_alt,
11381 .capsrc_nids = alc268_capsrc_nids,
11383 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11384 .channel_mode = alc268_modes,
11385 .input_mux = &alc268_capture_source,
11386 .unsol_event = alc268_toshiba_unsol_event,
11387 .init_hook = alc268_toshiba_automute,
11390 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11391 alc268_beep_mixer },
11392 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11393 alc268_acer_verbs },
11394 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11395 .dac_nids = alc268_dac_nids,
11396 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11397 .adc_nids = alc268_adc_nids_alt,
11398 .capsrc_nids = alc268_capsrc_nids,
11400 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11401 .channel_mode = alc268_modes,
11402 .input_mux = &alc268_acer_capture_source,
11403 .unsol_event = alc268_acer_unsol_event,
11404 .init_hook = alc268_acer_init_hook,
11406 [ALC268_ACER_ASPIRE_ONE] = {
11407 .mixers = { alc268_acer_aspire_one_mixer,
11408 alc268_capture_alt_mixer },
11409 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11410 alc268_acer_aspire_one_verbs },
11411 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11412 .dac_nids = alc268_dac_nids,
11413 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11414 .adc_nids = alc268_adc_nids_alt,
11415 .capsrc_nids = alc268_capsrc_nids,
11417 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11418 .channel_mode = alc268_modes,
11419 .input_mux = &alc268_acer_lc_capture_source,
11420 .unsol_event = alc268_acer_lc_unsol_event,
11421 .init_hook = alc268_acer_lc_init_hook,
11424 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11425 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11426 alc268_dell_verbs },
11427 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11428 .dac_nids = alc268_dac_nids,
11430 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11431 .channel_mode = alc268_modes,
11432 .unsol_event = alc268_dell_unsol_event,
11433 .init_hook = alc268_dell_init_hook,
11434 .input_mux = &alc268_capture_source,
11437 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11438 alc268_beep_mixer },
11439 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11440 alc268_toshiba_verbs },
11441 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11442 .dac_nids = alc268_dac_nids,
11443 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11444 .adc_nids = alc268_adc_nids_alt,
11445 .capsrc_nids = alc268_capsrc_nids,
11447 .dig_out_nid = ALC268_DIGOUT_NID,
11448 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11449 .channel_mode = alc268_modes,
11450 .input_mux = &alc268_capture_source,
11451 .unsol_event = alc268_toshiba_unsol_event,
11452 .init_hook = alc268_toshiba_automute
11454 #ifdef CONFIG_SND_DEBUG
11456 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11457 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11458 alc268_volume_init_verbs },
11459 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11460 .dac_nids = alc268_dac_nids,
11461 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11462 .adc_nids = alc268_adc_nids_alt,
11463 .capsrc_nids = alc268_capsrc_nids,
11465 .dig_out_nid = ALC268_DIGOUT_NID,
11466 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11467 .channel_mode = alc268_modes,
11468 .input_mux = &alc268_capture_source,
11473 static int patch_alc268(struct hda_codec *codec)
11475 struct alc_spec *spec;
11479 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11483 codec->spec = spec;
11485 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11489 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11490 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11491 "trying auto-probe from BIOS...\n");
11492 board_config = ALC268_AUTO;
11495 if (board_config == ALC268_AUTO) {
11496 /* automatic parse from the BIOS config */
11497 err = alc268_parse_auto_config(codec);
11503 "hda_codec: Cannot set up configuration "
11504 "from BIOS. Using base mode...\n");
11505 board_config = ALC268_3ST;
11509 if (board_config != ALC268_AUTO)
11510 setup_preset(spec, &alc268_presets[board_config]);
11512 if (codec->vendor_id == 0x10ec0267) {
11513 spec->stream_name_analog = "ALC267 Analog";
11514 spec->stream_name_digital = "ALC267 Digital";
11516 spec->stream_name_analog = "ALC268 Analog";
11517 spec->stream_name_digital = "ALC268 Digital";
11520 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11521 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11522 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11524 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11526 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11527 /* override the amp caps for beep generator */
11528 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11529 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11530 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11531 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11532 (0 << AC_AMPCAP_MUTE_SHIFT));
11534 if (!spec->adc_nids && spec->input_mux) {
11535 /* check whether NID 0x07 is valid */
11536 unsigned int wcap = get_wcaps(codec, 0x07);
11540 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11541 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11542 spec->adc_nids = alc268_adc_nids_alt;
11543 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11544 add_mixer(spec, alc268_capture_alt_mixer);
11546 spec->adc_nids = alc268_adc_nids;
11547 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11548 add_mixer(spec, alc268_capture_mixer);
11550 spec->capsrc_nids = alc268_capsrc_nids;
11551 /* set default input source */
11552 for (i = 0; i < spec->num_adc_nids; i++)
11553 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11554 0, AC_VERB_SET_CONNECT_SEL,
11555 spec->input_mux->items[0].index);
11558 spec->vmaster_nid = 0x02;
11560 codec->patch_ops = alc_patch_ops;
11561 if (board_config == ALC268_AUTO)
11562 spec->init_hook = alc268_auto_init;
11568 * ALC269 channel source setting (2 channel)
11570 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11572 #define alc269_dac_nids alc260_dac_nids
11574 static hda_nid_t alc269_adc_nids[1] = {
11579 static hda_nid_t alc269_capsrc_nids[1] = {
11583 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11587 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11595 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11603 #define alc269_modes alc260_modes
11604 #define alc269_capture_source alc880_lg_lw_capture_source
11606 static struct snd_kcontrol_new alc269_base_mixer[] = {
11607 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11608 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11609 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11610 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11611 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11612 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11613 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11614 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11617 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11618 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11620 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11624 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11625 /* output mixer control */
11626 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11629 .name = "Master Playback Switch",
11630 .info = snd_hda_mixer_amp_switch_info,
11631 .get = snd_hda_mixer_amp_switch_get,
11632 .put = alc268_acer_master_sw_put,
11633 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11637 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11638 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11639 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11640 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11641 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11642 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11646 /* bind volumes of both NID 0x0c and 0x0d */
11647 static struct hda_bind_ctls alc269_epc_bind_vol = {
11648 .ops = &snd_hda_bind_vol,
11650 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11651 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11656 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11657 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11658 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11659 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11663 /* capture mixer elements */
11664 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11665 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11666 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11667 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11672 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11673 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11675 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11680 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11681 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11682 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11686 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11687 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11688 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11690 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11691 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11692 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11696 /* toggle speaker-output according to the hp-jack state */
11697 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11699 unsigned int present;
11700 unsigned char bits;
11702 present = snd_hda_codec_read(codec, 0x15, 0,
11703 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11704 bits = present ? AMP_IN_MUTE(0) : 0;
11705 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11706 AMP_IN_MUTE(0), bits);
11707 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11708 AMP_IN_MUTE(0), bits);
11710 snd_hda_codec_write(codec, 0x20, 0,
11711 AC_VERB_SET_COEF_INDEX, 0x0c);
11712 snd_hda_codec_write(codec, 0x20, 0,
11713 AC_VERB_SET_PROC_COEF, 0x680);
11715 snd_hda_codec_write(codec, 0x20, 0,
11716 AC_VERB_SET_COEF_INDEX, 0x0c);
11717 snd_hda_codec_write(codec, 0x20, 0,
11718 AC_VERB_SET_PROC_COEF, 0x480);
11721 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11723 unsigned int present;
11725 present = snd_hda_codec_read(codec, 0x18, 0,
11726 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11727 snd_hda_codec_write(codec, 0x23, 0,
11728 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11731 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11734 if ((res >> 26) == ALC880_HP_EVENT)
11735 alc269_quanta_fl1_speaker_automute(codec);
11736 if ((res >> 26) == ALC880_MIC_EVENT)
11737 alc269_quanta_fl1_mic_automute(codec);
11740 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11742 alc269_quanta_fl1_speaker_automute(codec);
11743 alc269_quanta_fl1_mic_automute(codec);
11746 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11747 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11748 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
11749 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
11751 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11752 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11753 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11757 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
11758 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11759 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
11760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
11761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
11762 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11763 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11767 /* toggle speaker-output according to the hp-jack state */
11768 static void alc269_speaker_automute(struct hda_codec *codec)
11770 unsigned int present;
11771 unsigned char bits;
11773 present = snd_hda_codec_read(codec, 0x15, 0,
11774 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11775 bits = present ? AMP_IN_MUTE(0) : 0;
11776 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11777 AMP_IN_MUTE(0), bits);
11778 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11779 AMP_IN_MUTE(0), bits);
11782 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
11784 unsigned int present;
11786 present = snd_hda_codec_read(codec, 0x18, 0,
11787 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11788 snd_hda_codec_write(codec, 0x23, 0,
11789 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
11792 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
11794 unsigned int present;
11796 present = snd_hda_codec_read(codec, 0x18, 0,
11797 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11798 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11799 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
11800 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11801 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
11804 /* unsolicited event for HP jack sensing */
11805 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
11808 if ((res >> 26) == ALC880_HP_EVENT)
11809 alc269_speaker_automute(codec);
11811 if ((res >> 26) == ALC880_MIC_EVENT)
11812 alc269_eeepc_dmic_automute(codec);
11815 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
11817 alc269_speaker_automute(codec);
11818 alc269_eeepc_dmic_automute(codec);
11821 /* unsolicited event for HP jack sensing */
11822 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
11825 if ((res >> 26) == ALC880_HP_EVENT)
11826 alc269_speaker_automute(codec);
11828 if ((res >> 26) == ALC880_MIC_EVENT)
11829 alc269_eeepc_amic_automute(codec);
11832 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
11834 alc269_speaker_automute(codec);
11835 alc269_eeepc_amic_automute(codec);
11839 * generic initialization of ADC, input mixers and output mixers
11841 static struct hda_verb alc269_init_verbs[] = {
11843 * Unmute ADC0 and set the default input to mic-in
11845 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11847 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
11848 * analog-loopback mixer widget
11849 * Note: PASD motherboards uses the Line In 2 as the input for
11850 * front panel mic (mic 2)
11852 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11853 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11854 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11855 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11860 * Set up output mixers (0x0c - 0x0e)
11862 /* set vol=0 to output mixers */
11863 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11864 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11866 /* set up input amps for analog loopback */
11867 /* Amp Indices: DAC = 0, mixer = 1 */
11868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11871 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11873 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11877 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11879 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11880 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11881 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11883 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11884 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11885 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11888 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11889 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11891 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11892 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11894 /* FIXME: use matrix-type input source selection */
11895 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
11896 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11899 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11900 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11903 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11904 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11908 /* add playback controls from the parsed DAC table */
11909 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
11910 const struct auto_pin_cfg *cfg)
11915 spec->multiout.num_dacs = 1; /* only use one dac */
11916 spec->multiout.dac_nids = spec->private_dac_nids;
11917 spec->multiout.dac_nids[0] = 2;
11919 nid = cfg->line_out_pins[0];
11921 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11922 "Front Playback Volume",
11923 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
11926 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11927 "Front Playback Switch",
11928 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11933 nid = cfg->speaker_pins[0];
11935 if (!cfg->line_out_pins[0]) {
11936 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11937 "Speaker Playback Volume",
11938 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11944 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11945 "Speaker Playback Switch",
11946 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11951 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11952 "Speaker Playback Switch",
11953 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11959 nid = cfg->hp_pins[0];
11961 /* spec->multiout.hp_nid = 2; */
11962 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
11963 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11964 "Headphone Playback Volume",
11965 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
11971 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11972 "Headphone Playback Switch",
11973 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11978 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11979 "Headphone Playback Switch",
11980 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11989 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
11990 const struct auto_pin_cfg *cfg)
11994 err = alc880_auto_create_analog_input_ctls(spec, cfg);
11997 /* digital-mic input pin is excluded in alc880_auto_create..()
11998 * because it's under 0x18
12000 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12001 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12002 struct hda_input_mux *imux = &spec->private_imux;
12003 imux->items[imux->num_items].label = "Int Mic";
12004 imux->items[imux->num_items].index = 0x05;
12010 #ifdef CONFIG_SND_HDA_POWER_SAVE
12011 #define alc269_loopbacks alc880_loopbacks
12014 /* pcm configuration: identiacal with ALC880 */
12015 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12016 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12017 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12018 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12021 * BIOS auto configuration
12023 static int alc269_parse_auto_config(struct hda_codec *codec)
12025 struct alc_spec *spec = codec->spec;
12027 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12029 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12034 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12037 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12041 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12043 if (spec->autocfg.dig_out_pin)
12044 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12046 if (spec->kctls.list)
12047 add_mixer(spec, spec->kctls.list);
12049 /* create a beep mixer control if the pin 0x1d isn't assigned */
12050 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12051 if (spec->autocfg.input_pins[i] == 0x1d)
12053 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12054 add_mixer(spec, alc269_beep_mixer);
12056 add_verb(spec, alc269_init_verbs);
12057 spec->num_mux_defs = 1;
12058 spec->input_mux = &spec->private_imux;
12059 /* set default input source */
12060 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12061 0, AC_VERB_SET_CONNECT_SEL,
12062 spec->input_mux->items[0].index);
12064 err = alc_auto_add_mic_boost(codec);
12068 if (!spec->cap_mixer)
12069 set_capture_mixer(spec);
12071 store_pin_configs(codec);
12075 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12076 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12077 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12080 /* init callback for auto-configuration model -- overriding the default init */
12081 static void alc269_auto_init(struct hda_codec *codec)
12083 struct alc_spec *spec = codec->spec;
12084 alc269_auto_init_multi_out(codec);
12085 alc269_auto_init_hp_out(codec);
12086 alc269_auto_init_analog_input(codec);
12087 if (spec->unsol_event)
12088 alc_inithook(codec);
12092 * configuration and preset
12094 static const char *alc269_models[ALC269_MODEL_LAST] = {
12095 [ALC269_BASIC] = "basic",
12096 [ALC269_QUANTA_FL1] = "quanta",
12097 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12098 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12099 [ALC269_FUJITSU] = "fujitsu"
12102 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12103 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12104 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12105 ALC269_ASUS_EEEPC_P703),
12106 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12107 ALC269_ASUS_EEEPC_P901),
12108 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12109 ALC269_ASUS_EEEPC_P901),
12110 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12114 static struct alc_config_preset alc269_presets[] = {
12116 .mixers = { alc269_base_mixer },
12117 .init_verbs = { alc269_init_verbs },
12118 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12119 .dac_nids = alc269_dac_nids,
12121 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12122 .channel_mode = alc269_modes,
12123 .input_mux = &alc269_capture_source,
12125 [ALC269_QUANTA_FL1] = {
12126 .mixers = { alc269_quanta_fl1_mixer },
12127 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12128 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12129 .dac_nids = alc269_dac_nids,
12131 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12132 .channel_mode = alc269_modes,
12133 .input_mux = &alc269_capture_source,
12134 .unsol_event = alc269_quanta_fl1_unsol_event,
12135 .init_hook = alc269_quanta_fl1_init_hook,
12137 [ALC269_ASUS_EEEPC_P703] = {
12138 .mixers = { alc269_eeepc_mixer },
12139 .cap_mixer = alc269_epc_capture_mixer,
12140 .init_verbs = { alc269_init_verbs,
12141 alc269_eeepc_amic_init_verbs },
12142 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12143 .dac_nids = alc269_dac_nids,
12145 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12146 .channel_mode = alc269_modes,
12147 .input_mux = &alc269_eeepc_amic_capture_source,
12148 .unsol_event = alc269_eeepc_amic_unsol_event,
12149 .init_hook = alc269_eeepc_amic_inithook,
12151 [ALC269_ASUS_EEEPC_P901] = {
12152 .mixers = { alc269_eeepc_mixer },
12153 .cap_mixer = alc269_epc_capture_mixer,
12154 .init_verbs = { alc269_init_verbs,
12155 alc269_eeepc_dmic_init_verbs },
12156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12157 .dac_nids = alc269_dac_nids,
12159 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12160 .channel_mode = alc269_modes,
12161 .input_mux = &alc269_eeepc_dmic_capture_source,
12162 .unsol_event = alc269_eeepc_dmic_unsol_event,
12163 .init_hook = alc269_eeepc_dmic_inithook,
12165 [ALC269_FUJITSU] = {
12166 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12167 .cap_mixer = alc269_epc_capture_mixer,
12168 .init_verbs = { alc269_init_verbs,
12169 alc269_eeepc_dmic_init_verbs },
12170 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12171 .dac_nids = alc269_dac_nids,
12173 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12174 .channel_mode = alc269_modes,
12175 .input_mux = &alc269_eeepc_dmic_capture_source,
12176 .unsol_event = alc269_eeepc_dmic_unsol_event,
12177 .init_hook = alc269_eeepc_dmic_inithook,
12181 static int patch_alc269(struct hda_codec *codec)
12183 struct alc_spec *spec;
12187 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12191 codec->spec = spec;
12193 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12195 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12199 if (board_config < 0) {
12200 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12201 "trying auto-probe from BIOS...\n");
12202 board_config = ALC269_AUTO;
12205 if (board_config == ALC269_AUTO) {
12206 /* automatic parse from the BIOS config */
12207 err = alc269_parse_auto_config(codec);
12213 "hda_codec: Cannot set up configuration "
12214 "from BIOS. Using base mode...\n");
12215 board_config = ALC269_BASIC;
12219 if (board_config != ALC269_AUTO)
12220 setup_preset(spec, &alc269_presets[board_config]);
12222 spec->stream_name_analog = "ALC269 Analog";
12223 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12224 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12226 spec->stream_name_digital = "ALC269 Digital";
12227 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12228 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12230 spec->adc_nids = alc269_adc_nids;
12231 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12232 spec->capsrc_nids = alc269_capsrc_nids;
12233 if (!spec->cap_mixer)
12234 set_capture_mixer(spec);
12236 codec->patch_ops = alc_patch_ops;
12237 if (board_config == ALC269_AUTO)
12238 spec->init_hook = alc269_auto_init;
12239 #ifdef CONFIG_SND_HDA_POWER_SAVE
12240 if (!spec->loopback.amplist)
12241 spec->loopback.amplist = alc269_loopbacks;
12248 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12252 * set the path ways for 2 channel output
12253 * need to set the codec line out and mic 1 pin widgets to inputs
12255 static struct hda_verb alc861_threestack_ch2_init[] = {
12256 /* set pin widget 1Ah (line in) for input */
12257 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12258 /* set pin widget 18h (mic1/2) for input, for mic also enable
12261 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12263 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12265 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12266 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12272 * need to set the codec line out and mic 1 pin widgets to outputs
12274 static struct hda_verb alc861_threestack_ch6_init[] = {
12275 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12276 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12277 /* set pin widget 18h (mic1) for output (CLFE)*/
12278 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12280 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12281 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12283 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12285 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12286 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12291 static struct hda_channel_mode alc861_threestack_modes[2] = {
12292 { 2, alc861_threestack_ch2_init },
12293 { 6, alc861_threestack_ch6_init },
12295 /* Set mic1 as input and unmute the mixer */
12296 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12297 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12298 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12301 /* Set mic1 as output and mute mixer */
12302 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12303 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12304 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12308 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12309 { 2, alc861_uniwill_m31_ch2_init },
12310 { 4, alc861_uniwill_m31_ch4_init },
12313 /* Set mic1 and line-in as input and unmute the mixer */
12314 static struct hda_verb alc861_asus_ch2_init[] = {
12315 /* set pin widget 1Ah (line in) for input */
12316 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12317 /* set pin widget 18h (mic1/2) for input, for mic also enable
12320 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12322 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12324 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12325 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12329 /* Set mic1 nad line-in as output and mute mixer */
12330 static struct hda_verb alc861_asus_ch6_init[] = {
12331 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12332 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12333 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12334 /* set pin widget 18h (mic1) for output (CLFE)*/
12335 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12336 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12337 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12338 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12340 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12342 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12343 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12348 static struct hda_channel_mode alc861_asus_modes[2] = {
12349 { 2, alc861_asus_ch2_init },
12350 { 6, alc861_asus_ch6_init },
12355 static struct snd_kcontrol_new alc861_base_mixer[] = {
12356 /* output mixer control */
12357 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12358 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12359 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12360 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12361 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12363 /*Input mixer control */
12364 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12365 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12366 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12367 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12368 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12369 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12371 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12372 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12373 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12378 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12379 /* output mixer control */
12380 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12381 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12382 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12383 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12384 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12386 /* Input mixer control */
12387 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12388 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12389 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12390 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12391 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12392 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12393 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12394 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12395 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12396 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12400 .name = "Channel Mode",
12401 .info = alc_ch_mode_info,
12402 .get = alc_ch_mode_get,
12403 .put = alc_ch_mode_put,
12404 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12409 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12410 /* output mixer control */
12411 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12413 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12418 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12419 /* output mixer control */
12420 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12421 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12422 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12423 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12424 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12426 /* Input mixer control */
12427 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12428 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12429 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12430 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12431 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12432 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12434 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12440 .name = "Channel Mode",
12441 .info = alc_ch_mode_info,
12442 .get = alc_ch_mode_get,
12443 .put = alc_ch_mode_put,
12444 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12449 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12450 /* output mixer control */
12451 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12452 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12453 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12454 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12455 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12457 /* Input mixer control */
12458 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12459 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12460 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12461 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12462 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12463 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12465 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12466 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12467 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12471 .name = "Channel Mode",
12472 .info = alc_ch_mode_info,
12473 .get = alc_ch_mode_get,
12474 .put = alc_ch_mode_put,
12475 .private_value = ARRAY_SIZE(alc861_asus_modes),
12480 /* additional mixer */
12481 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12482 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12483 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12484 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12485 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12490 * generic initialization of ADC, input mixers and output mixers
12492 static struct hda_verb alc861_base_init_verbs[] = {
12494 * Unmute ADC0 and set the default input to mic-in
12496 /* port-A for surround (rear panel) */
12497 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12498 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12499 /* port-B for mic-in (rear panel) with vref */
12500 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12501 /* port-C for line-in (rear panel) */
12502 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12503 /* port-D for Front */
12504 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12505 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12506 /* port-E for HP out (front panel) */
12507 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12508 /* route front PCM to HP */
12509 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12510 /* port-F for mic-in (front panel) with vref */
12511 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12512 /* port-G for CLFE (rear panel) */
12513 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12514 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12515 /* port-H for side (rear panel) */
12516 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12517 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12519 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12520 /* route front mic to ADC1*/
12521 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12524 /* Unmute DAC0~3 & spdif out*/
12525 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12526 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12528 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12531 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12532 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12533 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12534 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12535 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12537 /* Unmute Stereo Mixer 15 */
12538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12543 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12545 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12546 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12548 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12549 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12551 /* hp used DAC 3 (Front) */
12552 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12558 static struct hda_verb alc861_threestack_init_verbs[] = {
12560 * Unmute ADC0 and set the default input to mic-in
12562 /* port-A for surround (rear panel) */
12563 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12564 /* port-B for mic-in (rear panel) with vref */
12565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12566 /* port-C for line-in (rear panel) */
12567 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12568 /* port-D for Front */
12569 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12570 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12571 /* port-E for HP out (front panel) */
12572 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12573 /* route front PCM to HP */
12574 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12575 /* port-F for mic-in (front panel) with vref */
12576 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12577 /* port-G for CLFE (rear panel) */
12578 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12579 /* port-H for side (rear panel) */
12580 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12582 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12583 /* route front mic to ADC1*/
12584 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12585 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12586 /* Unmute DAC0~3 & spdif out*/
12587 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12588 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12589 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12590 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12593 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12594 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12595 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12596 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12597 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12599 /* Unmute Stereo Mixer 15 */
12600 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12602 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12605 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12607 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12608 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12610 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12611 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12612 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12613 /* hp used DAC 3 (Front) */
12614 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12615 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12619 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12621 * Unmute ADC0 and set the default input to mic-in
12623 /* port-A for surround (rear panel) */
12624 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12625 /* port-B for mic-in (rear panel) with vref */
12626 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12627 /* port-C for line-in (rear panel) */
12628 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12629 /* port-D for Front */
12630 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12631 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12632 /* port-E for HP out (front panel) */
12633 /* this has to be set to VREF80 */
12634 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12635 /* route front PCM to HP */
12636 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12637 /* port-F for mic-in (front panel) with vref */
12638 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12639 /* port-G for CLFE (rear panel) */
12640 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12641 /* port-H for side (rear panel) */
12642 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12644 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12645 /* route front mic to ADC1*/
12646 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12648 /* Unmute DAC0~3 & spdif out*/
12649 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12650 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12651 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12652 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12653 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12655 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12656 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12657 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12658 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12659 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12661 /* Unmute Stereo Mixer 15 */
12662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12665 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12668 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12669 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12670 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12671 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12672 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12673 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12674 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12675 /* hp used DAC 3 (Front) */
12676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12677 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12681 static struct hda_verb alc861_asus_init_verbs[] = {
12683 * Unmute ADC0 and set the default input to mic-in
12685 /* port-A for surround (rear panel)
12686 * according to codec#0 this is the HP jack
12688 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12689 /* route front PCM to HP */
12690 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12691 /* port-B for mic-in (rear panel) with vref */
12692 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12693 /* port-C for line-in (rear panel) */
12694 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12695 /* port-D for Front */
12696 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12697 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12698 /* port-E for HP out (front panel) */
12699 /* this has to be set to VREF80 */
12700 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12701 /* route front PCM to HP */
12702 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12703 /* port-F for mic-in (front panel) with vref */
12704 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12705 /* port-G for CLFE (rear panel) */
12706 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12707 /* port-H for side (rear panel) */
12708 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12710 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12711 /* route front mic to ADC1*/
12712 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12714 /* Unmute DAC0~3 & spdif out*/
12715 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12716 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12717 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12718 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12720 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12721 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12722 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12723 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12724 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12726 /* Unmute Stereo Mixer 15 */
12727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12728 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12729 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12730 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12732 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12733 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12734 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12735 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12736 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12737 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12738 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12740 /* hp used DAC 3 (Front) */
12741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12746 /* additional init verbs for ASUS laptops */
12747 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
12748 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
12749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
12754 * generic initialization of ADC, input mixers and output mixers
12756 static struct hda_verb alc861_auto_init_verbs[] = {
12758 * Unmute ADC0 and set the default input to mic-in
12760 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
12761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12763 /* Unmute DAC0~3 & spdif out*/
12764 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12765 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12766 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12767 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12768 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12770 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12771 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12772 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12773 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12774 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12776 /* Unmute Stereo Mixer 15 */
12777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12779 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12780 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
12782 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12783 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12784 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12785 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12786 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12787 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12788 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12789 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12791 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12794 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12795 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12796 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12797 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12800 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
12805 static struct hda_verb alc861_toshiba_init_verbs[] = {
12806 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12811 /* toggle speaker-output according to the hp-jack state */
12812 static void alc861_toshiba_automute(struct hda_codec *codec)
12814 unsigned int present;
12816 present = snd_hda_codec_read(codec, 0x0f, 0,
12817 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12818 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
12819 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12820 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
12821 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
12824 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
12827 if ((res >> 26) == ALC880_HP_EVENT)
12828 alc861_toshiba_automute(codec);
12831 /* pcm configuration: identiacal with ALC880 */
12832 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
12833 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
12834 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
12835 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
12838 #define ALC861_DIGOUT_NID 0x07
12840 static struct hda_channel_mode alc861_8ch_modes[1] = {
12844 static hda_nid_t alc861_dac_nids[4] = {
12845 /* front, surround, clfe, side */
12846 0x03, 0x06, 0x05, 0x04
12849 static hda_nid_t alc660_dac_nids[3] = {
12850 /* front, clfe, surround */
12854 static hda_nid_t alc861_adc_nids[1] = {
12859 static struct hda_input_mux alc861_capture_source = {
12863 { "Front Mic", 0x3 },
12870 /* fill in the dac_nids table from the parsed pin configuration */
12871 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
12872 const struct auto_pin_cfg *cfg)
12877 spec->multiout.dac_nids = spec->private_dac_nids;
12878 for (i = 0; i < cfg->line_outs; i++) {
12879 nid = cfg->line_out_pins[i];
12881 if (i >= ARRAY_SIZE(alc861_dac_nids))
12883 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
12886 spec->multiout.num_dacs = cfg->line_outs;
12890 /* add playback controls from the parsed DAC table */
12891 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
12892 const struct auto_pin_cfg *cfg)
12895 static const char *chname[4] = {
12896 "Front", "Surround", NULL /*CLFE*/, "Side"
12901 for (i = 0; i < cfg->line_outs; i++) {
12902 nid = spec->multiout.dac_nids[i];
12907 err = add_control(spec, ALC_CTL_BIND_MUTE,
12908 "Center Playback Switch",
12909 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12913 err = add_control(spec, ALC_CTL_BIND_MUTE,
12914 "LFE Playback Switch",
12915 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12920 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
12922 if (nid == alc861_dac_nids[idx])
12924 sprintf(name, "%s Playback Switch", chname[idx]);
12925 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12926 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12935 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
12943 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
12945 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12946 "Headphone Playback Switch",
12947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12950 spec->multiout.hp_nid = nid;
12955 /* create playback/capture controls for input pins */
12956 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
12957 const struct auto_pin_cfg *cfg)
12959 struct hda_input_mux *imux = &spec->private_imux;
12960 int i, err, idx, idx1;
12962 for (i = 0; i < AUTO_PIN_LAST; i++) {
12963 switch (cfg->input_pins[i]) {
12966 idx = 2; /* Line In */
12970 idx = 2; /* Line In */
12974 idx = 1; /* Mic In */
12978 idx = 1; /* Mic In */
12988 err = new_analog_input(spec, cfg->input_pins[i],
12989 auto_pin_cfg_labels[i], idx, 0x15);
12993 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12994 imux->items[imux->num_items].index = idx1;
13000 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13002 int pin_type, int dac_idx)
13004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13006 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13010 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13012 struct alc_spec *spec = codec->spec;
13015 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13016 for (i = 0; i < spec->autocfg.line_outs; i++) {
13017 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13018 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13020 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13021 spec->multiout.dac_nids[i]);
13025 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13027 struct alc_spec *spec = codec->spec;
13030 pin = spec->autocfg.hp_pins[0];
13031 if (pin) /* connect to front */
13032 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13033 spec->multiout.dac_nids[0]);
13034 pin = spec->autocfg.speaker_pins[0];
13036 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13039 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13041 struct alc_spec *spec = codec->spec;
13044 for (i = 0; i < AUTO_PIN_LAST; i++) {
13045 hda_nid_t nid = spec->autocfg.input_pins[i];
13046 if (nid >= 0x0c && nid <= 0x11) {
13047 snd_hda_codec_write(codec, nid, 0,
13048 AC_VERB_SET_PIN_WIDGET_CONTROL,
13049 i <= AUTO_PIN_FRONT_MIC ?
13050 PIN_VREF80 : PIN_IN);
13055 /* parse the BIOS configuration and set up the alc_spec */
13056 /* return 1 if successful, 0 if the proper config is not found,
13057 * or a negative error code
13059 static int alc861_parse_auto_config(struct hda_codec *codec)
13061 struct alc_spec *spec = codec->spec;
13063 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13065 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13069 if (!spec->autocfg.line_outs)
13070 return 0; /* can't find valid BIOS pin config */
13072 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13075 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13078 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13081 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13085 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13087 if (spec->autocfg.dig_out_pin)
13088 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13090 if (spec->kctls.list)
13091 add_mixer(spec, spec->kctls.list);
13093 add_verb(spec, alc861_auto_init_verbs);
13095 spec->num_mux_defs = 1;
13096 spec->input_mux = &spec->private_imux;
13098 spec->adc_nids = alc861_adc_nids;
13099 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13100 set_capture_mixer(spec);
13102 store_pin_configs(codec);
13106 /* additional initialization for auto-configuration model */
13107 static void alc861_auto_init(struct hda_codec *codec)
13109 struct alc_spec *spec = codec->spec;
13110 alc861_auto_init_multi_out(codec);
13111 alc861_auto_init_hp_out(codec);
13112 alc861_auto_init_analog_input(codec);
13113 if (spec->unsol_event)
13114 alc_inithook(codec);
13117 #ifdef CONFIG_SND_HDA_POWER_SAVE
13118 static struct hda_amp_list alc861_loopbacks[] = {
13119 { 0x15, HDA_INPUT, 0 },
13120 { 0x15, HDA_INPUT, 1 },
13121 { 0x15, HDA_INPUT, 2 },
13122 { 0x15, HDA_INPUT, 3 },
13129 * configuration and preset
13131 static const char *alc861_models[ALC861_MODEL_LAST] = {
13132 [ALC861_3ST] = "3stack",
13133 [ALC660_3ST] = "3stack-660",
13134 [ALC861_3ST_DIG] = "3stack-dig",
13135 [ALC861_6ST_DIG] = "6stack-dig",
13136 [ALC861_UNIWILL_M31] = "uniwill-m31",
13137 [ALC861_TOSHIBA] = "toshiba",
13138 [ALC861_ASUS] = "asus",
13139 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13140 [ALC861_AUTO] = "auto",
13143 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13144 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13145 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13146 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13147 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13148 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13149 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13150 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13151 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13152 * Any other models that need this preset?
13154 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13155 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13156 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13157 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13158 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13159 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13160 /* FIXME: the below seems conflict */
13161 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13162 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13163 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13167 static struct alc_config_preset alc861_presets[] = {
13169 .mixers = { alc861_3ST_mixer },
13170 .init_verbs = { alc861_threestack_init_verbs },
13171 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13172 .dac_nids = alc861_dac_nids,
13173 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13174 .channel_mode = alc861_threestack_modes,
13176 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13177 .adc_nids = alc861_adc_nids,
13178 .input_mux = &alc861_capture_source,
13180 [ALC861_3ST_DIG] = {
13181 .mixers = { alc861_base_mixer },
13182 .init_verbs = { alc861_threestack_init_verbs },
13183 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13184 .dac_nids = alc861_dac_nids,
13185 .dig_out_nid = ALC861_DIGOUT_NID,
13186 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13187 .channel_mode = alc861_threestack_modes,
13189 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13190 .adc_nids = alc861_adc_nids,
13191 .input_mux = &alc861_capture_source,
13193 [ALC861_6ST_DIG] = {
13194 .mixers = { alc861_base_mixer },
13195 .init_verbs = { alc861_base_init_verbs },
13196 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13197 .dac_nids = alc861_dac_nids,
13198 .dig_out_nid = ALC861_DIGOUT_NID,
13199 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13200 .channel_mode = alc861_8ch_modes,
13201 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13202 .adc_nids = alc861_adc_nids,
13203 .input_mux = &alc861_capture_source,
13206 .mixers = { alc861_3ST_mixer },
13207 .init_verbs = { alc861_threestack_init_verbs },
13208 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13209 .dac_nids = alc660_dac_nids,
13210 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13211 .channel_mode = alc861_threestack_modes,
13213 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13214 .adc_nids = alc861_adc_nids,
13215 .input_mux = &alc861_capture_source,
13217 [ALC861_UNIWILL_M31] = {
13218 .mixers = { alc861_uniwill_m31_mixer },
13219 .init_verbs = { alc861_uniwill_m31_init_verbs },
13220 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13221 .dac_nids = alc861_dac_nids,
13222 .dig_out_nid = ALC861_DIGOUT_NID,
13223 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13224 .channel_mode = alc861_uniwill_m31_modes,
13226 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13227 .adc_nids = alc861_adc_nids,
13228 .input_mux = &alc861_capture_source,
13230 [ALC861_TOSHIBA] = {
13231 .mixers = { alc861_toshiba_mixer },
13232 .init_verbs = { alc861_base_init_verbs,
13233 alc861_toshiba_init_verbs },
13234 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13235 .dac_nids = alc861_dac_nids,
13236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13237 .channel_mode = alc883_3ST_2ch_modes,
13238 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13239 .adc_nids = alc861_adc_nids,
13240 .input_mux = &alc861_capture_source,
13241 .unsol_event = alc861_toshiba_unsol_event,
13242 .init_hook = alc861_toshiba_automute,
13245 .mixers = { alc861_asus_mixer },
13246 .init_verbs = { alc861_asus_init_verbs },
13247 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13248 .dac_nids = alc861_dac_nids,
13249 .dig_out_nid = ALC861_DIGOUT_NID,
13250 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13251 .channel_mode = alc861_asus_modes,
13254 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13255 .adc_nids = alc861_adc_nids,
13256 .input_mux = &alc861_capture_source,
13258 [ALC861_ASUS_LAPTOP] = {
13259 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13260 .init_verbs = { alc861_asus_init_verbs,
13261 alc861_asus_laptop_init_verbs },
13262 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13263 .dac_nids = alc861_dac_nids,
13264 .dig_out_nid = ALC861_DIGOUT_NID,
13265 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13266 .channel_mode = alc883_3ST_2ch_modes,
13268 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13269 .adc_nids = alc861_adc_nids,
13270 .input_mux = &alc861_capture_source,
13275 static int patch_alc861(struct hda_codec *codec)
13277 struct alc_spec *spec;
13281 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13285 codec->spec = spec;
13287 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13291 if (board_config < 0) {
13292 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13293 "trying auto-probe from BIOS...\n");
13294 board_config = ALC861_AUTO;
13297 if (board_config == ALC861_AUTO) {
13298 /* automatic parse from the BIOS config */
13299 err = alc861_parse_auto_config(codec);
13305 "hda_codec: Cannot set up configuration "
13306 "from BIOS. Using base mode...\n");
13307 board_config = ALC861_3ST_DIG;
13311 if (board_config != ALC861_AUTO)
13312 setup_preset(spec, &alc861_presets[board_config]);
13314 spec->stream_name_analog = "ALC861 Analog";
13315 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13316 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13318 spec->stream_name_digital = "ALC861 Digital";
13319 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13320 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13322 spec->vmaster_nid = 0x03;
13324 codec->patch_ops = alc_patch_ops;
13325 if (board_config == ALC861_AUTO)
13326 spec->init_hook = alc861_auto_init;
13327 #ifdef CONFIG_SND_HDA_POWER_SAVE
13328 if (!spec->loopback.amplist)
13329 spec->loopback.amplist = alc861_loopbacks;
13336 * ALC861-VD support
13340 * In addition, an independent DAC
13342 #define ALC861VD_DIGOUT_NID 0x06
13344 static hda_nid_t alc861vd_dac_nids[4] = {
13345 /* front, surr, clfe, side surr */
13346 0x02, 0x03, 0x04, 0x05
13349 /* dac_nids for ALC660vd are in a different order - according to
13350 * Realtek's driver.
13351 * This should probably tesult in a different mixer for 6stack models
13352 * of ALC660vd codecs, but for now there is only 3stack mixer
13353 * - and it is the same as in 861vd.
13354 * adc_nids in ALC660vd are (is) the same as in 861vd
13356 static hda_nid_t alc660vd_dac_nids[3] = {
13357 /* front, rear, clfe, rear_surr */
13361 static hda_nid_t alc861vd_adc_nids[1] = {
13366 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13369 /* FIXME: should be a matrix-type input source selection */
13370 static struct hda_input_mux alc861vd_capture_source = {
13374 { "Front Mic", 0x1 },
13380 static struct hda_input_mux alc861vd_dallas_capture_source = {
13383 { "Ext Mic", 0x0 },
13384 { "Int Mic", 0x1 },
13388 static struct hda_input_mux alc861vd_hp_capture_source = {
13391 { "Front Mic", 0x0 },
13392 { "ATAPI Mic", 0x1 },
13399 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13406 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13407 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13408 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13409 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13410 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13417 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13418 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13419 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13420 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13421 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13425 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13426 { 6, alc861vd_6stack_ch6_init },
13427 { 8, alc861vd_6stack_ch8_init },
13430 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13432 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13433 .name = "Channel Mode",
13434 .info = alc_ch_mode_info,
13435 .get = alc_ch_mode_get,
13436 .put = alc_ch_mode_put,
13441 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13442 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13444 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13445 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13448 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13449 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13451 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13453 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13455 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13456 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13458 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13459 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13461 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13463 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13464 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13467 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13468 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13469 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13471 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13472 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13475 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13477 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13478 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13483 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13484 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13489 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13493 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13494 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13495 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13503 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13504 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13509 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13510 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13511 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13512 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13516 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13517 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13518 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13520 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13521 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13524 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13525 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13530 /* Pin assignment: Speaker=0x14, HP = 0x15,
13531 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13533 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13534 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13535 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13536 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13537 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13538 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13539 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13540 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13541 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13542 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13543 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13544 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13545 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13549 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13550 * Front Mic=0x18, ATAPI Mic = 0x19,
13552 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13553 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13555 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13556 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13557 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13558 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13559 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13560 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13566 * generic initialization of ADC, input mixers and output mixers
13568 static struct hda_verb alc861vd_volume_init_verbs[] = {
13570 * Unmute ADC0 and set the default input to mic-in
13572 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13575 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13576 * the analog-loopback mixer widget
13578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13585 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13592 * Set up output mixers (0x02 - 0x05)
13594 /* set vol=0 to output mixers */
13595 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13596 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13598 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13600 /* set up input amps for analog loopback */
13601 /* Amp Indices: DAC = 0, mixer = 1 */
13602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13604 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13605 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13606 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13607 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13615 * 3-stack pin configuration:
13616 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13618 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13620 * Set pin mode and muting
13622 /* set front pin widgets 0x14 for output */
13623 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13624 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13625 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13627 /* Mic (rear) pin: input vref at 80% */
13628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13630 /* Front Mic pin: input vref at 80% */
13631 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13632 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13633 /* Line In pin: input */
13634 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13636 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13637 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13638 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13639 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13640 /* CD pin widget for input */
13641 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13647 * 6-stack pin configuration:
13649 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13651 * Set pin mode and muting
13653 /* set front pin widgets 0x14 for output */
13654 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13655 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13656 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13658 /* Rear Pin: output 1 (0x0d) */
13659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13660 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13661 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13662 /* CLFE Pin: output 2 (0x0e) */
13663 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13664 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13665 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13666 /* Side Pin: output 3 (0x0f) */
13667 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13668 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13669 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13671 /* Mic (rear) pin: input vref at 80% */
13672 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13673 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13674 /* Front Mic pin: input vref at 80% */
13675 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13676 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13677 /* Line In pin: input */
13678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13680 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13681 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13682 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13683 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13684 /* CD pin widget for input */
13685 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13690 static struct hda_verb alc861vd_eapd_verbs[] = {
13691 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13695 static struct hda_verb alc660vd_eapd_verbs[] = {
13696 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13697 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13701 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
13702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
13705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13706 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13710 /* toggle speaker-output according to the hp-jack state */
13711 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
13713 unsigned int present;
13714 unsigned char bits;
13716 present = snd_hda_codec_read(codec, 0x1b, 0,
13717 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13718 bits = present ? HDA_AMP_MUTE : 0;
13719 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13720 HDA_AMP_MUTE, bits);
13723 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
13725 unsigned int present;
13726 unsigned char bits;
13728 present = snd_hda_codec_read(codec, 0x18, 0,
13729 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13730 bits = present ? HDA_AMP_MUTE : 0;
13731 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
13732 HDA_AMP_MUTE, bits);
13735 static void alc861vd_lenovo_automute(struct hda_codec *codec)
13737 alc861vd_lenovo_hp_automute(codec);
13738 alc861vd_lenovo_mic_automute(codec);
13741 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
13744 switch (res >> 26) {
13745 case ALC880_HP_EVENT:
13746 alc861vd_lenovo_hp_automute(codec);
13748 case ALC880_MIC_EVENT:
13749 alc861vd_lenovo_mic_automute(codec);
13754 static struct hda_verb alc861vd_dallas_verbs[] = {
13755 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13756 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13757 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13758 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13764 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13765 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13767 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13769 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13771 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13773 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13775 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13776 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13778 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
13781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13782 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13784 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13785 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13793 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13794 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13799 /* toggle speaker-output according to the hp-jack state */
13800 static void alc861vd_dallas_automute(struct hda_codec *codec)
13802 unsigned int present;
13804 present = snd_hda_codec_read(codec, 0x15, 0,
13805 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13806 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13807 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13810 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
13812 if ((res >> 26) == ALC880_HP_EVENT)
13813 alc861vd_dallas_automute(codec);
13816 #ifdef CONFIG_SND_HDA_POWER_SAVE
13817 #define alc861vd_loopbacks alc880_loopbacks
13820 /* pcm configuration: identiacal with ALC880 */
13821 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
13822 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
13823 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
13824 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
13827 * configuration and preset
13829 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
13830 [ALC660VD_3ST] = "3stack-660",
13831 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13832 [ALC861VD_3ST] = "3stack",
13833 [ALC861VD_3ST_DIG] = "3stack-digout",
13834 [ALC861VD_6ST_DIG] = "6stack-digout",
13835 [ALC861VD_LENOVO] = "lenovo",
13836 [ALC861VD_DALLAS] = "dallas",
13837 [ALC861VD_HP] = "hp",
13838 [ALC861VD_AUTO] = "auto",
13841 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
13842 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
13843 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
13844 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
13845 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
13846 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
13847 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
13848 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
13849 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
13850 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
13851 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
13852 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
13853 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
13854 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
13855 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
13856 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
13857 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
13858 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
13862 static struct alc_config_preset alc861vd_presets[] = {
13864 .mixers = { alc861vd_3st_mixer },
13865 .init_verbs = { alc861vd_volume_init_verbs,
13866 alc861vd_3stack_init_verbs },
13867 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13868 .dac_nids = alc660vd_dac_nids,
13869 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13870 .channel_mode = alc861vd_3stack_2ch_modes,
13871 .input_mux = &alc861vd_capture_source,
13873 [ALC660VD_3ST_DIG] = {
13874 .mixers = { alc861vd_3st_mixer },
13875 .init_verbs = { alc861vd_volume_init_verbs,
13876 alc861vd_3stack_init_verbs },
13877 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13878 .dac_nids = alc660vd_dac_nids,
13879 .dig_out_nid = ALC861VD_DIGOUT_NID,
13880 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13881 .channel_mode = alc861vd_3stack_2ch_modes,
13882 .input_mux = &alc861vd_capture_source,
13885 .mixers = { alc861vd_3st_mixer },
13886 .init_verbs = { alc861vd_volume_init_verbs,
13887 alc861vd_3stack_init_verbs },
13888 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13889 .dac_nids = alc861vd_dac_nids,
13890 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13891 .channel_mode = alc861vd_3stack_2ch_modes,
13892 .input_mux = &alc861vd_capture_source,
13894 [ALC861VD_3ST_DIG] = {
13895 .mixers = { alc861vd_3st_mixer },
13896 .init_verbs = { alc861vd_volume_init_verbs,
13897 alc861vd_3stack_init_verbs },
13898 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13899 .dac_nids = alc861vd_dac_nids,
13900 .dig_out_nid = ALC861VD_DIGOUT_NID,
13901 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13902 .channel_mode = alc861vd_3stack_2ch_modes,
13903 .input_mux = &alc861vd_capture_source,
13905 [ALC861VD_6ST_DIG] = {
13906 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
13907 .init_verbs = { alc861vd_volume_init_verbs,
13908 alc861vd_6stack_init_verbs },
13909 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13910 .dac_nids = alc861vd_dac_nids,
13911 .dig_out_nid = ALC861VD_DIGOUT_NID,
13912 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
13913 .channel_mode = alc861vd_6stack_modes,
13914 .input_mux = &alc861vd_capture_source,
13916 [ALC861VD_LENOVO] = {
13917 .mixers = { alc861vd_lenovo_mixer },
13918 .init_verbs = { alc861vd_volume_init_verbs,
13919 alc861vd_3stack_init_verbs,
13920 alc861vd_eapd_verbs,
13921 alc861vd_lenovo_unsol_verbs },
13922 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
13923 .dac_nids = alc660vd_dac_nids,
13924 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13925 .channel_mode = alc861vd_3stack_2ch_modes,
13926 .input_mux = &alc861vd_capture_source,
13927 .unsol_event = alc861vd_lenovo_unsol_event,
13928 .init_hook = alc861vd_lenovo_automute,
13930 [ALC861VD_DALLAS] = {
13931 .mixers = { alc861vd_dallas_mixer },
13932 .init_verbs = { alc861vd_dallas_verbs },
13933 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13934 .dac_nids = alc861vd_dac_nids,
13935 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13936 .channel_mode = alc861vd_3stack_2ch_modes,
13937 .input_mux = &alc861vd_dallas_capture_source,
13938 .unsol_event = alc861vd_dallas_unsol_event,
13939 .init_hook = alc861vd_dallas_automute,
13942 .mixers = { alc861vd_hp_mixer },
13943 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
13944 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
13945 .dac_nids = alc861vd_dac_nids,
13946 .dig_out_nid = ALC861VD_DIGOUT_NID,
13947 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
13948 .channel_mode = alc861vd_3stack_2ch_modes,
13949 .input_mux = &alc861vd_hp_capture_source,
13950 .unsol_event = alc861vd_dallas_unsol_event,
13951 .init_hook = alc861vd_dallas_automute,
13956 * BIOS auto configuration
13958 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
13959 hda_nid_t nid, int pin_type, int dac_idx)
13961 alc_set_pin_output(codec, nid, pin_type);
13964 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
13966 struct alc_spec *spec = codec->spec;
13969 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13970 for (i = 0; i <= HDA_SIDE; i++) {
13971 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13972 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13974 alc861vd_auto_set_output_and_unmute(codec, nid,
13980 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
13982 struct alc_spec *spec = codec->spec;
13985 pin = spec->autocfg.hp_pins[0];
13986 if (pin) /* connect to front and use dac 0 */
13987 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13988 pin = spec->autocfg.speaker_pins[0];
13990 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13993 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
13994 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
13996 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
13998 struct alc_spec *spec = codec->spec;
14001 for (i = 0; i < AUTO_PIN_LAST; i++) {
14002 hda_nid_t nid = spec->autocfg.input_pins[i];
14003 if (alc861vd_is_input_pin(nid)) {
14004 snd_hda_codec_write(codec, nid, 0,
14005 AC_VERB_SET_PIN_WIDGET_CONTROL,
14006 i <= AUTO_PIN_FRONT_MIC ?
14007 PIN_VREF80 : PIN_IN);
14008 if (nid != ALC861VD_PIN_CD_NID)
14009 snd_hda_codec_write(codec, nid, 0,
14010 AC_VERB_SET_AMP_GAIN_MUTE,
14016 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14018 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14019 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14021 /* add playback controls from the parsed DAC table */
14022 /* Based on ALC880 version. But ALC861VD has separate,
14023 * different NIDs for mute/unmute switch and volume control */
14024 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14025 const struct auto_pin_cfg *cfg)
14028 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14029 hda_nid_t nid_v, nid_s;
14032 for (i = 0; i < cfg->line_outs; i++) {
14033 if (!spec->multiout.dac_nids[i])
14035 nid_v = alc861vd_idx_to_mixer_vol(
14037 spec->multiout.dac_nids[i]));
14038 nid_s = alc861vd_idx_to_mixer_switch(
14040 spec->multiout.dac_nids[i]));
14044 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14045 "Center Playback Volume",
14046 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14050 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14051 "LFE Playback Volume",
14052 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14056 err = add_control(spec, ALC_CTL_BIND_MUTE,
14057 "Center Playback Switch",
14058 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14062 err = add_control(spec, ALC_CTL_BIND_MUTE,
14063 "LFE Playback Switch",
14064 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14069 sprintf(name, "%s Playback Volume", chname[i]);
14070 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14071 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14075 sprintf(name, "%s Playback Switch", chname[i]);
14076 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14077 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14086 /* add playback controls for speaker and HP outputs */
14087 /* Based on ALC880 version. But ALC861VD has separate,
14088 * different NIDs for mute/unmute switch and volume control */
14089 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14090 hda_nid_t pin, const char *pfx)
14092 hda_nid_t nid_v, nid_s;
14099 if (alc880_is_fixed_pin(pin)) {
14100 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14101 /* specify the DAC as the extra output */
14102 if (!spec->multiout.hp_nid)
14103 spec->multiout.hp_nid = nid_v;
14105 spec->multiout.extra_out_nid[0] = nid_v;
14106 /* control HP volume/switch on the output mixer amp */
14107 nid_v = alc861vd_idx_to_mixer_vol(
14108 alc880_fixed_pin_idx(pin));
14109 nid_s = alc861vd_idx_to_mixer_switch(
14110 alc880_fixed_pin_idx(pin));
14112 sprintf(name, "%s Playback Volume", pfx);
14113 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14114 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14117 sprintf(name, "%s Playback Switch", pfx);
14118 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14119 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14122 } else if (alc880_is_multi_pin(pin)) {
14123 /* set manual connection */
14124 /* we have only a switch on HP-out PIN */
14125 sprintf(name, "%s Playback Switch", pfx);
14126 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14127 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14134 /* parse the BIOS configuration and set up the alc_spec
14135 * return 1 if successful, 0 if the proper config is not found,
14136 * or a negative error code
14137 * Based on ALC880 version - had to change it to override
14138 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14139 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14141 struct alc_spec *spec = codec->spec;
14143 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14145 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14149 if (!spec->autocfg.line_outs)
14150 return 0; /* can't find valid BIOS pin config */
14152 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14155 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14158 err = alc861vd_auto_create_extra_out(spec,
14159 spec->autocfg.speaker_pins[0],
14163 err = alc861vd_auto_create_extra_out(spec,
14164 spec->autocfg.hp_pins[0],
14168 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14172 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14174 if (spec->autocfg.dig_out_pin)
14175 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14177 if (spec->kctls.list)
14178 add_mixer(spec, spec->kctls.list);
14180 add_verb(spec, alc861vd_volume_init_verbs);
14182 spec->num_mux_defs = 1;
14183 spec->input_mux = &spec->private_imux;
14185 err = alc_auto_add_mic_boost(codec);
14189 store_pin_configs(codec);
14193 /* additional initialization for auto-configuration model */
14194 static void alc861vd_auto_init(struct hda_codec *codec)
14196 struct alc_spec *spec = codec->spec;
14197 alc861vd_auto_init_multi_out(codec);
14198 alc861vd_auto_init_hp_out(codec);
14199 alc861vd_auto_init_analog_input(codec);
14200 alc861vd_auto_init_input_src(codec);
14201 if (spec->unsol_event)
14202 alc_inithook(codec);
14205 static int patch_alc861vd(struct hda_codec *codec)
14207 struct alc_spec *spec;
14208 int err, board_config;
14210 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14214 codec->spec = spec;
14216 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14220 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14221 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14222 "ALC861VD, trying auto-probe from BIOS...\n");
14223 board_config = ALC861VD_AUTO;
14226 if (board_config == ALC861VD_AUTO) {
14227 /* automatic parse from the BIOS config */
14228 err = alc861vd_parse_auto_config(codec);
14234 "hda_codec: Cannot set up configuration "
14235 "from BIOS. Using base mode...\n");
14236 board_config = ALC861VD_3ST;
14240 if (board_config != ALC861VD_AUTO)
14241 setup_preset(spec, &alc861vd_presets[board_config]);
14243 if (codec->vendor_id == 0x10ec0660) {
14244 spec->stream_name_analog = "ALC660-VD Analog";
14245 spec->stream_name_digital = "ALC660-VD Digital";
14246 /* always turn on EAPD */
14247 add_verb(spec, alc660vd_eapd_verbs);
14249 spec->stream_name_analog = "ALC861VD Analog";
14250 spec->stream_name_digital = "ALC861VD Digital";
14253 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14254 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14256 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14257 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14259 spec->adc_nids = alc861vd_adc_nids;
14260 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14261 spec->capsrc_nids = alc861vd_capsrc_nids;
14262 spec->is_mix_capture = 1;
14264 set_capture_mixer(spec);
14266 spec->vmaster_nid = 0x02;
14268 codec->patch_ops = alc_patch_ops;
14270 if (board_config == ALC861VD_AUTO)
14271 spec->init_hook = alc861vd_auto_init;
14272 #ifdef CONFIG_SND_HDA_POWER_SAVE
14273 if (!spec->loopback.amplist)
14274 spec->loopback.amplist = alc861vd_loopbacks;
14283 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14284 * configuration. Each pin widget can choose any input DACs and a mixer.
14285 * Each ADC is connected from a mixer of all inputs. This makes possible
14286 * 6-channel independent captures.
14288 * In addition, an independent DAC for the multi-playback (not used in this
14291 #define ALC662_DIGOUT_NID 0x06
14292 #define ALC662_DIGIN_NID 0x0a
14294 static hda_nid_t alc662_dac_nids[4] = {
14295 /* front, rear, clfe, rear_surr */
14299 static hda_nid_t alc662_adc_nids[1] = {
14304 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14307 /* FIXME: should be a matrix-type input source selection */
14308 static struct hda_input_mux alc662_capture_source = {
14312 { "Front Mic", 0x1 },
14318 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14326 static struct hda_input_mux alc662_eeepc_capture_source = {
14334 static struct hda_input_mux alc663_capture_source = {
14338 { "Front Mic", 0x1 },
14343 static struct hda_input_mux alc663_m51va_capture_source = {
14346 { "Ext-Mic", 0x0 },
14354 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14361 static struct hda_verb alc662_3ST_ch2_init[] = {
14362 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14363 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14364 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14365 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14372 static struct hda_verb alc662_3ST_ch6_init[] = {
14373 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14374 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14375 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14376 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14377 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14378 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14382 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14383 { 2, alc662_3ST_ch2_init },
14384 { 6, alc662_3ST_ch6_init },
14390 static struct hda_verb alc662_sixstack_ch6_init[] = {
14391 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14392 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14393 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14400 static struct hda_verb alc662_sixstack_ch8_init[] = {
14401 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14402 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14403 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14407 static struct hda_channel_mode alc662_5stack_modes[2] = {
14408 { 2, alc662_sixstack_ch6_init },
14409 { 6, alc662_sixstack_ch8_init },
14412 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14413 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14416 static struct snd_kcontrol_new alc662_base_mixer[] = {
14417 /* output mixer control */
14418 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14419 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14420 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14421 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14422 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14423 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14424 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14425 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14426 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14428 /*Input mixer control */
14429 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14430 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14431 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14432 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14433 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14434 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14440 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14441 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14442 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14446 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14447 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14448 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14450 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14451 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14452 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14453 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14457 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14458 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14459 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14460 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14461 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14462 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14463 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14464 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14465 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14466 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14467 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14468 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14473 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14474 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14475 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14476 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14480 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14481 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14482 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14483 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14484 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14486 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14487 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14493 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14494 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14496 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14497 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14499 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14500 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14501 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14503 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14504 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14505 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14509 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14510 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14511 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14512 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14513 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14514 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14515 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14516 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14517 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14519 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14527 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14528 .ops = &snd_hda_bind_vol,
14530 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14531 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14536 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14537 .ops = &snd_hda_bind_sw,
14539 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14540 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14545 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14546 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14547 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14553 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14554 .ops = &snd_hda_bind_sw,
14556 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14557 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14558 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14563 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14564 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14565 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14568 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14569 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14574 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14575 .ops = &snd_hda_bind_sw,
14577 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14578 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14579 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14584 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14585 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14586 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14589 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14590 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14594 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14595 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14596 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14597 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14600 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14601 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14605 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14606 .ops = &snd_hda_bind_vol,
14608 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14609 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14614 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14615 .ops = &snd_hda_bind_sw,
14617 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14618 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14623 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14624 HDA_BIND_VOL("Master Playback Volume",
14625 &alc663_asus_two_bind_master_vol),
14626 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14627 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14628 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14634 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14635 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14636 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14644 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14645 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14646 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14647 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14648 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14651 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14653 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14654 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14658 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14659 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14660 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14661 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14663 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14664 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14665 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14666 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14672 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
14674 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14675 .name = "Channel Mode",
14676 .info = alc_ch_mode_info,
14677 .get = alc_ch_mode_get,
14678 .put = alc_ch_mode_put,
14683 static struct hda_verb alc662_init_verbs[] = {
14684 /* ADC: mute amp left and right */
14685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14686 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14687 /* Front mixer: unmute input/output amp left and right (volume = 0) */
14689 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14690 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14696 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14697 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14698 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14699 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14700 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14702 /* Front Pin: output 0 (0x0c) */
14703 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14704 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14706 /* Rear Pin: output 1 (0x0d) */
14707 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14708 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14710 /* CLFE Pin: output 2 (0x0e) */
14711 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14714 /* Mic (rear) pin: input vref at 80% */
14715 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14717 /* Front Mic pin: input vref at 80% */
14718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14720 /* Line In pin: input */
14721 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14723 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14724 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14725 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14726 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14727 /* CD pin widget for input */
14728 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14730 /* FIXME: use matrix-type input source selection */
14731 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14734 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14735 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14736 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14739 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14743 /* always trun on EAPD */
14744 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14745 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14750 static struct hda_verb alc662_sue_init_verbs[] = {
14751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14752 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14756 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
14757 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14758 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14762 /* Set Unsolicited Event*/
14763 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
14764 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14765 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14770 * generic initialization of ADC, input mixers and output mixers
14772 static struct hda_verb alc662_auto_init_verbs[] = {
14774 * Unmute ADC and set the default input to mic-in
14776 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14777 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14779 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
14781 * Note: PASD motherboards uses the Line In 2 as the input for front
14782 * panel mic (mic 2)
14784 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14785 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14786 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14787 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14788 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14789 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14792 * Set up output mixers (0x0c - 0x0f)
14794 /* set vol=0 to output mixers */
14795 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14796 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14797 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14799 /* set up input amps for analog loopback */
14800 /* Amp Indices: DAC = 0, mixer = 1 */
14801 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14805 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14809 /* FIXME: use matrix-type input source selection */
14810 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
14812 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14817 /* additional verbs for ALC663 */
14818 static struct hda_verb alc663_auto_init_verbs[] = {
14819 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14820 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14824 static struct hda_verb alc663_m51va_init_verbs[] = {
14825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14826 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14827 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14828 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14829 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14830 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
14832 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14833 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14837 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
14838 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14839 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14840 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14842 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14843 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14844 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14848 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
14849 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14851 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14852 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14853 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14854 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14855 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14856 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14860 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
14861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14864 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14865 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14871 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
14872 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14873 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14874 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14875 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
14876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14878 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
14879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14881 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14882 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14883 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14887 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
14888 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14889 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14890 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14891 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14893 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14894 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
14895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14896 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14897 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14898 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14903 static struct hda_verb alc663_g71v_init_verbs[] = {
14904 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14905 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
14906 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
14908 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14909 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14910 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
14913 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
14914 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
14918 static struct hda_verb alc663_g50v_init_verbs[] = {
14919 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14920 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14921 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
14923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14924 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14928 static struct hda_verb alc662_ecs_init_verbs[] = {
14929 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
14930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14936 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
14937 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14938 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14942 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
14944 unsigned int present;
14945 unsigned char bits;
14947 present = snd_hda_codec_read(codec, 0x14, 0,
14948 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14949 bits = present ? HDA_AMP_MUTE : 0;
14950 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14951 HDA_AMP_MUTE, bits);
14954 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
14956 unsigned int present;
14957 unsigned char bits;
14959 present = snd_hda_codec_read(codec, 0x1b, 0,
14960 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14961 bits = present ? HDA_AMP_MUTE : 0;
14962 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
14963 HDA_AMP_MUTE, bits);
14964 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14965 HDA_AMP_MUTE, bits);
14968 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
14971 if ((res >> 26) == ALC880_HP_EVENT)
14972 alc662_lenovo_101e_all_automute(codec);
14973 if ((res >> 26) == ALC880_FRONT_EVENT)
14974 alc662_lenovo_101e_ispeaker_automute(codec);
14977 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
14979 unsigned int present;
14981 present = snd_hda_codec_read(codec, 0x18, 0,
14982 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14983 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14984 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14985 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14986 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
14987 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14988 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14989 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14990 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
14993 /* unsolicited event for HP jack sensing */
14994 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
14997 if ((res >> 26) == ALC880_HP_EVENT)
14998 alc262_hippo1_automute( codec );
15000 if ((res >> 26) == ALC880_MIC_EVENT)
15001 alc662_eeepc_mic_automute(codec);
15004 static void alc662_eeepc_inithook(struct hda_codec *codec)
15006 alc262_hippo1_automute( codec );
15007 alc662_eeepc_mic_automute(codec);
15010 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15013 unsigned int present;
15015 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15016 present = snd_hda_codec_read(codec, 0x14, 0,
15017 AC_VERB_GET_PIN_SENSE, 0);
15018 present = (present & 0x80000000) != 0;
15020 /* mute internal speaker */
15021 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15022 HDA_AMP_MUTE, HDA_AMP_MUTE);
15024 /* unmute internal speaker if necessary */
15025 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15026 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15027 HDA_AMP_MUTE, mute);
15031 /* unsolicited event for HP jack sensing */
15032 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15035 if ((res >> 26) == ALC880_HP_EVENT)
15036 alc662_eeepc_ep20_automute(codec);
15039 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15041 alc662_eeepc_ep20_automute(codec);
15044 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15046 unsigned int present;
15047 unsigned char bits;
15049 present = snd_hda_codec_read(codec, 0x21, 0,
15050 AC_VERB_GET_PIN_SENSE, 0)
15051 & AC_PINSENSE_PRESENCE;
15052 bits = present ? HDA_AMP_MUTE : 0;
15053 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15054 AMP_IN_MUTE(0), bits);
15055 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15056 AMP_IN_MUTE(0), bits);
15059 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15061 unsigned int present;
15062 unsigned char bits;
15064 present = snd_hda_codec_read(codec, 0x21, 0,
15065 AC_VERB_GET_PIN_SENSE, 0)
15066 & AC_PINSENSE_PRESENCE;
15067 bits = present ? HDA_AMP_MUTE : 0;
15068 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15069 AMP_IN_MUTE(0), bits);
15070 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15071 AMP_IN_MUTE(0), bits);
15072 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15073 AMP_IN_MUTE(0), bits);
15074 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15075 AMP_IN_MUTE(0), bits);
15078 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15080 unsigned int present;
15081 unsigned char bits;
15083 present = snd_hda_codec_read(codec, 0x15, 0,
15084 AC_VERB_GET_PIN_SENSE, 0)
15085 & AC_PINSENSE_PRESENCE;
15086 bits = present ? HDA_AMP_MUTE : 0;
15087 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15088 AMP_IN_MUTE(0), bits);
15089 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15090 AMP_IN_MUTE(0), bits);
15091 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15092 AMP_IN_MUTE(0), bits);
15093 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15094 AMP_IN_MUTE(0), bits);
15097 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15099 unsigned int present;
15100 unsigned char bits;
15102 present = snd_hda_codec_read(codec, 0x1b, 0,
15103 AC_VERB_GET_PIN_SENSE, 0)
15104 & AC_PINSENSE_PRESENCE;
15105 bits = present ? 0 : PIN_OUT;
15106 snd_hda_codec_write(codec, 0x14, 0,
15107 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15110 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15112 unsigned int present1, present2;
15114 present1 = snd_hda_codec_read(codec, 0x21, 0,
15115 AC_VERB_GET_PIN_SENSE, 0)
15116 & AC_PINSENSE_PRESENCE;
15117 present2 = snd_hda_codec_read(codec, 0x15, 0,
15118 AC_VERB_GET_PIN_SENSE, 0)
15119 & AC_PINSENSE_PRESENCE;
15121 if (present1 || present2) {
15122 snd_hda_codec_write_cache(codec, 0x14, 0,
15123 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15125 snd_hda_codec_write_cache(codec, 0x14, 0,
15126 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15130 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15132 unsigned int present1, present2;
15134 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15135 AC_VERB_GET_PIN_SENSE, 0)
15136 & AC_PINSENSE_PRESENCE;
15137 present2 = snd_hda_codec_read(codec, 0x15, 0,
15138 AC_VERB_GET_PIN_SENSE, 0)
15139 & AC_PINSENSE_PRESENCE;
15141 if (present1 || present2) {
15142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15143 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15144 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15145 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15147 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15148 AMP_IN_MUTE(0), 0);
15149 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15150 AMP_IN_MUTE(0), 0);
15154 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15156 unsigned int present;
15158 present = snd_hda_codec_read(codec, 0x18, 0,
15159 AC_VERB_GET_PIN_SENSE, 0)
15160 & AC_PINSENSE_PRESENCE;
15161 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15162 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15163 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15164 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15165 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15166 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15167 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15168 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15171 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15174 switch (res >> 26) {
15175 case ALC880_HP_EVENT:
15176 alc663_m51va_speaker_automute(codec);
15178 case ALC880_MIC_EVENT:
15179 alc663_m51va_mic_automute(codec);
15184 static void alc663_m51va_inithook(struct hda_codec *codec)
15186 alc663_m51va_speaker_automute(codec);
15187 alc663_m51va_mic_automute(codec);
15190 /* ***************** Mode1 ******************************/
15191 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15194 switch (res >> 26) {
15195 case ALC880_HP_EVENT:
15196 alc663_m51va_speaker_automute(codec);
15198 case ALC880_MIC_EVENT:
15199 alc662_eeepc_mic_automute(codec);
15204 static void alc663_mode1_inithook(struct hda_codec *codec)
15206 alc663_m51va_speaker_automute(codec);
15207 alc662_eeepc_mic_automute(codec);
15209 /* ***************** Mode2 ******************************/
15210 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15213 switch (res >> 26) {
15214 case ALC880_HP_EVENT:
15215 alc662_f5z_speaker_automute(codec);
15217 case ALC880_MIC_EVENT:
15218 alc662_eeepc_mic_automute(codec);
15223 static void alc662_mode2_inithook(struct hda_codec *codec)
15225 alc662_f5z_speaker_automute(codec);
15226 alc662_eeepc_mic_automute(codec);
15228 /* ***************** Mode3 ******************************/
15229 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15232 switch (res >> 26) {
15233 case ALC880_HP_EVENT:
15234 alc663_two_hp_m1_speaker_automute(codec);
15236 case ALC880_MIC_EVENT:
15237 alc662_eeepc_mic_automute(codec);
15242 static void alc663_mode3_inithook(struct hda_codec *codec)
15244 alc663_two_hp_m1_speaker_automute(codec);
15245 alc662_eeepc_mic_automute(codec);
15247 /* ***************** Mode4 ******************************/
15248 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15251 switch (res >> 26) {
15252 case ALC880_HP_EVENT:
15253 alc663_21jd_two_speaker_automute(codec);
15255 case ALC880_MIC_EVENT:
15256 alc662_eeepc_mic_automute(codec);
15261 static void alc663_mode4_inithook(struct hda_codec *codec)
15263 alc663_21jd_two_speaker_automute(codec);
15264 alc662_eeepc_mic_automute(codec);
15266 /* ***************** Mode5 ******************************/
15267 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15270 switch (res >> 26) {
15271 case ALC880_HP_EVENT:
15272 alc663_15jd_two_speaker_automute(codec);
15274 case ALC880_MIC_EVENT:
15275 alc662_eeepc_mic_automute(codec);
15280 static void alc663_mode5_inithook(struct hda_codec *codec)
15282 alc663_15jd_two_speaker_automute(codec);
15283 alc662_eeepc_mic_automute(codec);
15285 /* ***************** Mode6 ******************************/
15286 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15289 switch (res >> 26) {
15290 case ALC880_HP_EVENT:
15291 alc663_two_hp_m2_speaker_automute(codec);
15293 case ALC880_MIC_EVENT:
15294 alc662_eeepc_mic_automute(codec);
15299 static void alc663_mode6_inithook(struct hda_codec *codec)
15301 alc663_two_hp_m2_speaker_automute(codec);
15302 alc662_eeepc_mic_automute(codec);
15305 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15307 unsigned int present;
15308 unsigned char bits;
15310 present = snd_hda_codec_read(codec, 0x21, 0,
15311 AC_VERB_GET_PIN_SENSE, 0)
15312 & AC_PINSENSE_PRESENCE;
15313 bits = present ? HDA_AMP_MUTE : 0;
15314 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15315 HDA_AMP_MUTE, bits);
15316 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15317 HDA_AMP_MUTE, bits);
15320 static void alc663_g71v_front_automute(struct hda_codec *codec)
15322 unsigned int present;
15323 unsigned char bits;
15325 present = snd_hda_codec_read(codec, 0x15, 0,
15326 AC_VERB_GET_PIN_SENSE, 0)
15327 & AC_PINSENSE_PRESENCE;
15328 bits = present ? HDA_AMP_MUTE : 0;
15329 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15330 HDA_AMP_MUTE, bits);
15333 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15336 switch (res >> 26) {
15337 case ALC880_HP_EVENT:
15338 alc663_g71v_hp_automute(codec);
15340 case ALC880_FRONT_EVENT:
15341 alc663_g71v_front_automute(codec);
15343 case ALC880_MIC_EVENT:
15344 alc662_eeepc_mic_automute(codec);
15349 static void alc663_g71v_inithook(struct hda_codec *codec)
15351 alc663_g71v_front_automute(codec);
15352 alc663_g71v_hp_automute(codec);
15353 alc662_eeepc_mic_automute(codec);
15356 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15359 switch (res >> 26) {
15360 case ALC880_HP_EVENT:
15361 alc663_m51va_speaker_automute(codec);
15363 case ALC880_MIC_EVENT:
15364 alc662_eeepc_mic_automute(codec);
15369 static void alc663_g50v_inithook(struct hda_codec *codec)
15371 alc663_m51va_speaker_automute(codec);
15372 alc662_eeepc_mic_automute(codec);
15375 /* bind hp and internal speaker mute (with plug check) */
15376 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15377 struct snd_ctl_elem_value *ucontrol)
15379 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15380 long *valp = ucontrol->value.integer.value;
15383 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15385 valp[0] ? 0 : HDA_AMP_MUTE);
15386 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15388 valp[1] ? 0 : HDA_AMP_MUTE);
15390 alc262_hippo1_automute(codec);
15394 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15395 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15397 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15398 .name = "Master Playback Switch",
15399 .info = snd_hda_mixer_amp_switch_info,
15400 .get = snd_hda_mixer_amp_switch_get,
15401 .put = alc662_ecs_master_sw_put,
15402 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15405 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15406 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15407 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15409 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15410 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15411 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15415 #ifdef CONFIG_SND_HDA_POWER_SAVE
15416 #define alc662_loopbacks alc880_loopbacks
15420 /* pcm configuration: identiacal with ALC880 */
15421 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15422 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15423 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15424 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15427 * configuration and preset
15429 static const char *alc662_models[ALC662_MODEL_LAST] = {
15430 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15431 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15432 [ALC662_3ST_6ch] = "3stack-6ch",
15433 [ALC662_5ST_DIG] = "6stack-dig",
15434 [ALC662_LENOVO_101E] = "lenovo-101e",
15435 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15436 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15437 [ALC662_ECS] = "ecs",
15438 [ALC663_ASUS_M51VA] = "m51va",
15439 [ALC663_ASUS_G71V] = "g71v",
15440 [ALC663_ASUS_H13] = "h13",
15441 [ALC663_ASUS_G50V] = "g50v",
15442 [ALC663_ASUS_MODE1] = "asus-mode1",
15443 [ALC662_ASUS_MODE2] = "asus-mode2",
15444 [ALC663_ASUS_MODE3] = "asus-mode3",
15445 [ALC663_ASUS_MODE4] = "asus-mode4",
15446 [ALC663_ASUS_MODE5] = "asus-mode5",
15447 [ALC663_ASUS_MODE6] = "asus-mode6",
15448 [ALC662_AUTO] = "auto",
15451 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15452 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15453 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15454 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15455 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15456 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15457 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15458 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15459 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15460 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15461 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15462 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15463 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15464 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15465 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15466 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15467 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15468 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15469 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15470 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15471 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15472 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15473 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15474 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15475 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15476 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15477 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15478 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15479 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15480 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15481 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15482 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15483 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15484 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15485 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15486 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15487 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15488 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15489 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15490 ALC662_3ST_6ch_DIG),
15491 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15492 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15493 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15494 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15495 ALC662_3ST_6ch_DIG),
15496 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15497 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15498 ALC662_3ST_6ch_DIG),
15499 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15500 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15501 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15505 static struct alc_config_preset alc662_presets[] = {
15506 [ALC662_3ST_2ch_DIG] = {
15507 .mixers = { alc662_3ST_2ch_mixer },
15508 .init_verbs = { alc662_init_verbs },
15509 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15510 .dac_nids = alc662_dac_nids,
15511 .dig_out_nid = ALC662_DIGOUT_NID,
15512 .dig_in_nid = ALC662_DIGIN_NID,
15513 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15514 .channel_mode = alc662_3ST_2ch_modes,
15515 .input_mux = &alc662_capture_source,
15517 [ALC662_3ST_6ch_DIG] = {
15518 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15519 .init_verbs = { alc662_init_verbs },
15520 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15521 .dac_nids = alc662_dac_nids,
15522 .dig_out_nid = ALC662_DIGOUT_NID,
15523 .dig_in_nid = ALC662_DIGIN_NID,
15524 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15525 .channel_mode = alc662_3ST_6ch_modes,
15527 .input_mux = &alc662_capture_source,
15529 [ALC662_3ST_6ch] = {
15530 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15531 .init_verbs = { alc662_init_verbs },
15532 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15533 .dac_nids = alc662_dac_nids,
15534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15535 .channel_mode = alc662_3ST_6ch_modes,
15537 .input_mux = &alc662_capture_source,
15539 [ALC662_5ST_DIG] = {
15540 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
15541 .init_verbs = { alc662_init_verbs },
15542 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15543 .dac_nids = alc662_dac_nids,
15544 .dig_out_nid = ALC662_DIGOUT_NID,
15545 .dig_in_nid = ALC662_DIGIN_NID,
15546 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15547 .channel_mode = alc662_5stack_modes,
15548 .input_mux = &alc662_capture_source,
15550 [ALC662_LENOVO_101E] = {
15551 .mixers = { alc662_lenovo_101e_mixer },
15552 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15553 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15554 .dac_nids = alc662_dac_nids,
15555 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15556 .channel_mode = alc662_3ST_2ch_modes,
15557 .input_mux = &alc662_lenovo_101e_capture_source,
15558 .unsol_event = alc662_lenovo_101e_unsol_event,
15559 .init_hook = alc662_lenovo_101e_all_automute,
15561 [ALC662_ASUS_EEEPC_P701] = {
15562 .mixers = { alc662_eeepc_p701_mixer },
15563 .init_verbs = { alc662_init_verbs,
15564 alc662_eeepc_sue_init_verbs },
15565 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15566 .dac_nids = alc662_dac_nids,
15567 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15568 .channel_mode = alc662_3ST_2ch_modes,
15569 .input_mux = &alc662_eeepc_capture_source,
15570 .unsol_event = alc662_eeepc_unsol_event,
15571 .init_hook = alc662_eeepc_inithook,
15573 [ALC662_ASUS_EEEPC_EP20] = {
15574 .mixers = { alc662_eeepc_ep20_mixer,
15575 alc662_chmode_mixer },
15576 .init_verbs = { alc662_init_verbs,
15577 alc662_eeepc_ep20_sue_init_verbs },
15578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15579 .dac_nids = alc662_dac_nids,
15580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15581 .channel_mode = alc662_3ST_6ch_modes,
15582 .input_mux = &alc662_lenovo_101e_capture_source,
15583 .unsol_event = alc662_eeepc_ep20_unsol_event,
15584 .init_hook = alc662_eeepc_ep20_inithook,
15587 .mixers = { alc662_ecs_mixer },
15588 .init_verbs = { alc662_init_verbs,
15589 alc662_ecs_init_verbs },
15590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15591 .dac_nids = alc662_dac_nids,
15592 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15593 .channel_mode = alc662_3ST_2ch_modes,
15594 .input_mux = &alc662_eeepc_capture_source,
15595 .unsol_event = alc662_eeepc_unsol_event,
15596 .init_hook = alc662_eeepc_inithook,
15598 [ALC663_ASUS_M51VA] = {
15599 .mixers = { alc663_m51va_mixer },
15600 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15602 .dac_nids = alc662_dac_nids,
15603 .dig_out_nid = ALC662_DIGOUT_NID,
15604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15605 .channel_mode = alc662_3ST_2ch_modes,
15606 .input_mux = &alc663_m51va_capture_source,
15607 .unsol_event = alc663_m51va_unsol_event,
15608 .init_hook = alc663_m51va_inithook,
15610 [ALC663_ASUS_G71V] = {
15611 .mixers = { alc663_g71v_mixer },
15612 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15613 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15614 .dac_nids = alc662_dac_nids,
15615 .dig_out_nid = ALC662_DIGOUT_NID,
15616 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15617 .channel_mode = alc662_3ST_2ch_modes,
15618 .input_mux = &alc662_eeepc_capture_source,
15619 .unsol_event = alc663_g71v_unsol_event,
15620 .init_hook = alc663_g71v_inithook,
15622 [ALC663_ASUS_H13] = {
15623 .mixers = { alc663_m51va_mixer },
15624 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15625 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15626 .dac_nids = alc662_dac_nids,
15627 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15628 .channel_mode = alc662_3ST_2ch_modes,
15629 .input_mux = &alc663_m51va_capture_source,
15630 .unsol_event = alc663_m51va_unsol_event,
15631 .init_hook = alc663_m51va_inithook,
15633 [ALC663_ASUS_G50V] = {
15634 .mixers = { alc663_g50v_mixer },
15635 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15636 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15637 .dac_nids = alc662_dac_nids,
15638 .dig_out_nid = ALC662_DIGOUT_NID,
15639 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15640 .channel_mode = alc662_3ST_6ch_modes,
15641 .input_mux = &alc663_capture_source,
15642 .unsol_event = alc663_g50v_unsol_event,
15643 .init_hook = alc663_g50v_inithook,
15645 [ALC663_ASUS_MODE1] = {
15646 .mixers = { alc663_m51va_mixer },
15647 .cap_mixer = alc662_auto_capture_mixer,
15648 .init_verbs = { alc662_init_verbs,
15649 alc663_21jd_amic_init_verbs },
15650 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15652 .dac_nids = alc662_dac_nids,
15653 .dig_out_nid = ALC662_DIGOUT_NID,
15654 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15655 .channel_mode = alc662_3ST_2ch_modes,
15656 .input_mux = &alc662_eeepc_capture_source,
15657 .unsol_event = alc663_mode1_unsol_event,
15658 .init_hook = alc663_mode1_inithook,
15660 [ALC662_ASUS_MODE2] = {
15661 .mixers = { alc662_1bjd_mixer },
15662 .cap_mixer = alc662_auto_capture_mixer,
15663 .init_verbs = { alc662_init_verbs,
15664 alc662_1bjd_amic_init_verbs },
15665 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15666 .dac_nids = alc662_dac_nids,
15667 .dig_out_nid = ALC662_DIGOUT_NID,
15668 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15669 .channel_mode = alc662_3ST_2ch_modes,
15670 .input_mux = &alc662_eeepc_capture_source,
15671 .unsol_event = alc662_mode2_unsol_event,
15672 .init_hook = alc662_mode2_inithook,
15674 [ALC663_ASUS_MODE3] = {
15675 .mixers = { alc663_two_hp_m1_mixer },
15676 .cap_mixer = alc662_auto_capture_mixer,
15677 .init_verbs = { alc662_init_verbs,
15678 alc663_two_hp_amic_m1_init_verbs },
15679 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15681 .dac_nids = alc662_dac_nids,
15682 .dig_out_nid = ALC662_DIGOUT_NID,
15683 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15684 .channel_mode = alc662_3ST_2ch_modes,
15685 .input_mux = &alc662_eeepc_capture_source,
15686 .unsol_event = alc663_mode3_unsol_event,
15687 .init_hook = alc663_mode3_inithook,
15689 [ALC663_ASUS_MODE4] = {
15690 .mixers = { alc663_asus_21jd_clfe_mixer },
15691 .cap_mixer = alc662_auto_capture_mixer,
15692 .init_verbs = { alc662_init_verbs,
15693 alc663_21jd_amic_init_verbs},
15694 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15696 .dac_nids = alc662_dac_nids,
15697 .dig_out_nid = ALC662_DIGOUT_NID,
15698 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15699 .channel_mode = alc662_3ST_2ch_modes,
15700 .input_mux = &alc662_eeepc_capture_source,
15701 .unsol_event = alc663_mode4_unsol_event,
15702 .init_hook = alc663_mode4_inithook,
15704 [ALC663_ASUS_MODE5] = {
15705 .mixers = { alc663_asus_15jd_clfe_mixer },
15706 .cap_mixer = alc662_auto_capture_mixer,
15707 .init_verbs = { alc662_init_verbs,
15708 alc663_15jd_amic_init_verbs },
15709 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15711 .dac_nids = alc662_dac_nids,
15712 .dig_out_nid = ALC662_DIGOUT_NID,
15713 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15714 .channel_mode = alc662_3ST_2ch_modes,
15715 .input_mux = &alc662_eeepc_capture_source,
15716 .unsol_event = alc663_mode5_unsol_event,
15717 .init_hook = alc663_mode5_inithook,
15719 [ALC663_ASUS_MODE6] = {
15720 .mixers = { alc663_two_hp_m2_mixer },
15721 .cap_mixer = alc662_auto_capture_mixer,
15722 .init_verbs = { alc662_init_verbs,
15723 alc663_two_hp_amic_m2_init_verbs },
15724 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15726 .dac_nids = alc662_dac_nids,
15727 .dig_out_nid = ALC662_DIGOUT_NID,
15728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15729 .channel_mode = alc662_3ST_2ch_modes,
15730 .input_mux = &alc662_eeepc_capture_source,
15731 .unsol_event = alc663_mode6_unsol_event,
15732 .init_hook = alc663_mode6_inithook,
15738 * BIOS auto configuration
15741 /* add playback controls from the parsed DAC table */
15742 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
15743 const struct auto_pin_cfg *cfg)
15746 static const char *chname[4] = {
15747 "Front", "Surround", NULL /*CLFE*/, "Side"
15752 for (i = 0; i < cfg->line_outs; i++) {
15753 if (!spec->multiout.dac_nids[i])
15755 nid = alc880_idx_to_dac(i);
15758 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15759 "Center Playback Volume",
15760 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
15764 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15765 "LFE Playback Volume",
15766 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
15770 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15771 "Center Playback Switch",
15772 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
15776 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
15777 "LFE Playback Switch",
15778 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
15783 sprintf(name, "%s Playback Volume", chname[i]);
15784 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15785 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
15789 sprintf(name, "%s Playback Switch", chname[i]);
15790 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15791 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
15800 /* add playback controls for speaker and HP outputs */
15801 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
15812 /* ALC663 has a mono output pin on 0x17 */
15813 sprintf(name, "%s Playback Switch", pfx);
15814 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15815 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
15819 if (alc880_is_fixed_pin(pin)) {
15820 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15821 /* printk("DAC nid=%x\n",nid); */
15822 /* specify the DAC as the extra output */
15823 if (!spec->multiout.hp_nid)
15824 spec->multiout.hp_nid = nid;
15826 spec->multiout.extra_out_nid[0] = nid;
15827 /* control HP volume/switch on the output mixer amp */
15828 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15829 sprintf(name, "%s Playback Volume", pfx);
15830 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15831 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
15834 sprintf(name, "%s Playback Switch", pfx);
15835 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15836 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
15839 } else if (alc880_is_multi_pin(pin)) {
15840 /* set manual connection */
15841 /* we have only a switch on HP-out PIN */
15842 sprintf(name, "%s Playback Switch", pfx);
15843 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15844 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15851 /* create playback/capture controls for input pins */
15852 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
15853 const struct auto_pin_cfg *cfg)
15855 struct hda_input_mux *imux = &spec->private_imux;
15858 for (i = 0; i < AUTO_PIN_LAST; i++) {
15859 if (alc880_is_input_pin(cfg->input_pins[i])) {
15860 idx = alc880_input_pin_idx(cfg->input_pins[i]);
15861 err = new_analog_input(spec, cfg->input_pins[i],
15862 auto_pin_cfg_labels[i],
15866 imux->items[imux->num_items].label =
15867 auto_pin_cfg_labels[i];
15868 imux->items[imux->num_items].index =
15869 alc880_input_pin_idx(cfg->input_pins[i]);
15876 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
15877 hda_nid_t nid, int pin_type,
15880 alc_set_pin_output(codec, nid, pin_type);
15881 /* need the manual connection? */
15882 if (alc880_is_multi_pin(nid)) {
15883 struct alc_spec *spec = codec->spec;
15884 int idx = alc880_multi_pin_idx(nid);
15885 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
15886 AC_VERB_SET_CONNECT_SEL,
15887 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
15891 static void alc662_auto_init_multi_out(struct hda_codec *codec)
15893 struct alc_spec *spec = codec->spec;
15896 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
15897 for (i = 0; i <= HDA_SIDE; i++) {
15898 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15899 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15901 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
15906 static void alc662_auto_init_hp_out(struct hda_codec *codec)
15908 struct alc_spec *spec = codec->spec;
15911 pin = spec->autocfg.hp_pins[0];
15912 if (pin) /* connect to front */
15914 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15915 pin = spec->autocfg.speaker_pins[0];
15917 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15920 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
15921 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
15923 static void alc662_auto_init_analog_input(struct hda_codec *codec)
15925 struct alc_spec *spec = codec->spec;
15928 for (i = 0; i < AUTO_PIN_LAST; i++) {
15929 hda_nid_t nid = spec->autocfg.input_pins[i];
15930 if (alc662_is_input_pin(nid)) {
15931 snd_hda_codec_write(codec, nid, 0,
15932 AC_VERB_SET_PIN_WIDGET_CONTROL,
15933 (i <= AUTO_PIN_FRONT_MIC ?
15934 PIN_VREF80 : PIN_IN));
15935 if (nid != ALC662_PIN_CD_NID)
15936 snd_hda_codec_write(codec, nid, 0,
15937 AC_VERB_SET_AMP_GAIN_MUTE,
15943 #define alc662_auto_init_input_src alc882_auto_init_input_src
15945 static int alc662_parse_auto_config(struct hda_codec *codec)
15947 struct alc_spec *spec = codec->spec;
15949 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
15951 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15955 if (!spec->autocfg.line_outs)
15956 return 0; /* can't find valid BIOS pin config */
15958 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15961 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
15964 err = alc662_auto_create_extra_out(spec,
15965 spec->autocfg.speaker_pins[0],
15969 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
15973 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
15977 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15979 if (spec->autocfg.dig_out_pin)
15980 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
15982 if (spec->kctls.list)
15983 add_mixer(spec, spec->kctls.list);
15985 spec->num_mux_defs = 1;
15986 spec->input_mux = &spec->private_imux;
15988 add_verb(spec, alc662_auto_init_verbs);
15989 if (codec->vendor_id == 0x10ec0663)
15990 add_verb(spec, alc663_auto_init_verbs);
15992 err = alc_auto_add_mic_boost(codec);
15996 store_pin_configs(codec);
16000 /* additional initialization for auto-configuration model */
16001 static void alc662_auto_init(struct hda_codec *codec)
16003 struct alc_spec *spec = codec->spec;
16004 alc662_auto_init_multi_out(codec);
16005 alc662_auto_init_hp_out(codec);
16006 alc662_auto_init_analog_input(codec);
16007 alc662_auto_init_input_src(codec);
16008 if (spec->unsol_event)
16009 alc_inithook(codec);
16012 static int patch_alc662(struct hda_codec *codec)
16014 struct alc_spec *spec;
16015 int err, board_config;
16017 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16021 codec->spec = spec;
16023 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16025 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16028 if (board_config < 0) {
16029 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16030 "trying auto-probe from BIOS...\n");
16031 board_config = ALC662_AUTO;
16034 if (board_config == ALC662_AUTO) {
16035 /* automatic parse from the BIOS config */
16036 err = alc662_parse_auto_config(codec);
16042 "hda_codec: Cannot set up configuration "
16043 "from BIOS. Using base mode...\n");
16044 board_config = ALC662_3ST_2ch_DIG;
16048 if (board_config != ALC662_AUTO)
16049 setup_preset(spec, &alc662_presets[board_config]);
16051 if (codec->vendor_id == 0x10ec0663) {
16052 spec->stream_name_analog = "ALC663 Analog";
16053 spec->stream_name_digital = "ALC663 Digital";
16054 } else if (codec->vendor_id == 0x10ec0272) {
16055 spec->stream_name_analog = "ALC272 Analog";
16056 spec->stream_name_digital = "ALC272 Digital";
16058 spec->stream_name_analog = "ALC662 Analog";
16059 spec->stream_name_digital = "ALC662 Digital";
16062 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16063 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16065 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16066 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16068 spec->adc_nids = alc662_adc_nids;
16069 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16070 spec->capsrc_nids = alc662_capsrc_nids;
16071 spec->is_mix_capture = 1;
16073 if (!spec->cap_mixer)
16074 set_capture_mixer(spec);
16076 spec->vmaster_nid = 0x02;
16078 codec->patch_ops = alc_patch_ops;
16079 if (board_config == ALC662_AUTO)
16080 spec->init_hook = alc662_auto_init;
16081 #ifdef CONFIG_SND_HDA_POWER_SAVE
16082 if (!spec->loopback.amplist)
16083 spec->loopback.amplist = alc662_loopbacks;
16092 struct hda_codec_preset snd_hda_preset_realtek[] = {
16093 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16094 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16095 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16096 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16097 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16098 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16099 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16100 .patch = patch_alc861 },
16101 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16102 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16103 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16104 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16105 .patch = patch_alc883 },
16106 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16107 .patch = patch_alc662 },
16108 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16109 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16110 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16111 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16112 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16113 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16114 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16115 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16116 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16117 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16118 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16119 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16120 .patch = patch_alc883 },
16121 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16122 {} /* terminator */