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"
34 #define ALC880_FRONT_EVENT 0x01
35 #define ALC880_DCVOL_EVENT 0x02
36 #define ALC880_HP_EVENT 0x04
37 #define ALC880_MIC_EVENT 0x08
39 /* ALC880 board config type */
62 #ifdef CONFIG_SND_DEBUG
66 ALC880_MODEL_LAST /* last tag */
78 #ifdef CONFIG_SND_DEBUG
82 ALC260_MODEL_LAST /* last tag */
92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF,
101 ALC262_MODEL_LAST /* last tag */
111 #ifdef CONFIG_SND_DEBUG
115 ALC268_MODEL_LAST /* last tag */
122 ALC269_MODEL_LAST /* last tag */
139 /* ALC861-VD models */
160 ALC662_ASUS_EEEPC_P701,
161 ALC662_ASUS_EEEPC_EP20,
189 ALC883_TARGA_2ch_DIG,
195 ALC883_LENOVO_101E_2ch,
196 ALC883_LENOVO_NB0763,
197 ALC888_LENOVO_MS7195_DIG,
208 #define GPIO_MASK 0x03
211 /* codec parameterization */
212 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
213 unsigned int num_mixers;
215 const struct hda_verb *init_verbs[5]; /* initialization verbs
219 unsigned int num_init_verbs;
221 char *stream_name_analog; /* analog PCM stream */
222 struct hda_pcm_stream *stream_analog_playback;
223 struct hda_pcm_stream *stream_analog_capture;
224 struct hda_pcm_stream *stream_analog_alt_playback;
225 struct hda_pcm_stream *stream_analog_alt_capture;
227 char *stream_name_digital; /* digital PCM stream */
228 struct hda_pcm_stream *stream_digital_playback;
229 struct hda_pcm_stream *stream_digital_capture;
232 struct hda_multi_out multiout; /* playback set-up
233 * max_channels, dacs must be set
234 * dig_out_nid and hp_nid are optional
236 hda_nid_t alt_dac_nid;
239 unsigned int num_adc_nids;
241 hda_nid_t dig_in_nid; /* digital-in NID; optional */
244 unsigned int num_mux_defs;
245 const struct hda_input_mux *input_mux;
246 unsigned int cur_mux[3];
249 const struct hda_channel_mode *channel_mode;
250 int num_channel_mode;
253 /* PCM information */
254 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
256 /* dynamic controls, init_verbs and input_mux */
257 struct auto_pin_cfg autocfg;
258 unsigned int num_kctl_alloc, num_kctl_used;
259 struct snd_kcontrol_new *kctl_alloc;
260 struct hda_input_mux private_imux;
261 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
264 void (*init_hook)(struct hda_codec *codec);
265 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
267 /* for pin sensing */
268 unsigned int sense_updated: 1;
269 unsigned int jack_present: 1;
270 unsigned int master_sw: 1;
272 /* for virtual master */
273 hda_nid_t vmaster_nid;
275 #ifdef CONFIG_SND_HDA_POWER_SAVE
276 struct hda_loopback_check loopback;
281 * configuration template - to be copied to the spec instance
283 struct alc_config_preset {
284 struct snd_kcontrol_new *mixers[5]; /* should be identical size
287 const struct hda_verb *init_verbs[5];
288 unsigned int num_dacs;
290 hda_nid_t dig_out_nid; /* optional */
291 hda_nid_t hp_nid; /* optional */
292 unsigned int num_adc_nids;
294 hda_nid_t dig_in_nid;
295 unsigned int num_channel_mode;
296 const struct hda_channel_mode *channel_mode;
298 unsigned int num_mux_defs;
299 const struct hda_input_mux *input_mux;
300 void (*unsol_event)(struct hda_codec *, unsigned int);
301 void (*init_hook)(struct hda_codec *);
302 #ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_amp_list *loopbacks;
311 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_info *uinfo)
314 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct alc_spec *spec = codec->spec;
316 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
317 if (mux_idx >= spec->num_mux_defs)
319 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
322 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
323 struct snd_ctl_elem_value *ucontrol)
325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326 struct alc_spec *spec = codec->spec;
327 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
329 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
333 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
334 struct snd_ctl_elem_value *ucontrol)
336 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
337 struct alc_spec *spec = codec->spec;
338 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
339 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
340 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
341 spec->adc_nids[adc_idx],
342 &spec->cur_mux[adc_idx]);
347 * channel mode setting
349 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
350 struct snd_ctl_elem_info *uinfo)
352 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
353 struct alc_spec *spec = codec->spec;
354 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
355 spec->num_channel_mode);
358 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
359 struct snd_ctl_elem_value *ucontrol)
361 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
362 struct alc_spec *spec = codec->spec;
363 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
364 spec->num_channel_mode,
365 spec->multiout.max_channels);
368 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
369 struct snd_ctl_elem_value *ucontrol)
371 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
372 struct alc_spec *spec = codec->spec;
373 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
374 spec->num_channel_mode,
375 &spec->multiout.max_channels);
376 if (err >= 0 && spec->need_dac_fix)
377 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
382 * Control the mode of pin widget settings via the mixer. "pc" is used
383 * instead of "%" to avoid consequences of accidently treating the % as
384 * being part of a format specifier. Maximum allowed length of a value is
385 * 63 characters plus NULL terminator.
387 * Note: some retasking pin complexes seem to ignore requests for input
388 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
389 * are requested. Therefore order this list so that this behaviour will not
390 * cause problems when mixer clients move through the enum sequentially.
391 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
394 static char *alc_pin_mode_names[] = {
395 "Mic 50pc bias", "Mic 80pc bias",
396 "Line in", "Line out", "Headphone out",
398 static unsigned char alc_pin_mode_values[] = {
399 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
401 /* The control can present all 5 options, or it can limit the options based
402 * in the pin being assumed to be exclusively an input or an output pin. In
403 * addition, "input" pins may or may not process the mic bias option
404 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
405 * accept requests for bias as of chip versions up to March 2006) and/or
406 * wiring in the computer.
408 #define ALC_PIN_DIR_IN 0x00
409 #define ALC_PIN_DIR_OUT 0x01
410 #define ALC_PIN_DIR_INOUT 0x02
411 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
412 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
414 /* Info about the pin modes supported by the different pin direction modes.
415 * For each direction the minimum and maximum values are given.
417 static signed char alc_pin_mode_dir_info[5][2] = {
418 { 0, 2 }, /* ALC_PIN_DIR_IN */
419 { 3, 4 }, /* ALC_PIN_DIR_OUT */
420 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
421 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
422 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
424 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
425 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
426 #define alc_pin_mode_n_items(_dir) \
427 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
429 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
430 struct snd_ctl_elem_info *uinfo)
432 unsigned int item_num = uinfo->value.enumerated.item;
433 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
435 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
437 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
439 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
440 item_num = alc_pin_mode_min(dir);
441 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
445 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
450 hda_nid_t nid = kcontrol->private_value & 0xffff;
451 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
452 long *valp = ucontrol->value.integer.value;
453 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
454 AC_VERB_GET_PIN_WIDGET_CONTROL,
457 /* Find enumerated value for current pinctl setting */
458 i = alc_pin_mode_min(dir);
459 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
461 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
465 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_value *ucontrol)
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 hda_nid_t nid = kcontrol->private_value & 0xffff;
471 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
472 long val = *ucontrol->value.integer.value;
473 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
474 AC_VERB_GET_PIN_WIDGET_CONTROL,
477 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
478 val = alc_pin_mode_min(dir);
480 change = pinctl != alc_pin_mode_values[val];
482 /* Set pin mode to that requested */
483 snd_hda_codec_write_cache(codec, nid, 0,
484 AC_VERB_SET_PIN_WIDGET_CONTROL,
485 alc_pin_mode_values[val]);
487 /* Also enable the retasking pin's input/output as required
488 * for the requested pin mode. Enum values of 2 or less are
491 * Dynamically switching the input/output buffers probably
492 * reduces noise slightly (particularly on input) so we'll
493 * do it. However, having both input and output buffers
494 * enabled simultaneously doesn't seem to be problematic if
495 * this turns out to be necessary in the future.
498 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
499 HDA_AMP_MUTE, HDA_AMP_MUTE);
500 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
503 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
504 HDA_AMP_MUTE, HDA_AMP_MUTE);
505 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
512 #define ALC_PIN_MODE(xname, nid, dir) \
513 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
514 .info = alc_pin_mode_info, \
515 .get = alc_pin_mode_get, \
516 .put = alc_pin_mode_put, \
517 .private_value = nid | (dir<<16) }
519 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
520 * together using a mask with more than one bit set. This control is
521 * currently used only by the ALC260 test model. At this stage they are not
522 * needed for any "production" models.
524 #ifdef CONFIG_SND_DEBUG
525 #define alc_gpio_data_info snd_ctl_boolean_mono_info
527 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
528 struct snd_ctl_elem_value *ucontrol)
530 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
531 hda_nid_t nid = kcontrol->private_value & 0xffff;
532 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
533 long *valp = ucontrol->value.integer.value;
534 unsigned int val = snd_hda_codec_read(codec, nid, 0,
535 AC_VERB_GET_GPIO_DATA, 0x00);
537 *valp = (val & mask) != 0;
540 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
541 struct snd_ctl_elem_value *ucontrol)
544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
545 hda_nid_t nid = kcontrol->private_value & 0xffff;
546 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
547 long val = *ucontrol->value.integer.value;
548 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
549 AC_VERB_GET_GPIO_DATA,
552 /* Set/unset the masked GPIO bit(s) as needed */
553 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
558 snd_hda_codec_write_cache(codec, nid, 0,
559 AC_VERB_SET_GPIO_DATA, gpio_data);
563 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
564 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
565 .info = alc_gpio_data_info, \
566 .get = alc_gpio_data_get, \
567 .put = alc_gpio_data_put, \
568 .private_value = nid | (mask<<16) }
569 #endif /* CONFIG_SND_DEBUG */
571 /* A switch control to allow the enabling of the digital IO pins on the
572 * ALC260. This is incredibly simplistic; the intention of this control is
573 * to provide something in the test model allowing digital outputs to be
574 * identified if present. If models are found which can utilise these
575 * outputs a more complete mixer control can be devised for those models if
578 #ifdef CONFIG_SND_DEBUG
579 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
581 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *ucontrol)
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long *valp = ucontrol->value.integer.value;
588 unsigned int val = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
591 *valp = (val & mask) != 0;
594 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
595 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 val = *ucontrol->value.integer.value;
602 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
603 AC_VERB_GET_DIGI_CONVERT_1,
606 /* Set/unset the masked control bit(s) as needed */
607 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
612 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
617 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
618 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
619 .info = alc_spdif_ctrl_info, \
620 .get = alc_spdif_ctrl_get, \
621 .put = alc_spdif_ctrl_put, \
622 .private_value = nid | (mask<<16) }
623 #endif /* CONFIG_SND_DEBUG */
625 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
626 * Again, this is only used in the ALC26x test models to help identify when
627 * the EAPD line must be asserted for features to work.
629 #ifdef CONFIG_SND_DEBUG
630 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
632 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol)
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 hda_nid_t nid = kcontrol->private_value & 0xffff;
637 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
638 long *valp = ucontrol->value.integer.value;
639 unsigned int val = snd_hda_codec_read(codec, nid, 0,
640 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
642 *valp = (val & mask) != 0;
646 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
647 struct snd_ctl_elem_value *ucontrol)
650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
651 hda_nid_t nid = kcontrol->private_value & 0xffff;
652 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
653 long val = *ucontrol->value.integer.value;
654 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
655 AC_VERB_GET_EAPD_BTLENABLE,
658 /* Set/unset the masked control bit(s) as needed */
659 change = (!val ? 0 : mask) != (ctrl_data & mask);
664 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
670 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
672 .info = alc_eapd_ctrl_info, \
673 .get = alc_eapd_ctrl_get, \
674 .put = alc_eapd_ctrl_put, \
675 .private_value = nid | (mask<<16) }
676 #endif /* CONFIG_SND_DEBUG */
679 * set up from the preset table
681 static void setup_preset(struct alc_spec *spec,
682 const struct alc_config_preset *preset)
686 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
687 spec->mixers[spec->num_mixers++] = preset->mixers[i];
688 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
690 spec->init_verbs[spec->num_init_verbs++] =
691 preset->init_verbs[i];
693 spec->channel_mode = preset->channel_mode;
694 spec->num_channel_mode = preset->num_channel_mode;
695 spec->need_dac_fix = preset->need_dac_fix;
697 spec->multiout.max_channels = spec->channel_mode[0].channels;
699 spec->multiout.num_dacs = preset->num_dacs;
700 spec->multiout.dac_nids = preset->dac_nids;
701 spec->multiout.dig_out_nid = preset->dig_out_nid;
702 spec->multiout.hp_nid = preset->hp_nid;
704 spec->num_mux_defs = preset->num_mux_defs;
705 if (!spec->num_mux_defs)
706 spec->num_mux_defs = 1;
707 spec->input_mux = preset->input_mux;
709 spec->num_adc_nids = preset->num_adc_nids;
710 spec->adc_nids = preset->adc_nids;
711 spec->dig_in_nid = preset->dig_in_nid;
713 spec->unsol_event = preset->unsol_event;
714 spec->init_hook = preset->init_hook;
715 #ifdef CONFIG_SND_HDA_POWER_SAVE
716 spec->loopback.amplist = preset->loopbacks;
720 /* Enable GPIO mask and set output */
721 static struct hda_verb alc_gpio1_init_verbs[] = {
722 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
723 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
724 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
728 static struct hda_verb alc_gpio2_init_verbs[] = {
729 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
730 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
731 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
735 static struct hda_verb alc_gpio3_init_verbs[] = {
736 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
737 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
738 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
742 static void alc_sku_automute(struct hda_codec *codec)
744 struct alc_spec *spec = codec->spec;
746 unsigned int present;
747 unsigned int hp_nid = spec->autocfg.hp_pins[0];
748 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
750 /* need to execute and sync at first */
751 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
752 present = snd_hda_codec_read(codec, hp_nid, 0,
753 AC_VERB_GET_PIN_SENSE, 0);
754 spec->jack_present = (present & 0x80000000) != 0;
755 if (spec->jack_present) {
756 /* mute internal speaker */
757 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
758 HDA_AMP_MUTE, HDA_AMP_MUTE);
760 /* unmute internal speaker if necessary */
761 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
762 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
767 /* unsolicited event for HP jack sensing */
768 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
770 if (codec->vendor_id == 0x10ec0880)
774 if (res != ALC880_HP_EVENT)
777 alc_sku_automute(codec);
780 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
781 * 31 ~ 16 : Manufacture ID
783 * 7 ~ 0 : Assembly ID
784 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
786 static void alc_subsystem_id(struct hda_codec *codec,
787 unsigned int porta, unsigned int porte,
790 unsigned int ass, tmp, i;
792 struct alc_spec *spec = codec->spec;
794 ass = codec->subsystem_id & 0xffff;
795 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
799 * 31~30 : port conetcivity
802 * 19~16 : Check sum (15:1)
807 if (codec->vendor_id == 0x10ec0260)
809 ass = snd_hda_codec_read(codec, nid, 0,
810 AC_VERB_GET_CONFIG_DEFAULT, 0);
811 if (!(ass & 1) && !(ass & 0x100000))
813 if ((ass >> 30) != 1) /* no physical connection */
818 for (i = 1; i < 16; i++) {
822 if (((ass >> 16) & 0xf) != tmp)
828 * 2 : 0 --> Desktop, 1 --> Laptop
829 * 3~5 : External Amplifier control
832 tmp = (ass & 0x38) >> 3; /* external Amp control */
835 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
838 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
841 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
843 case 5: /* set EAPD output high */
844 switch (codec->vendor_id) {
846 snd_hda_codec_write(codec, 0x0f, 0,
847 AC_VERB_SET_EAPD_BTLENABLE, 2);
848 snd_hda_codec_write(codec, 0x10, 0,
849 AC_VERB_SET_EAPD_BTLENABLE, 2);
857 snd_hda_codec_write(codec, 0x14, 0,
858 AC_VERB_SET_EAPD_BTLENABLE, 2);
859 snd_hda_codec_write(codec, 0x15, 0,
860 AC_VERB_SET_EAPD_BTLENABLE, 2);
863 switch (codec->vendor_id) {
865 snd_hda_codec_write(codec, 0x1a, 0,
866 AC_VERB_SET_COEF_INDEX, 7);
867 tmp = snd_hda_codec_read(codec, 0x1a, 0,
868 AC_VERB_GET_PROC_COEF, 0);
869 snd_hda_codec_write(codec, 0x1a, 0,
870 AC_VERB_SET_COEF_INDEX, 7);
871 snd_hda_codec_write(codec, 0x1a, 0,
872 AC_VERB_SET_PROC_COEF,
881 snd_hda_codec_write(codec, 0x20, 0,
882 AC_VERB_SET_COEF_INDEX, 7);
883 tmp = snd_hda_codec_read(codec, 0x20, 0,
884 AC_VERB_GET_PROC_COEF, 0);
885 snd_hda_codec_write(codec, 0x20, 0,
886 AC_VERB_SET_COEF_INDEX, 7);
887 snd_hda_codec_write(codec, 0x20, 0,
888 AC_VERB_SET_PROC_COEF,
893 snd_hda_codec_write(codec, 0x20, 0,
894 AC_VERB_SET_COEF_INDEX, 7);
895 tmp = snd_hda_codec_read(codec, 0x20, 0,
896 AC_VERB_GET_PROC_COEF, 0);
897 snd_hda_codec_write(codec, 0x20, 0,
898 AC_VERB_SET_COEF_INDEX, 7);
899 snd_hda_codec_write(codec, 0x20, 0,
900 AC_VERB_SET_PROC_COEF,
908 /* is laptop or Desktop and enable the function "Mute internal speaker
909 * when the external headphone out jack is plugged"
914 * 10~8 : Jack location
915 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
917 * 15 : 1 --> enable the function "Mute internal speaker
918 * when the external headphone out jack is plugged"
920 if (!spec->autocfg.speaker_pins[0]) {
921 if (spec->autocfg.line_out_pins[0])
922 spec->autocfg.speaker_pins[0] =
923 spec->autocfg.line_out_pins[0];
928 if (!spec->autocfg.hp_pins[0]) {
929 tmp = (ass >> 11) & 0x3; /* HP to chassis */
931 spec->autocfg.hp_pins[0] = porta;
933 spec->autocfg.hp_pins[0] = porte;
935 spec->autocfg.hp_pins[0] = portd;
940 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
941 AC_VERB_SET_UNSOLICITED_ENABLE,
942 AC_USRSP_EN | ALC880_HP_EVENT);
943 spec->unsol_event = alc_sku_unsol_event;
944 spec->init_hook = alc_sku_automute;
948 * Fix-up pin default configurations
956 static void alc_fix_pincfg(struct hda_codec *codec,
957 const struct snd_pci_quirk *quirk,
958 const struct alc_pincfg **pinfix)
960 const struct alc_pincfg *cfg;
962 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
966 cfg = pinfix[quirk->value];
967 for (; cfg->nid; cfg++) {
970 for (i = 0; i < 4; i++) {
971 snd_hda_codec_write(codec, cfg->nid, 0,
972 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
980 * ALC880 3-stack model
982 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
983 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
984 * F-Mic = 0x1b, HP = 0x19
987 static hda_nid_t alc880_dac_nids[4] = {
988 /* front, rear, clfe, rear_surr */
989 0x02, 0x05, 0x04, 0x03
992 static hda_nid_t alc880_adc_nids[3] = {
997 /* The datasheet says the node 0x07 is connected from inputs,
998 * but it shows zero connection in the real implementation on some devices.
999 * Note: this is a 915GAV bug, fixed on 915GLV
1001 static hda_nid_t alc880_adc_nids_alt[2] = {
1006 #define ALC880_DIGOUT_NID 0x06
1007 #define ALC880_DIGIN_NID 0x0a
1009 static struct hda_input_mux alc880_capture_source = {
1013 { "Front Mic", 0x3 },
1019 /* channel source setting (2/6 channel selection for 3-stack) */
1021 static struct hda_verb alc880_threestack_ch2_init[] = {
1022 /* set line-in to input, mute it */
1023 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1024 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1025 /* set mic-in to input vref 80%, mute it */
1026 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1027 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1032 static struct hda_verb alc880_threestack_ch6_init[] = {
1033 /* set line-in to output, unmute it */
1034 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1035 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1036 /* set mic-in to output, unmute it */
1037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1042 static struct hda_channel_mode alc880_threestack_modes[2] = {
1043 { 2, alc880_threestack_ch2_init },
1044 { 6, alc880_threestack_ch6_init },
1047 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1048 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1049 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1052 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1053 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1054 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1055 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1056 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1057 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1059 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1062 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1064 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1065 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1069 .name = "Channel Mode",
1070 .info = alc_ch_mode_info,
1071 .get = alc_ch_mode_get,
1072 .put = alc_ch_mode_put,
1077 /* capture mixer elements */
1078 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1079 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1080 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1081 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1082 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1083 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1084 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1086 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1087 /* The multiple "Capture Source" controls confuse alsamixer
1088 * So call somewhat different..
1090 /* .name = "Capture Source", */
1091 .name = "Input Source",
1093 .info = alc_mux_enum_info,
1094 .get = alc_mux_enum_get,
1095 .put = alc_mux_enum_put,
1100 /* capture mixer elements (in case NID 0x07 not available) */
1101 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1102 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1103 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1104 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1105 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108 /* The multiple "Capture Source" controls confuse alsamixer
1109 * So call somewhat different..
1111 /* .name = "Capture Source", */
1112 .name = "Input Source",
1114 .info = alc_mux_enum_info,
1115 .get = alc_mux_enum_get,
1116 .put = alc_mux_enum_put,
1124 * ALC880 5-stack model
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1128 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1129 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1132 /* additional mixers to alc880_three_stack_mixer */
1133 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1134 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1135 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1139 /* channel source setting (6/8 channel selection for 5-stack) */
1141 static struct hda_verb alc880_fivestack_ch6_init[] = {
1142 /* set line-in to input, mute it */
1143 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1144 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1149 static struct hda_verb alc880_fivestack_ch8_init[] = {
1150 /* set line-in to output, unmute it */
1151 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1152 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1156 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1157 { 6, alc880_fivestack_ch6_init },
1158 { 8, alc880_fivestack_ch8_init },
1163 * ALC880 6-stack model
1165 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1166 * Side = 0x05 (0x0f)
1167 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1168 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1171 static hda_nid_t alc880_6st_dac_nids[4] = {
1172 /* front, rear, clfe, rear_surr */
1173 0x02, 0x03, 0x04, 0x05
1176 static struct hda_input_mux alc880_6stack_capture_source = {
1180 { "Front Mic", 0x1 },
1186 /* fixed 8-channels */
1187 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1191 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1195 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1196 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1198 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1200 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1201 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1202 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1203 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1205 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1207 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1208 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1209 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1210 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1211 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1213 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1214 .name = "Channel Mode",
1215 .info = alc_ch_mode_info,
1216 .get = alc_ch_mode_get,
1217 .put = alc_ch_mode_put,
1226 * W810 has rear IO for:
1229 * Center/LFE (DAC 04)
1232 * The system also has a pair of internal speakers, and a headphone jack.
1233 * These are both connected to Line2 on the codec, hence to DAC 02.
1235 * There is a variable resistor to control the speaker or headphone
1236 * volume. This is a hardware-only device without a software API.
1238 * Plugging headphones in will disable the internal speakers. This is
1239 * implemented in hardware, not via the driver using jack sense. In
1240 * a similar fashion, plugging into the rear socket marked "front" will
1241 * disable both the speakers and headphones.
1243 * For input, there's a microphone jack, and an "audio in" jack.
1244 * These may not do anything useful with this driver yet, because I
1245 * haven't setup any initialization verbs for these yet...
1248 static hda_nid_t alc880_w810_dac_nids[3] = {
1249 /* front, rear/surround, clfe */
1253 /* fixed 6 channels */
1254 static struct hda_channel_mode alc880_w810_modes[1] = {
1258 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1259 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1260 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1261 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1262 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1263 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1264 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1265 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1266 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1267 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1276 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1277 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1281 static hda_nid_t alc880_z71v_dac_nids[1] = {
1284 #define ALC880_Z71V_HP_DAC 0x03
1286 /* fixed 2 channels */
1287 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1291 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1292 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1293 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1295 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1305 * ALC880 F1734 model
1307 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1308 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1311 static hda_nid_t alc880_f1734_dac_nids[1] = {
1314 #define ALC880_F1734_HP_DAC 0x02
1316 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1318 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1319 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1320 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1321 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1322 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1323 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1324 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1332 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1333 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1334 * Mic = 0x18, Line = 0x1a
1337 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1338 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1340 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1341 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1342 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1344 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1345 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1346 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1347 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1348 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1349 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1350 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .name = "Channel Mode",
1358 .info = alc_ch_mode_info,
1359 .get = alc_ch_mode_get,
1360 .put = alc_ch_mode_put,
1366 * ALC880 ASUS W1V model
1368 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1369 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1370 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1373 /* additional mixers to alc880_asus_mixer */
1374 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1375 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1376 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1380 /* additional mixers to alc880_asus_mixer */
1381 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1382 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1383 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1388 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1389 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1390 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1392 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1393 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1396 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1397 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1399 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1400 /* The multiple "Capture Source" controls confuse alsamixer
1401 * So call somewhat different..
1403 /* .name = "Capture Source", */
1404 .name = "Input Source",
1406 .info = alc_mux_enum_info,
1407 .get = alc_mux_enum_get,
1408 .put = alc_mux_enum_put,
1414 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1416 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1417 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1418 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1419 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1420 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1421 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1422 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1423 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1424 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1425 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1426 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1429 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1430 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1431 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1432 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1434 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1435 .name = "Channel Mode",
1436 .info = alc_ch_mode_info,
1437 .get = alc_ch_mode_get,
1438 .put = alc_ch_mode_put,
1443 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1445 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1446 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1447 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1448 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1449 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1450 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1451 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1452 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1453 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1457 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1458 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1459 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1460 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1461 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1468 * virtual master controls
1472 * slave controls for virtual master
1474 static const char *alc_slave_vols[] = {
1475 "Front Playback Volume",
1476 "Surround Playback Volume",
1477 "Center Playback Volume",
1478 "LFE Playback Volume",
1479 "Side Playback Volume",
1480 "Headphone Playback Volume",
1481 "Speaker Playback Volume",
1482 "Mono Playback Volume",
1483 "Line-Out Playback Volume",
1487 static const char *alc_slave_sws[] = {
1488 "Front Playback Switch",
1489 "Surround Playback Switch",
1490 "Center Playback Switch",
1491 "LFE Playback Switch",
1492 "Side Playback Switch",
1493 "Headphone Playback Switch",
1494 "Speaker Playback Switch",
1495 "Mono Playback Switch",
1496 "IEC958 Playback Switch",
1501 * build control elements
1503 static int alc_build_controls(struct hda_codec *codec)
1505 struct alc_spec *spec = codec->spec;
1509 for (i = 0; i < spec->num_mixers; i++) {
1510 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1515 if (spec->multiout.dig_out_nid) {
1516 err = snd_hda_create_spdif_out_ctls(codec,
1517 spec->multiout.dig_out_nid);
1521 if (spec->dig_in_nid) {
1522 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1527 /* if we have no master control, let's create it */
1528 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1529 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1530 HDA_OUTPUT, spec->vmaster_tlv);
1531 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1532 spec->vmaster_tlv, alc_slave_vols);
1536 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1537 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1538 NULL, alc_slave_sws);
1548 * initialize the codec volumes, etc
1552 * generic initialization of ADC, input mixers and output mixers
1554 static struct hda_verb alc880_volume_init_verbs[] = {
1556 * Unmute ADC0-2 and set the default input to mic-in
1558 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1559 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1560 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1562 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1565 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1567 * Note: PASD motherboards uses the Line In 2 as the input for front
1570 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1580 * Set up output mixers (0x0c - 0x0f)
1582 /* set vol=0 to output mixers */
1583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1586 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1587 /* set up input amps for analog loopback */
1588 /* Amp Indices: DAC = 0, mixer = 1 */
1589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1591 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1593 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1602 * 3-stack pin configuration:
1603 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1605 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1607 * preset connection lists of input pins
1608 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1610 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1611 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1612 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1615 * Set pin mode and muting
1617 /* set front pin widgets 0x14 for output */
1618 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1620 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1623 /* Mic2 (as headphone out) for HP output */
1624 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1625 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1626 /* Line In pin widget for input */
1627 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1628 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1629 /* Line2 (as front mic) pin widget for input and vref at 80% */
1630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1631 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1632 /* CD pin widget for input */
1633 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1639 * 5-stack pin configuration:
1640 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1641 * line-in/side = 0x1a, f-mic = 0x1b
1643 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1645 * preset connection lists of input pins
1646 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1648 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1649 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1652 * Set pin mode and muting
1654 /* set pin widgets 0x14-0x17 for output */
1655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1657 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1658 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1659 /* unmute pins for output (no gain on this amp) */
1660 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1663 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1665 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1666 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1667 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1668 /* Mic2 (as headphone out) for HP output */
1669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1671 /* Line In pin widget for input */
1672 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1674 /* Line2 (as front mic) pin widget for input and vref at 80% */
1675 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1676 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1677 /* CD pin widget for input */
1678 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1684 * W810 pin configuration:
1685 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1687 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1688 /* hphone/speaker input selector: front DAC */
1689 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1696 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1705 * Z71V pin configuration:
1706 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1708 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1714 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1715 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1716 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1717 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1723 * 6-stack pin configuration:
1724 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1725 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1727 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1728 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1737 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1739 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1741 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1742 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1743 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1744 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1746 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1753 * Uniwill pin configuration:
1754 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1757 static struct hda_verb alc880_uniwill_init_verbs[] = {
1758 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1764 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1767 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1770 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1771 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1772 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1773 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1779 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1780 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1781 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1782 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1785 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1786 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1793 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1795 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1796 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1798 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1804 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1808 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1809 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1811 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1818 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1819 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1824 static struct hda_verb alc880_beep_init_verbs[] = {
1825 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1829 /* toggle speaker-output according to the hp-jack state */
1830 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1832 unsigned int present;
1835 present = snd_hda_codec_read(codec, 0x14, 0,
1836 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1837 bits = present ? HDA_AMP_MUTE : 0;
1838 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1839 HDA_AMP_MUTE, bits);
1840 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1841 HDA_AMP_MUTE, bits);
1844 /* auto-toggle front mic */
1845 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1847 unsigned int present;
1850 present = snd_hda_codec_read(codec, 0x18, 0,
1851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1852 bits = present ? HDA_AMP_MUTE : 0;
1853 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1856 static void alc880_uniwill_automute(struct hda_codec *codec)
1858 alc880_uniwill_hp_automute(codec);
1859 alc880_uniwill_mic_automute(codec);
1862 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1865 /* Looks like the unsol event is incompatible with the standard
1866 * definition. 4bit tag is placed at 28 bit!
1868 switch (res >> 28) {
1869 case ALC880_HP_EVENT:
1870 alc880_uniwill_hp_automute(codec);
1872 case ALC880_MIC_EVENT:
1873 alc880_uniwill_mic_automute(codec);
1878 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1880 unsigned int present;
1883 present = snd_hda_codec_read(codec, 0x14, 0,
1884 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1885 bits = present ? HDA_AMP_MUTE : 0;
1886 snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1889 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1891 unsigned int present;
1893 present = snd_hda_codec_read(codec, 0x21, 0,
1894 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1895 present &= HDA_AMP_VOLMASK;
1896 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1897 HDA_AMP_VOLMASK, present);
1898 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1899 HDA_AMP_VOLMASK, present);
1902 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1905 /* Looks like the unsol event is incompatible with the standard
1906 * definition. 4bit tag is placed at 28 bit!
1908 if ((res >> 28) == ALC880_HP_EVENT)
1909 alc880_uniwill_p53_hp_automute(codec);
1910 if ((res >> 28) == ALC880_DCVOL_EVENT)
1911 alc880_uniwill_p53_dcvol_automute(codec);
1915 * F1734 pin configuration:
1916 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1918 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1919 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1920 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1921 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1922 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1927 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1930 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1931 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1943 * ASUS pin configuration:
1944 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1946 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1947 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1948 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1949 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1955 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1957 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1958 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1959 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1962 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1963 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1965 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1967 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1968 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1969 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1974 /* Enable GPIO mask and set output */
1975 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1976 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1978 /* Clevo m520g init */
1979 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1980 /* headphone output */
1981 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1986 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1987 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1989 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1990 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1991 /* Mic1 (rear panel) */
1992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1994 /* Mic2 (front panel) */
1995 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1996 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1998 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1999 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2000 /* change to EAPD mode */
2001 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2002 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2007 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2008 /* change to EAPD mode */
2009 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2010 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2012 /* Headphone output */
2013 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2016 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2018 /* Line In pin widget for input */
2019 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2020 /* CD pin widget for input */
2021 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2022 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2023 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2025 /* change to EAPD mode */
2026 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2027 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2033 * LG m1 express dual
2036 * Rear Line-In/Out (blue): 0x14
2037 * Build-in Mic-In: 0x15
2039 * HP-Out (green): 0x1b
2040 * Mic-In/Out (red): 0x19
2044 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2045 static hda_nid_t alc880_lg_dac_nids[3] = {
2049 /* seems analog CD is not working */
2050 static struct hda_input_mux alc880_lg_capture_source = {
2055 { "Internal Mic", 0x6 },
2059 /* 2,4,6 channel modes */
2060 static struct hda_verb alc880_lg_ch2_init[] = {
2061 /* set line-in and mic-in to input */
2062 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2063 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2067 static struct hda_verb alc880_lg_ch4_init[] = {
2068 /* set line-in to out and mic-in to input */
2069 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2070 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2074 static struct hda_verb alc880_lg_ch6_init[] = {
2075 /* set line-in and mic-in to output */
2076 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2077 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2081 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2082 { 2, alc880_lg_ch2_init },
2083 { 4, alc880_lg_ch4_init },
2084 { 6, alc880_lg_ch6_init },
2087 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2088 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2089 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2090 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2097 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2101 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2103 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2104 .name = "Channel Mode",
2105 .info = alc_ch_mode_info,
2106 .get = alc_ch_mode_get,
2107 .put = alc_ch_mode_put,
2112 static struct hda_verb alc880_lg_init_verbs[] = {
2113 /* set capture source to mic-in */
2114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2115 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2116 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2117 /* mute all amp mixer inputs */
2118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2121 /* line-in to input */
2122 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2123 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2128 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2129 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2130 /* mic-in to input */
2131 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2135 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2136 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2139 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2143 /* toggle speaker-output according to the hp-jack state */
2144 static void alc880_lg_automute(struct hda_codec *codec)
2146 unsigned int present;
2149 present = snd_hda_codec_read(codec, 0x1b, 0,
2150 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2151 bits = present ? HDA_AMP_MUTE : 0;
2152 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2153 HDA_AMP_MUTE, bits);
2156 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2158 /* Looks like the unsol event is incompatible with the standard
2159 * definition. 4bit tag is placed at 28 bit!
2161 if ((res >> 28) == 0x01)
2162 alc880_lg_automute(codec);
2171 * Built-in Mic-In: 0x19
2177 static struct hda_input_mux alc880_lg_lw_capture_source = {
2181 { "Internal Mic", 0x1 },
2186 #define alc880_lg_lw_modes alc880_threestack_modes
2188 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2189 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2190 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2191 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2192 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2193 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2194 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2195 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2196 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2202 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2205 .name = "Channel Mode",
2206 .info = alc_ch_mode_info,
2207 .get = alc_ch_mode_get,
2208 .put = alc_ch_mode_put,
2213 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2214 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2215 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2216 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2218 /* set capture source to mic-in */
2219 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2221 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2224 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2225 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2228 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 /* mic-in to input */
2230 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2240 /* toggle speaker-output according to the hp-jack state */
2241 static void alc880_lg_lw_automute(struct hda_codec *codec)
2243 unsigned int present;
2246 present = snd_hda_codec_read(codec, 0x1b, 0,
2247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2248 bits = present ? HDA_AMP_MUTE : 0;
2249 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2250 HDA_AMP_MUTE, bits);
2253 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2255 /* Looks like the unsol event is incompatible with the standard
2256 * definition. 4bit tag is placed at 28 bit!
2258 if ((res >> 28) == 0x01)
2259 alc880_lg_lw_automute(codec);
2262 #ifdef CONFIG_SND_HDA_POWER_SAVE
2263 static struct hda_amp_list alc880_loopbacks[] = {
2264 { 0x0b, HDA_INPUT, 0 },
2265 { 0x0b, HDA_INPUT, 1 },
2266 { 0x0b, HDA_INPUT, 2 },
2267 { 0x0b, HDA_INPUT, 3 },
2268 { 0x0b, HDA_INPUT, 4 },
2272 static struct hda_amp_list alc880_lg_loopbacks[] = {
2273 { 0x0b, HDA_INPUT, 1 },
2274 { 0x0b, HDA_INPUT, 6 },
2275 { 0x0b, HDA_INPUT, 7 },
2284 static int alc_init(struct hda_codec *codec)
2286 struct alc_spec *spec = codec->spec;
2289 for (i = 0; i < spec->num_init_verbs; i++)
2290 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2292 if (spec->init_hook)
2293 spec->init_hook(codec);
2298 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2300 struct alc_spec *spec = codec->spec;
2302 if (spec->unsol_event)
2303 spec->unsol_event(codec, res);
2306 #ifdef CONFIG_SND_HDA_POWER_SAVE
2307 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2309 struct alc_spec *spec = codec->spec;
2310 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2315 * Analog playback callbacks
2317 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2318 struct hda_codec *codec,
2319 struct snd_pcm_substream *substream)
2321 struct alc_spec *spec = codec->spec;
2322 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2325 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2326 struct hda_codec *codec,
2327 unsigned int stream_tag,
2328 unsigned int format,
2329 struct snd_pcm_substream *substream)
2331 struct alc_spec *spec = codec->spec;
2332 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2333 stream_tag, format, substream);
2336 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2337 struct hda_codec *codec,
2338 struct snd_pcm_substream *substream)
2340 struct alc_spec *spec = codec->spec;
2341 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2347 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2348 struct hda_codec *codec,
2349 struct snd_pcm_substream *substream)
2351 struct alc_spec *spec = codec->spec;
2352 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2355 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2356 struct hda_codec *codec,
2357 unsigned int stream_tag,
2358 unsigned int format,
2359 struct snd_pcm_substream *substream)
2361 struct alc_spec *spec = codec->spec;
2362 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2363 stream_tag, format, substream);
2366 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2367 struct hda_codec *codec,
2368 struct snd_pcm_substream *substream)
2370 struct alc_spec *spec = codec->spec;
2371 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2377 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2378 struct hda_codec *codec,
2379 unsigned int stream_tag,
2380 unsigned int format,
2381 struct snd_pcm_substream *substream)
2383 struct alc_spec *spec = codec->spec;
2385 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2386 stream_tag, 0, format);
2390 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2391 struct hda_codec *codec,
2392 struct snd_pcm_substream *substream)
2394 struct alc_spec *spec = codec->spec;
2396 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2404 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2408 /* NID is set in alc_build_pcms */
2410 .open = alc880_playback_pcm_open,
2411 .prepare = alc880_playback_pcm_prepare,
2412 .cleanup = alc880_playback_pcm_cleanup
2416 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2420 /* NID is set in alc_build_pcms */
2423 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2427 /* NID is set in alc_build_pcms */
2430 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2431 .substreams = 2, /* can be overridden */
2434 /* NID is set in alc_build_pcms */
2436 .prepare = alc880_alt_capture_pcm_prepare,
2437 .cleanup = alc880_alt_capture_pcm_cleanup
2441 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2445 /* NID is set in alc_build_pcms */
2447 .open = alc880_dig_playback_pcm_open,
2448 .close = alc880_dig_playback_pcm_close,
2449 .prepare = alc880_dig_playback_pcm_prepare
2453 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2457 /* NID is set in alc_build_pcms */
2460 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2461 static struct hda_pcm_stream alc_pcm_null_stream = {
2467 static int alc_build_pcms(struct hda_codec *codec)
2469 struct alc_spec *spec = codec->spec;
2470 struct hda_pcm *info = spec->pcm_rec;
2473 codec->num_pcms = 1;
2474 codec->pcm_info = info;
2476 info->name = spec->stream_name_analog;
2477 if (spec->stream_analog_playback) {
2478 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2479 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2482 if (spec->stream_analog_capture) {
2483 snd_assert(spec->adc_nids, return -EINVAL);
2484 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2488 if (spec->channel_mode) {
2489 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2490 for (i = 0; i < spec->num_channel_mode; i++) {
2491 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2492 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2497 /* SPDIF for stream index #1 */
2498 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2499 codec->num_pcms = 2;
2500 info = spec->pcm_rec + 1;
2501 info->name = spec->stream_name_digital;
2502 if (spec->multiout.dig_out_nid &&
2503 spec->stream_digital_playback) {
2504 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2505 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2507 if (spec->dig_in_nid &&
2508 spec->stream_digital_capture) {
2509 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2510 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2514 /* If the use of more than one ADC is requested for the current
2515 * model, configure a second analog capture-only PCM.
2517 /* Additional Analaog capture for index #2 */
2518 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2519 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2520 codec->num_pcms = 3;
2521 info = spec->pcm_rec + 2;
2522 info->name = spec->stream_name_analog;
2523 if (spec->alt_dac_nid) {
2524 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2525 *spec->stream_analog_alt_playback;
2526 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2529 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2530 alc_pcm_null_stream;
2531 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2533 if (spec->num_adc_nids > 1) {
2534 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2535 *spec->stream_analog_alt_capture;
2536 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2538 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2539 spec->num_adc_nids - 1;
2541 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2542 alc_pcm_null_stream;
2543 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2550 static void alc_free(struct hda_codec *codec)
2552 struct alc_spec *spec = codec->spec;
2558 if (spec->kctl_alloc) {
2559 for (i = 0; i < spec->num_kctl_used; i++)
2560 kfree(spec->kctl_alloc[i].name);
2561 kfree(spec->kctl_alloc);
2568 static struct hda_codec_ops alc_patch_ops = {
2569 .build_controls = alc_build_controls,
2570 .build_pcms = alc_build_pcms,
2573 .unsol_event = alc_unsol_event,
2574 #ifdef CONFIG_SND_HDA_POWER_SAVE
2575 .check_power_status = alc_check_power_status,
2581 * Test configuration for debugging
2583 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2586 #ifdef CONFIG_SND_DEBUG
2587 static hda_nid_t alc880_test_dac_nids[4] = {
2588 0x02, 0x03, 0x04, 0x05
2591 static struct hda_input_mux alc880_test_capture_source = {
2600 { "Surround", 0x6 },
2604 static struct hda_channel_mode alc880_test_modes[4] = {
2611 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2612 struct snd_ctl_elem_info *uinfo)
2614 static char *texts[] = {
2615 "N/A", "Line Out", "HP Out",
2616 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2618 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2620 uinfo->value.enumerated.items = 8;
2621 if (uinfo->value.enumerated.item >= 8)
2622 uinfo->value.enumerated.item = 7;
2623 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2627 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2628 struct snd_ctl_elem_value *ucontrol)
2630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2631 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2632 unsigned int pin_ctl, item = 0;
2634 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2635 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2636 if (pin_ctl & AC_PINCTL_OUT_EN) {
2637 if (pin_ctl & AC_PINCTL_HP_EN)
2641 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2642 switch (pin_ctl & AC_PINCTL_VREFEN) {
2643 case AC_PINCTL_VREF_HIZ: item = 3; break;
2644 case AC_PINCTL_VREF_50: item = 4; break;
2645 case AC_PINCTL_VREF_GRD: item = 5; break;
2646 case AC_PINCTL_VREF_80: item = 6; break;
2647 case AC_PINCTL_VREF_100: item = 7; break;
2650 ucontrol->value.enumerated.item[0] = item;
2654 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2655 struct snd_ctl_elem_value *ucontrol)
2657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2658 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2659 static unsigned int ctls[] = {
2660 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2661 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2662 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2663 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2667 unsigned int old_ctl, new_ctl;
2669 old_ctl = snd_hda_codec_read(codec, nid, 0,
2670 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2671 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2672 if (old_ctl != new_ctl) {
2674 snd_hda_codec_write_cache(codec, nid, 0,
2675 AC_VERB_SET_PIN_WIDGET_CONTROL,
2677 val = ucontrol->value.enumerated.item[0] >= 3 ?
2679 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2686 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2687 struct snd_ctl_elem_info *uinfo)
2689 static char *texts[] = {
2690 "Front", "Surround", "CLFE", "Side"
2692 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2694 uinfo->value.enumerated.items = 4;
2695 if (uinfo->value.enumerated.item >= 4)
2696 uinfo->value.enumerated.item = 3;
2697 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2701 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2702 struct snd_ctl_elem_value *ucontrol)
2704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2705 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2708 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2709 ucontrol->value.enumerated.item[0] = sel & 3;
2713 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2714 struct snd_ctl_elem_value *ucontrol)
2716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2717 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2720 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2721 if (ucontrol->value.enumerated.item[0] != sel) {
2722 sel = ucontrol->value.enumerated.item[0] & 3;
2723 snd_hda_codec_write_cache(codec, nid, 0,
2724 AC_VERB_SET_CONNECT_SEL, sel);
2730 #define PIN_CTL_TEST(xname,nid) { \
2731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2733 .info = alc_test_pin_ctl_info, \
2734 .get = alc_test_pin_ctl_get, \
2735 .put = alc_test_pin_ctl_put, \
2736 .private_value = nid \
2739 #define PIN_SRC_TEST(xname,nid) { \
2740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2742 .info = alc_test_pin_src_info, \
2743 .get = alc_test_pin_src_get, \
2744 .put = alc_test_pin_src_put, \
2745 .private_value = nid \
2748 static struct snd_kcontrol_new alc880_test_mixer[] = {
2749 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2750 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2751 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2752 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2753 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2754 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2755 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2756 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2757 PIN_CTL_TEST("Front Pin Mode", 0x14),
2758 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2759 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2760 PIN_CTL_TEST("Side Pin Mode", 0x17),
2761 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2762 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2763 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2764 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2765 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2766 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2767 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2768 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2769 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2770 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2771 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2772 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2773 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2774 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2775 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2776 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2777 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2778 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2781 .name = "Channel Mode",
2782 .info = alc_ch_mode_info,
2783 .get = alc_ch_mode_get,
2784 .put = alc_ch_mode_put,
2789 static struct hda_verb alc880_test_init_verbs[] = {
2790 /* Unmute inputs of 0x0c - 0x0f */
2791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2793 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2794 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2795 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2799 /* Vol output for 0x0c-0x0f */
2800 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2801 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2802 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2804 /* Set output pins 0x14-0x17 */
2805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2807 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2808 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2809 /* Unmute output pins 0x14-0x17 */
2810 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2812 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2813 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2814 /* Set input pins 0x18-0x1c */
2815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2817 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2818 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2819 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2820 /* Mute input pins 0x18-0x1b */
2821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2822 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2823 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2827 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2828 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2829 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2830 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2831 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2832 /* Analog input/passthru */
2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2834 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2845 static const char *alc880_models[ALC880_MODEL_LAST] = {
2846 [ALC880_3ST] = "3stack",
2847 [ALC880_TCL_S700] = "tcl",
2848 [ALC880_3ST_DIG] = "3stack-digout",
2849 [ALC880_CLEVO] = "clevo",
2850 [ALC880_5ST] = "5stack",
2851 [ALC880_5ST_DIG] = "5stack-digout",
2852 [ALC880_W810] = "w810",
2853 [ALC880_Z71V] = "z71v",
2854 [ALC880_6ST] = "6stack",
2855 [ALC880_6ST_DIG] = "6stack-digout",
2856 [ALC880_ASUS] = "asus",
2857 [ALC880_ASUS_W1V] = "asus-w1v",
2858 [ALC880_ASUS_DIG] = "asus-dig",
2859 [ALC880_ASUS_DIG2] = "asus-dig2",
2860 [ALC880_UNIWILL_DIG] = "uniwill",
2861 [ALC880_UNIWILL_P53] = "uniwill-p53",
2862 [ALC880_FUJITSU] = "fujitsu",
2863 [ALC880_F1734] = "F1734",
2865 [ALC880_LG_LW] = "lg-lw",
2866 #ifdef CONFIG_SND_DEBUG
2867 [ALC880_TEST] = "test",
2869 [ALC880_AUTO] = "auto",
2872 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2873 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2874 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2875 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2876 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2877 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2878 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2879 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2880 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2881 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2882 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2883 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2884 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2885 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2886 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2887 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2888 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2889 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2890 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2891 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2892 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2893 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2894 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2895 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2896 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2897 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2898 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2899 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2900 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2901 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2902 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2903 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2904 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2905 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2906 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2907 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2908 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2909 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2910 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2911 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2912 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2913 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2914 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2915 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2916 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2917 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2918 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2919 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2920 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2921 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2922 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2923 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2924 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2925 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2926 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2927 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
2928 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2929 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2930 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2931 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2932 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2933 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2934 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2935 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2936 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2937 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2938 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2939 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
2940 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2941 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2946 * ALC880 codec presets
2948 static struct alc_config_preset alc880_presets[] = {
2950 .mixers = { alc880_three_stack_mixer },
2951 .init_verbs = { alc880_volume_init_verbs,
2952 alc880_pin_3stack_init_verbs },
2953 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2954 .dac_nids = alc880_dac_nids,
2955 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2956 .channel_mode = alc880_threestack_modes,
2958 .input_mux = &alc880_capture_source,
2960 [ALC880_3ST_DIG] = {
2961 .mixers = { alc880_three_stack_mixer },
2962 .init_verbs = { alc880_volume_init_verbs,
2963 alc880_pin_3stack_init_verbs },
2964 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2965 .dac_nids = alc880_dac_nids,
2966 .dig_out_nid = ALC880_DIGOUT_NID,
2967 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2968 .channel_mode = alc880_threestack_modes,
2970 .input_mux = &alc880_capture_source,
2972 [ALC880_TCL_S700] = {
2973 .mixers = { alc880_tcl_s700_mixer },
2974 .init_verbs = { alc880_volume_init_verbs,
2975 alc880_pin_tcl_S700_init_verbs,
2976 alc880_gpio2_init_verbs },
2977 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2978 .dac_nids = alc880_dac_nids,
2980 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2981 .channel_mode = alc880_2_jack_modes,
2982 .input_mux = &alc880_capture_source,
2985 .mixers = { alc880_three_stack_mixer,
2986 alc880_five_stack_mixer},
2987 .init_verbs = { alc880_volume_init_verbs,
2988 alc880_pin_5stack_init_verbs },
2989 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2990 .dac_nids = alc880_dac_nids,
2991 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2992 .channel_mode = alc880_fivestack_modes,
2993 .input_mux = &alc880_capture_source,
2995 [ALC880_5ST_DIG] = {
2996 .mixers = { alc880_three_stack_mixer,
2997 alc880_five_stack_mixer },
2998 .init_verbs = { alc880_volume_init_verbs,
2999 alc880_pin_5stack_init_verbs },
3000 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3001 .dac_nids = alc880_dac_nids,
3002 .dig_out_nid = ALC880_DIGOUT_NID,
3003 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3004 .channel_mode = alc880_fivestack_modes,
3005 .input_mux = &alc880_capture_source,
3008 .mixers = { alc880_six_stack_mixer },
3009 .init_verbs = { alc880_volume_init_verbs,
3010 alc880_pin_6stack_init_verbs },
3011 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3012 .dac_nids = alc880_6st_dac_nids,
3013 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3014 .channel_mode = alc880_sixstack_modes,
3015 .input_mux = &alc880_6stack_capture_source,
3017 [ALC880_6ST_DIG] = {
3018 .mixers = { alc880_six_stack_mixer },
3019 .init_verbs = { alc880_volume_init_verbs,
3020 alc880_pin_6stack_init_verbs },
3021 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3022 .dac_nids = alc880_6st_dac_nids,
3023 .dig_out_nid = ALC880_DIGOUT_NID,
3024 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3025 .channel_mode = alc880_sixstack_modes,
3026 .input_mux = &alc880_6stack_capture_source,
3029 .mixers = { alc880_w810_base_mixer },
3030 .init_verbs = { alc880_volume_init_verbs,
3031 alc880_pin_w810_init_verbs,
3032 alc880_gpio2_init_verbs },
3033 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3034 .dac_nids = alc880_w810_dac_nids,
3035 .dig_out_nid = ALC880_DIGOUT_NID,
3036 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3037 .channel_mode = alc880_w810_modes,
3038 .input_mux = &alc880_capture_source,
3041 .mixers = { alc880_z71v_mixer },
3042 .init_verbs = { alc880_volume_init_verbs,
3043 alc880_pin_z71v_init_verbs },
3044 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3045 .dac_nids = alc880_z71v_dac_nids,
3046 .dig_out_nid = ALC880_DIGOUT_NID,
3048 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3049 .channel_mode = alc880_2_jack_modes,
3050 .input_mux = &alc880_capture_source,
3053 .mixers = { alc880_f1734_mixer },
3054 .init_verbs = { alc880_volume_init_verbs,
3055 alc880_pin_f1734_init_verbs },
3056 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3057 .dac_nids = alc880_f1734_dac_nids,
3059 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3060 .channel_mode = alc880_2_jack_modes,
3061 .input_mux = &alc880_capture_source,
3064 .mixers = { alc880_asus_mixer },
3065 .init_verbs = { alc880_volume_init_verbs,
3066 alc880_pin_asus_init_verbs,
3067 alc880_gpio1_init_verbs },
3068 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3069 .dac_nids = alc880_asus_dac_nids,
3070 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3071 .channel_mode = alc880_asus_modes,
3073 .input_mux = &alc880_capture_source,
3075 [ALC880_ASUS_DIG] = {
3076 .mixers = { alc880_asus_mixer },
3077 .init_verbs = { alc880_volume_init_verbs,
3078 alc880_pin_asus_init_verbs,
3079 alc880_gpio1_init_verbs },
3080 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3081 .dac_nids = alc880_asus_dac_nids,
3082 .dig_out_nid = ALC880_DIGOUT_NID,
3083 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3084 .channel_mode = alc880_asus_modes,
3086 .input_mux = &alc880_capture_source,
3088 [ALC880_ASUS_DIG2] = {
3089 .mixers = { alc880_asus_mixer },
3090 .init_verbs = { alc880_volume_init_verbs,
3091 alc880_pin_asus_init_verbs,
3092 alc880_gpio2_init_verbs }, /* use GPIO2 */
3093 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3094 .dac_nids = alc880_asus_dac_nids,
3095 .dig_out_nid = ALC880_DIGOUT_NID,
3096 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3097 .channel_mode = alc880_asus_modes,
3099 .input_mux = &alc880_capture_source,
3101 [ALC880_ASUS_W1V] = {
3102 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3103 .init_verbs = { alc880_volume_init_verbs,
3104 alc880_pin_asus_init_verbs,
3105 alc880_gpio1_init_verbs },
3106 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3107 .dac_nids = alc880_asus_dac_nids,
3108 .dig_out_nid = ALC880_DIGOUT_NID,
3109 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3110 .channel_mode = alc880_asus_modes,
3112 .input_mux = &alc880_capture_source,
3114 [ALC880_UNIWILL_DIG] = {
3115 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3116 .init_verbs = { alc880_volume_init_verbs,
3117 alc880_pin_asus_init_verbs },
3118 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3119 .dac_nids = alc880_asus_dac_nids,
3120 .dig_out_nid = ALC880_DIGOUT_NID,
3121 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3122 .channel_mode = alc880_asus_modes,
3124 .input_mux = &alc880_capture_source,
3126 [ALC880_UNIWILL] = {
3127 .mixers = { alc880_uniwill_mixer },
3128 .init_verbs = { alc880_volume_init_verbs,
3129 alc880_uniwill_init_verbs },
3130 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3131 .dac_nids = alc880_asus_dac_nids,
3132 .dig_out_nid = ALC880_DIGOUT_NID,
3133 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3134 .channel_mode = alc880_threestack_modes,
3136 .input_mux = &alc880_capture_source,
3137 .unsol_event = alc880_uniwill_unsol_event,
3138 .init_hook = alc880_uniwill_automute,
3140 [ALC880_UNIWILL_P53] = {
3141 .mixers = { alc880_uniwill_p53_mixer },
3142 .init_verbs = { alc880_volume_init_verbs,
3143 alc880_uniwill_p53_init_verbs },
3144 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3145 .dac_nids = alc880_asus_dac_nids,
3146 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3147 .channel_mode = alc880_threestack_modes,
3148 .input_mux = &alc880_capture_source,
3149 .unsol_event = alc880_uniwill_p53_unsol_event,
3150 .init_hook = alc880_uniwill_p53_hp_automute,
3152 [ALC880_FUJITSU] = {
3153 .mixers = { alc880_fujitsu_mixer,
3154 alc880_pcbeep_mixer, },
3155 .init_verbs = { alc880_volume_init_verbs,
3156 alc880_uniwill_p53_init_verbs,
3157 alc880_beep_init_verbs },
3158 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3159 .dac_nids = alc880_dac_nids,
3160 .dig_out_nid = ALC880_DIGOUT_NID,
3161 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3162 .channel_mode = alc880_2_jack_modes,
3163 .input_mux = &alc880_capture_source,
3164 .unsol_event = alc880_uniwill_p53_unsol_event,
3165 .init_hook = alc880_uniwill_p53_hp_automute,
3168 .mixers = { alc880_three_stack_mixer },
3169 .init_verbs = { alc880_volume_init_verbs,
3170 alc880_pin_clevo_init_verbs },
3171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3172 .dac_nids = alc880_dac_nids,
3174 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3175 .channel_mode = alc880_threestack_modes,
3177 .input_mux = &alc880_capture_source,
3180 .mixers = { alc880_lg_mixer },
3181 .init_verbs = { alc880_volume_init_verbs,
3182 alc880_lg_init_verbs },
3183 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3184 .dac_nids = alc880_lg_dac_nids,
3185 .dig_out_nid = ALC880_DIGOUT_NID,
3186 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3187 .channel_mode = alc880_lg_ch_modes,
3189 .input_mux = &alc880_lg_capture_source,
3190 .unsol_event = alc880_lg_unsol_event,
3191 .init_hook = alc880_lg_automute,
3192 #ifdef CONFIG_SND_HDA_POWER_SAVE
3193 .loopbacks = alc880_lg_loopbacks,
3197 .mixers = { alc880_lg_lw_mixer },
3198 .init_verbs = { alc880_volume_init_verbs,
3199 alc880_lg_lw_init_verbs },
3200 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3201 .dac_nids = alc880_dac_nids,
3202 .dig_out_nid = ALC880_DIGOUT_NID,
3203 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3204 .channel_mode = alc880_lg_lw_modes,
3205 .input_mux = &alc880_lg_lw_capture_source,
3206 .unsol_event = alc880_lg_lw_unsol_event,
3207 .init_hook = alc880_lg_lw_automute,
3209 #ifdef CONFIG_SND_DEBUG
3211 .mixers = { alc880_test_mixer },
3212 .init_verbs = { alc880_test_init_verbs },
3213 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3214 .dac_nids = alc880_test_dac_nids,
3215 .dig_out_nid = ALC880_DIGOUT_NID,
3216 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3217 .channel_mode = alc880_test_modes,
3218 .input_mux = &alc880_test_capture_source,
3224 * Automatic parse of I/O pins from the BIOS configuration
3227 #define NUM_CONTROL_ALLOC 32
3228 #define NUM_VERB_ALLOC 32
3232 ALC_CTL_WIDGET_MUTE,
3235 static struct snd_kcontrol_new alc880_control_templates[] = {
3236 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3237 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3238 HDA_BIND_MUTE(NULL, 0, 0, 0),
3241 /* add dynamic controls */
3242 static int add_control(struct alc_spec *spec, int type, const char *name,
3245 struct snd_kcontrol_new *knew;
3247 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3248 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3250 /* array + terminator */
3251 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3254 if (spec->kctl_alloc) {
3255 memcpy(knew, spec->kctl_alloc,
3256 sizeof(*knew) * spec->num_kctl_alloc);
3257 kfree(spec->kctl_alloc);
3259 spec->kctl_alloc = knew;
3260 spec->num_kctl_alloc = num;
3263 knew = &spec->kctl_alloc[spec->num_kctl_used];
3264 *knew = alc880_control_templates[type];
3265 knew->name = kstrdup(name, GFP_KERNEL);
3268 knew->private_value = val;
3269 spec->num_kctl_used++;
3273 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3274 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3275 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3276 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3277 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3278 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3279 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3280 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3281 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3282 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3283 #define ALC880_PIN_CD_NID 0x1c
3285 /* fill in the dac_nids table from the parsed pin configuration */
3286 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3287 const struct auto_pin_cfg *cfg)
3293 memset(assigned, 0, sizeof(assigned));
3294 spec->multiout.dac_nids = spec->private_dac_nids;
3296 /* check the pins hardwired to audio widget */
3297 for (i = 0; i < cfg->line_outs; i++) {
3298 nid = cfg->line_out_pins[i];
3299 if (alc880_is_fixed_pin(nid)) {
3300 int idx = alc880_fixed_pin_idx(nid);
3301 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3305 /* left pins can be connect to any audio widget */
3306 for (i = 0; i < cfg->line_outs; i++) {
3307 nid = cfg->line_out_pins[i];
3308 if (alc880_is_fixed_pin(nid))
3310 /* search for an empty channel */
3311 for (j = 0; j < cfg->line_outs; j++) {
3313 spec->multiout.dac_nids[i] =
3314 alc880_idx_to_dac(j);
3320 spec->multiout.num_dacs = cfg->line_outs;
3324 /* add playback controls from the parsed DAC table */
3325 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3326 const struct auto_pin_cfg *cfg)
3329 static const char *chname[4] = {
3330 "Front", "Surround", NULL /*CLFE*/, "Side"
3335 for (i = 0; i < cfg->line_outs; i++) {
3336 if (!spec->multiout.dac_nids[i])
3338 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3341 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3342 "Center Playback Volume",
3343 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3347 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3348 "LFE Playback Volume",
3349 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3353 err = add_control(spec, ALC_CTL_BIND_MUTE,
3354 "Center Playback Switch",
3355 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3359 err = add_control(spec, ALC_CTL_BIND_MUTE,
3360 "LFE Playback Switch",
3361 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3366 sprintf(name, "%s Playback Volume", chname[i]);
3367 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3368 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3372 sprintf(name, "%s Playback Switch", chname[i]);
3373 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3374 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3383 /* add playback controls for speaker and HP outputs */
3384 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3394 if (alc880_is_fixed_pin(pin)) {
3395 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3396 /* specify the DAC as the extra output */
3397 if (!spec->multiout.hp_nid)
3398 spec->multiout.hp_nid = nid;
3400 spec->multiout.extra_out_nid[0] = nid;
3401 /* control HP volume/switch on the output mixer amp */
3402 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3403 sprintf(name, "%s Playback Volume", pfx);
3404 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3405 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3408 sprintf(name, "%s Playback Switch", pfx);
3409 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3410 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3413 } else if (alc880_is_multi_pin(pin)) {
3414 /* set manual connection */
3415 /* we have only a switch on HP-out PIN */
3416 sprintf(name, "%s Playback Switch", pfx);
3417 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3418 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3425 /* create input playback/capture controls for the given pin */
3426 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3427 const char *ctlname,
3428 int idx, hda_nid_t mix_nid)
3433 sprintf(name, "%s Playback Volume", ctlname);
3434 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3435 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3438 sprintf(name, "%s Playback Switch", ctlname);
3439 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3440 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3446 /* create playback/capture controls for input pins */
3447 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3448 const struct auto_pin_cfg *cfg)
3450 struct hda_input_mux *imux = &spec->private_imux;
3453 for (i = 0; i < AUTO_PIN_LAST; i++) {
3454 if (alc880_is_input_pin(cfg->input_pins[i])) {
3455 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3456 err = new_analog_input(spec, cfg->input_pins[i],
3457 auto_pin_cfg_labels[i],
3461 imux->items[imux->num_items].label =
3462 auto_pin_cfg_labels[i];
3463 imux->items[imux->num_items].index =
3464 alc880_input_pin_idx(cfg->input_pins[i]);
3471 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3472 hda_nid_t nid, int pin_type,
3476 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3478 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3480 /* need the manual connection? */
3481 if (alc880_is_multi_pin(nid)) {
3482 struct alc_spec *spec = codec->spec;
3483 int idx = alc880_multi_pin_idx(nid);
3484 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3485 AC_VERB_SET_CONNECT_SEL,
3486 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3490 static int get_pin_type(int line_out_type)
3492 if (line_out_type == AUTO_PIN_HP_OUT)
3498 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3500 struct alc_spec *spec = codec->spec;
3503 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3504 for (i = 0; i < spec->autocfg.line_outs; i++) {
3505 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3506 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3507 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3511 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3513 struct alc_spec *spec = codec->spec;
3516 pin = spec->autocfg.speaker_pins[0];
3517 if (pin) /* connect to front */
3518 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3519 pin = spec->autocfg.hp_pins[0];
3520 if (pin) /* connect to front */
3521 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3524 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3526 struct alc_spec *spec = codec->spec;
3529 for (i = 0; i < AUTO_PIN_LAST; i++) {
3530 hda_nid_t nid = spec->autocfg.input_pins[i];
3531 if (alc880_is_input_pin(nid)) {
3532 snd_hda_codec_write(codec, nid, 0,
3533 AC_VERB_SET_PIN_WIDGET_CONTROL,
3534 i <= AUTO_PIN_FRONT_MIC ?
3535 PIN_VREF80 : PIN_IN);
3536 if (nid != ALC880_PIN_CD_NID)
3537 snd_hda_codec_write(codec, nid, 0,
3538 AC_VERB_SET_AMP_GAIN_MUTE,
3544 /* parse the BIOS configuration and set up the alc_spec */
3545 /* return 1 if successful, 0 if the proper config is not found,
3546 * or a negative error code
3548 static int alc880_parse_auto_config(struct hda_codec *codec)
3550 struct alc_spec *spec = codec->spec;
3552 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3554 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3558 if (!spec->autocfg.line_outs)
3559 return 0; /* can't find valid BIOS pin config */
3561 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3564 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3567 err = alc880_auto_create_extra_out(spec,
3568 spec->autocfg.speaker_pins[0],
3572 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3576 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3580 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3582 if (spec->autocfg.dig_out_pin)
3583 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3584 if (spec->autocfg.dig_in_pin)
3585 spec->dig_in_nid = ALC880_DIGIN_NID;
3587 if (spec->kctl_alloc)
3588 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3590 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3592 spec->num_mux_defs = 1;
3593 spec->input_mux = &spec->private_imux;
3598 /* additional initialization for auto-configuration model */
3599 static void alc880_auto_init(struct hda_codec *codec)
3601 alc880_auto_init_multi_out(codec);
3602 alc880_auto_init_extra_out(codec);
3603 alc880_auto_init_analog_input(codec);
3607 * OK, here we have finally the patch for ALC880
3610 static int patch_alc880(struct hda_codec *codec)
3612 struct alc_spec *spec;
3616 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3622 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3625 if (board_config < 0) {
3626 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3627 "trying auto-probe from BIOS...\n");
3628 board_config = ALC880_AUTO;
3631 if (board_config == ALC880_AUTO) {
3632 /* automatic parse from the BIOS config */
3633 err = alc880_parse_auto_config(codec);
3639 "hda_codec: Cannot set up configuration "
3640 "from BIOS. Using 3-stack mode...\n");
3641 board_config = ALC880_3ST;
3645 if (board_config != ALC880_AUTO)
3646 setup_preset(spec, &alc880_presets[board_config]);
3648 spec->stream_name_analog = "ALC880 Analog";
3649 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3650 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3651 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3653 spec->stream_name_digital = "ALC880 Digital";
3654 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3655 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3657 if (!spec->adc_nids && spec->input_mux) {
3658 /* check whether NID 0x07 is valid */
3659 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3661 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3662 if (wcap != AC_WID_AUD_IN) {
3663 spec->adc_nids = alc880_adc_nids_alt;
3664 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3665 spec->mixers[spec->num_mixers] =
3666 alc880_capture_alt_mixer;
3669 spec->adc_nids = alc880_adc_nids;
3670 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3671 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3676 spec->vmaster_nid = 0x0c;
3678 codec->patch_ops = alc_patch_ops;
3679 if (board_config == ALC880_AUTO)
3680 spec->init_hook = alc880_auto_init;
3681 #ifdef CONFIG_SND_HDA_POWER_SAVE
3682 if (!spec->loopback.amplist)
3683 spec->loopback.amplist = alc880_loopbacks;
3694 static hda_nid_t alc260_dac_nids[1] = {
3699 static hda_nid_t alc260_adc_nids[1] = {
3704 static hda_nid_t alc260_adc_nids_alt[1] = {
3709 static hda_nid_t alc260_hp_adc_nids[2] = {
3714 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3715 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3717 static hda_nid_t alc260_dual_adc_nids[2] = {
3722 #define ALC260_DIGOUT_NID 0x03
3723 #define ALC260_DIGIN_NID 0x06
3725 static struct hda_input_mux alc260_capture_source = {
3729 { "Front Mic", 0x1 },
3735 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3736 * headphone jack and the internal CD lines since these are the only pins at
3737 * which audio can appear. For flexibility, also allow the option of
3738 * recording the mixer output on the second ADC (ADC0 doesn't have a
3739 * connection to the mixer output).
3741 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3745 { "Mic/Line", 0x0 },
3747 { "Headphone", 0x2 },
3753 { "Mic/Line", 0x0 },
3755 { "Headphone", 0x2 },
3762 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3763 * the Fujitsu S702x, but jacks are marked differently.
3765 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3772 { "Headphone", 0x5 },
3781 { "Headphone", 0x6 },
3787 * This is just place-holder, so there's something for alc_build_pcms to look
3788 * at when it calculates the maximum number of channels. ALC260 has no mixer
3789 * element which allows changing the channel mode, so the verb list is
3792 static struct hda_channel_mode alc260_modes[1] = {
3797 /* Mixer combinations
3799 * basic: base_output + input + pc_beep + capture
3800 * HP: base_output + input + capture_alt
3801 * HP_3013: hp_3013 + input + capture
3802 * fujitsu: fujitsu + capture
3803 * acer: acer + capture
3806 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3807 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3808 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3809 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3810 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3811 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3812 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3816 static struct snd_kcontrol_new alc260_input_mixer[] = {
3817 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3818 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3819 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3820 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3822 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3823 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3824 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3828 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3829 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3830 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3834 /* update HP, line and mono out pins according to the master switch */
3835 static void alc260_hp_master_update(struct hda_codec *codec,
3836 hda_nid_t hp, hda_nid_t line,
3839 struct alc_spec *spec = codec->spec;
3840 unsigned int val = spec->master_sw ? PIN_HP : 0;
3841 /* change HP and line-out pins */
3842 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3844 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3846 /* mono (speaker) depending on the HP jack sense */
3847 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3848 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3852 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3853 struct snd_ctl_elem_value *ucontrol)
3855 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3856 struct alc_spec *spec = codec->spec;
3857 *ucontrol->value.integer.value = spec->master_sw;
3861 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3862 struct snd_ctl_elem_value *ucontrol)
3864 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3865 struct alc_spec *spec = codec->spec;
3866 int val = !!*ucontrol->value.integer.value;
3867 hda_nid_t hp, line, mono;
3869 if (val == spec->master_sw)
3871 spec->master_sw = val;
3872 hp = (kcontrol->private_value >> 16) & 0xff;
3873 line = (kcontrol->private_value >> 8) & 0xff;
3874 mono = kcontrol->private_value & 0xff;
3875 alc260_hp_master_update(codec, hp, line, mono);
3879 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3881 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3882 .name = "Master Playback Switch",
3883 .info = snd_ctl_boolean_mono_info,
3884 .get = alc260_hp_master_sw_get,
3885 .put = alc260_hp_master_sw_put,
3886 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
3888 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3889 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3890 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3891 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3892 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
3894 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3898 static struct hda_verb alc260_hp_unsol_verbs[] = {
3899 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3903 static void alc260_hp_automute(struct hda_codec *codec)
3905 struct alc_spec *spec = codec->spec;
3906 unsigned int present;
3908 present = snd_hda_codec_read(codec, 0x10, 0,
3909 AC_VERB_GET_PIN_SENSE, 0);
3910 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3911 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
3914 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
3916 if ((res >> 26) == ALC880_HP_EVENT)
3917 alc260_hp_automute(codec);
3920 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3922 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3923 .name = "Master Playback Switch",
3924 .info = snd_ctl_boolean_mono_info,
3925 .get = alc260_hp_master_sw_get,
3926 .put = alc260_hp_master_sw_put,
3927 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
3929 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3930 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3931 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3932 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3933 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3934 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3935 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3936 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3940 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
3941 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3945 static void alc260_hp_3013_automute(struct hda_codec *codec)
3947 struct alc_spec *spec = codec->spec;
3948 unsigned int present;
3950 present = snd_hda_codec_read(codec, 0x15, 0,
3951 AC_VERB_GET_PIN_SENSE, 0);
3952 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
3953 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
3956 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
3959 if ((res >> 26) == ALC880_HP_EVENT)
3960 alc260_hp_3013_automute(codec);
3963 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3964 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3966 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3968 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3969 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3970 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3971 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3972 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3973 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3974 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3975 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3976 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3977 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3978 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3982 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3983 * versions of the ALC260 don't act on requests to enable mic bias from NID
3984 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3985 * datasheet doesn't mention this restriction. At this stage it's not clear
3986 * whether this behaviour is intentional or is a hardware bug in chip
3987 * revisions available in early 2006. Therefore for now allow the
3988 * "Headphone Jack Mode" control to span all choices, but if it turns out
3989 * that the lack of mic bias for this NID is intentional we could change the
3990 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3992 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3993 * don't appear to make the mic bias available from the "line" jack, even
3994 * though the NID used for this jack (0x14) can supply it. The theory is
3995 * that perhaps Acer have included blocking capacitors between the ALC260
3996 * and the output jack. If this turns out to be the case for all such
3997 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3998 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4000 * The C20x Tablet series have a mono internal speaker which is controlled
4001 * via the chip's Mono sum widget and pin complex, so include the necessary
4002 * controls for such models. On models without a "mono speaker" the control
4003 * won't do anything.
4005 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4006 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4007 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4008 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4009 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4011 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4016 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4017 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4018 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4019 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4020 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4021 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4022 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4026 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4027 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4029 static struct snd_kcontrol_new alc260_will_mixer[] = {
4030 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4031 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4033 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4034 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4035 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4036 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4037 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4038 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4039 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4040 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4041 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4045 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4046 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4048 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4049 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4050 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4052 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4053 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4054 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4055 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4056 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4057 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4058 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4062 /* capture mixer elements */
4063 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4064 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4065 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4066 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4067 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4070 /* The multiple "Capture Source" controls confuse alsamixer
4071 * So call somewhat different..
4073 /* .name = "Capture Source", */
4074 .name = "Input Source",
4076 .info = alc_mux_enum_info,
4077 .get = alc_mux_enum_get,
4078 .put = alc_mux_enum_put,
4083 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4084 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4085 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4088 /* The multiple "Capture Source" controls confuse alsamixer
4089 * So call somewhat different..
4091 /* .name = "Capture Source", */
4092 .name = "Input Source",
4094 .info = alc_mux_enum_info,
4095 .get = alc_mux_enum_get,
4096 .put = alc_mux_enum_put,
4102 * initialization verbs
4104 static struct hda_verb alc260_init_verbs[] = {
4105 /* Line In pin widget for input */
4106 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4107 /* CD pin widget for input */
4108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4109 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4110 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4111 /* Mic2 (front panel) pin widget for input and vref at 80% */
4112 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4113 /* LINE-2 is used for line-out in rear */
4114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4115 /* select line-out */
4116 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4118 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4120 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4122 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4123 /* mute capture amp left and right */
4124 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4125 /* set connection select to line in (default select for this ADC) */
4126 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4127 /* mute capture amp left and right */
4128 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4129 /* set connection select to line in (default select for this ADC) */
4130 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4131 /* set vol=0 Line-Out mixer amp left and right */
4132 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4133 /* unmute pin widget amp left and right (no gain on this amp) */
4134 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4135 /* set vol=0 HP mixer amp left and right */
4136 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4137 /* unmute pin widget amp left and right (no gain on this amp) */
4138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4139 /* set vol=0 Mono mixer amp left and right */
4140 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4141 /* unmute pin widget amp left and right (no gain on this amp) */
4142 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4143 /* unmute LINE-2 out pin */
4144 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4145 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4148 /* mute analog inputs */
4149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4154 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4155 /* mute Front out path */
4156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4158 /* mute Headphone out path */
4159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4160 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4161 /* mute Mono out path */
4162 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4163 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4167 #if 0 /* should be identical with alc260_init_verbs? */
4168 static struct hda_verb alc260_hp_init_verbs[] = {
4169 /* Headphone and output */
4170 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4172 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4173 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4175 /* Mic2 (front panel) pin widget for input and vref at 80% */
4176 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4177 /* Line In pin widget for input */
4178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4179 /* Line-2 pin widget for output */
4180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4181 /* CD pin widget for input */
4182 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4183 /* unmute amp left and right */
4184 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4185 /* set connection select to line in (default select for this ADC) */
4186 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4187 /* unmute Line-Out mixer amp left and right (volume = 0) */
4188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4189 /* mute pin widget amp left and right (no gain on this amp) */
4190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4191 /* unmute HP mixer amp left and right (volume = 0) */
4192 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4193 /* mute pin widget amp left and right (no gain on this amp) */
4194 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4195 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4198 /* mute analog inputs */
4199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4200 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4201 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4202 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4203 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4204 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4205 /* Unmute Front out path */
4206 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4207 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4208 /* Unmute Headphone out path */
4209 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4210 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4211 /* Unmute Mono out path */
4212 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4213 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4218 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4219 /* Line out and output */
4220 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4222 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4223 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4224 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4225 /* Mic2 (front panel) pin widget for input and vref at 80% */
4226 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4227 /* Line In pin widget for input */
4228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4229 /* Headphone pin widget for output */
4230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4231 /* CD pin widget for input */
4232 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4233 /* unmute amp left and right */
4234 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4235 /* set connection select to line in (default select for this ADC) */
4236 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4237 /* unmute Line-Out mixer amp left and right (volume = 0) */
4238 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4239 /* mute pin widget amp left and right (no gain on this amp) */
4240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4241 /* unmute HP mixer amp left and right (volume = 0) */
4242 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4243 /* mute pin widget amp left and right (no gain on this amp) */
4244 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4245 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4248 /* mute analog inputs */
4249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4254 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4255 /* Unmute Front out path */
4256 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4257 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4258 /* Unmute Headphone out path */
4259 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4260 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4261 /* Unmute Mono out path */
4262 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4263 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4267 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4268 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4269 * audio = 0x16, internal speaker = 0x10.
4271 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4272 /* Disable all GPIOs */
4273 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4274 /* Internal speaker is connected to headphone pin */
4275 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4276 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4277 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4278 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4279 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4280 /* Ensure all other unused pins are disabled and muted. */
4281 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4282 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4283 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4284 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4285 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4286 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4287 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4288 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4290 /* Disable digital (SPDIF) pins */
4291 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4292 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4294 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4295 * when acting as an output.
4297 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4299 /* Start with output sum widgets muted and their output gains at min */
4300 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4301 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4303 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4306 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4307 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4308 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4310 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4311 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4312 /* Unmute Line1 pin widget output buffer since it starts as an output.
4313 * If the pin mode is changed by the user the pin mode control will
4314 * take care of enabling the pin's input/output buffers as needed.
4315 * Therefore there's no need to enable the input buffer at this
4318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4319 /* Unmute input buffer of pin widget used for Line-in (no equiv
4322 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4324 /* Mute capture amp left and right */
4325 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4326 /* Set ADC connection select to match default mixer setting - line
4329 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4331 /* Do the same for the second ADC: mute capture input amp and
4332 * set ADC connection to line in (on mic1 pin)
4334 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4335 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4337 /* Mute all inputs to mixer widget (even unconnected ones) */
4338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4339 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4341 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4342 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4343 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4344 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4350 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4351 * similar laptops (adapted from Fujitsu init verbs).
4353 static struct hda_verb alc260_acer_init_verbs[] = {
4354 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4355 * the headphone jack. Turn this on and rely on the standard mute
4356 * methods whenever the user wants to turn these outputs off.
4358 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4359 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4360 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4361 /* Internal speaker/Headphone jack is connected to Line-out pin */
4362 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4363 /* Internal microphone/Mic jack is connected to Mic1 pin */
4364 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4365 /* Line In jack is connected to Line1 pin */
4366 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4367 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4368 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4369 /* Ensure all other unused pins are disabled and muted. */
4370 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4371 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4372 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4373 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4374 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4375 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4376 /* Disable digital (SPDIF) pins */
4377 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4378 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4380 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4381 * bus when acting as outputs.
4383 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4384 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4386 /* Start with output sum widgets muted and their output gains at min */
4387 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4388 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4389 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4390 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4391 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4392 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4393 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4394 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4395 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4397 /* Unmute Line-out pin widget amp left and right
4398 * (no equiv mixer ctrl)
4400 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4401 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4402 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4403 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4404 * inputs. If the pin mode is changed by the user the pin mode control
4405 * will take care of enabling the pin's input/output buffers as needed.
4406 * Therefore there's no need to enable the input buffer at this
4409 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4410 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4412 /* Mute capture amp left and right */
4413 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4414 /* Set ADC connection select to match default mixer setting - mic
4417 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4419 /* Do similar with the second ADC: mute capture input amp and
4420 * set ADC connection to mic to match ALSA's default state.
4422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4423 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4425 /* Mute all inputs to mixer widget (even unconnected ones) */
4426 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4432 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4433 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4438 static struct hda_verb alc260_will_verbs[] = {
4439 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4440 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4441 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4442 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4443 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4444 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4448 static struct hda_verb alc260_replacer_672v_verbs[] = {
4449 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4450 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4451 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4453 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4454 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4455 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4457 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4461 /* toggle speaker-output according to the hp-jack state */
4462 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4464 unsigned int present;
4466 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4467 present = snd_hda_codec_read(codec, 0x0f, 0,
4468 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4470 snd_hda_codec_write_cache(codec, 0x01, 0,
4471 AC_VERB_SET_GPIO_DATA, 1);
4472 snd_hda_codec_write_cache(codec, 0x0f, 0,
4473 AC_VERB_SET_PIN_WIDGET_CONTROL,
4476 snd_hda_codec_write_cache(codec, 0x01, 0,
4477 AC_VERB_SET_GPIO_DATA, 0);
4478 snd_hda_codec_write_cache(codec, 0x0f, 0,
4479 AC_VERB_SET_PIN_WIDGET_CONTROL,
4484 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4487 if ((res >> 26) == ALC880_HP_EVENT)
4488 alc260_replacer_672v_automute(codec);
4491 /* Test configuration for debugging, modelled after the ALC880 test
4494 #ifdef CONFIG_SND_DEBUG
4495 static hda_nid_t alc260_test_dac_nids[1] = {
4498 static hda_nid_t alc260_test_adc_nids[2] = {
4501 /* For testing the ALC260, each input MUX needs its own definition since
4502 * the signal assignments are different. This assumes that the first ADC
4505 static struct hda_input_mux alc260_test_capture_sources[2] = {
4509 { "MIC1 pin", 0x0 },
4510 { "MIC2 pin", 0x1 },
4511 { "LINE1 pin", 0x2 },
4512 { "LINE2 pin", 0x3 },
4514 { "LINE-OUT pin", 0x5 },
4515 { "HP-OUT pin", 0x6 },
4521 { "MIC1 pin", 0x0 },
4522 { "MIC2 pin", 0x1 },
4523 { "LINE1 pin", 0x2 },
4524 { "LINE2 pin", 0x3 },
4527 { "LINE-OUT pin", 0x6 },
4528 { "HP-OUT pin", 0x7 },
4532 static struct snd_kcontrol_new alc260_test_mixer[] = {
4533 /* Output driver widgets */
4534 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4535 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4536 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4537 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4538 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4539 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4541 /* Modes for retasking pin widgets
4542 * Note: the ALC260 doesn't seem to act on requests to enable mic
4543 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4544 * mention this restriction. At this stage it's not clear whether
4545 * this behaviour is intentional or is a hardware bug in chip
4546 * revisions available at least up until early 2006. Therefore for
4547 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4548 * choices, but if it turns out that the lack of mic bias for these
4549 * NIDs is intentional we could change their modes from
4550 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4552 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4553 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4554 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4555 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4556 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4557 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4559 /* Loopback mixer controls */
4560 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4561 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4562 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4563 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4564 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4565 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4566 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4567 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4568 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4569 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4570 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4571 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4572 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4573 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4574 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4575 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4577 /* Controls for GPIO pins, assuming they are configured as outputs */
4578 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4579 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4580 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4581 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4583 /* Switches to allow the digital IO pins to be enabled. The datasheet
4584 * is ambigious as to which NID is which; testing on laptops which
4585 * make this output available should provide clarification.
4587 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4588 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4590 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4591 * this output to turn on an external amplifier.
4593 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4594 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4598 static struct hda_verb alc260_test_init_verbs[] = {
4599 /* Enable all GPIOs as outputs with an initial value of 0 */
4600 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4601 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4602 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4604 /* Enable retasking pins as output, initially without power amp */
4605 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4606 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4609 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4610 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4612 /* Disable digital (SPDIF) pins initially, but users can enable
4613 * them via a mixer switch. In the case of SPDIF-out, this initverb
4614 * payload also sets the generation to 0, output to be in "consumer"
4615 * PCM format, copyright asserted, no pre-emphasis and no validity
4618 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4619 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4621 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4622 * OUT1 sum bus when acting as an output.
4624 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4625 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4626 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4627 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4629 /* Start with output sum widgets muted and their output gains at min */
4630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4631 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4634 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4635 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4637 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4638 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4640 /* Unmute retasking pin widget output buffers since the default
4641 * state appears to be output. As the pin mode is changed by the
4642 * user the pin mode control will take care of enabling the pin's
4643 * input/output buffers as needed.
4645 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4646 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4648 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4649 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4650 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4651 /* Also unmute the mono-out pin widget */
4652 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4654 /* Mute capture amp left and right */
4655 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656 /* Set ADC connection select to match default mixer setting (mic1
4659 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4661 /* Do the same for the second ADC: mute capture input amp and
4662 * set ADC connection to mic1 pin
4664 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4665 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4667 /* Mute all inputs to mixer widget (even unconnected ones) */
4668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4669 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4670 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4672 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4673 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4675 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4681 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4682 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4684 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4685 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4688 * for BIOS auto-configuration
4691 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4695 unsigned long vol_val, sw_val;
4699 if (nid >= 0x0f && nid < 0x11) {
4700 nid_vol = nid - 0x7;
4701 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4702 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4703 } else if (nid == 0x11) {
4704 nid_vol = nid - 0x7;
4705 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4706 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4707 } else if (nid >= 0x12 && nid <= 0x15) {
4709 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4710 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4714 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4715 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4718 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4719 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4725 /* add playback controls from the parsed DAC table */
4726 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4727 const struct auto_pin_cfg *cfg)
4732 spec->multiout.num_dacs = 1;
4733 spec->multiout.dac_nids = spec->private_dac_nids;
4734 spec->multiout.dac_nids[0] = 0x02;
4736 nid = cfg->line_out_pins[0];
4738 err = alc260_add_playback_controls(spec, nid, "Front");
4743 nid = cfg->speaker_pins[0];
4745 err = alc260_add_playback_controls(spec, nid, "Speaker");
4750 nid = cfg->hp_pins[0];
4752 err = alc260_add_playback_controls(spec, nid, "Headphone");
4759 /* create playback/capture controls for input pins */
4760 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4761 const struct auto_pin_cfg *cfg)
4763 struct hda_input_mux *imux = &spec->private_imux;
4766 for (i = 0; i < AUTO_PIN_LAST; i++) {
4767 if (cfg->input_pins[i] >= 0x12) {
4768 idx = cfg->input_pins[i] - 0x12;
4769 err = new_analog_input(spec, cfg->input_pins[i],
4770 auto_pin_cfg_labels[i], idx,
4774 imux->items[imux->num_items].label =
4775 auto_pin_cfg_labels[i];
4776 imux->items[imux->num_items].index = idx;
4779 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4780 idx = cfg->input_pins[i] - 0x09;
4781 err = new_analog_input(spec, cfg->input_pins[i],
4782 auto_pin_cfg_labels[i], idx,
4786 imux->items[imux->num_items].label =
4787 auto_pin_cfg_labels[i];
4788 imux->items[imux->num_items].index = idx;
4795 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4796 hda_nid_t nid, int pin_type,
4800 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4802 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4804 /* need the manual connection? */
4806 int idx = nid - 0x12;
4807 snd_hda_codec_write(codec, idx + 0x0b, 0,
4808 AC_VERB_SET_CONNECT_SEL, sel_idx);
4812 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4814 struct alc_spec *spec = codec->spec;
4817 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4818 nid = spec->autocfg.line_out_pins[0];
4820 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4821 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4824 nid = spec->autocfg.speaker_pins[0];
4826 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4828 nid = spec->autocfg.hp_pins[0];
4830 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4833 #define ALC260_PIN_CD_NID 0x16
4834 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4836 struct alc_spec *spec = codec->spec;
4839 for (i = 0; i < AUTO_PIN_LAST; i++) {
4840 hda_nid_t nid = spec->autocfg.input_pins[i];
4842 snd_hda_codec_write(codec, nid, 0,
4843 AC_VERB_SET_PIN_WIDGET_CONTROL,
4844 i <= AUTO_PIN_FRONT_MIC ?
4845 PIN_VREF80 : PIN_IN);
4846 if (nid != ALC260_PIN_CD_NID)
4847 snd_hda_codec_write(codec, nid, 0,
4848 AC_VERB_SET_AMP_GAIN_MUTE,
4855 * generic initialization of ADC, input mixers and output mixers
4857 static struct hda_verb alc260_volume_init_verbs[] = {
4859 * Unmute ADC0-1 and set the default input to mic-in
4861 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4862 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4863 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4864 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4866 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4868 * Note: PASD motherboards uses the Line In 2 as the input for
4869 * front panel mic (mic 2)
4871 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4872 /* mute analog inputs */
4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4880 * Set up output mixers (0x08 - 0x0a)
4882 /* set vol=0 to output mixers */
4883 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4885 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4886 /* set up input amps for analog loopback */
4887 /* Amp Indices: DAC = 0, mixer = 1 */
4888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4891 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4892 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4893 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4898 static int alc260_parse_auto_config(struct hda_codec *codec)
4900 struct alc_spec *spec = codec->spec;
4903 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4905 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4909 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4912 if (!spec->kctl_alloc)
4913 return 0; /* can't find valid BIOS pin config */
4914 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4918 spec->multiout.max_channels = 2;
4920 if (spec->autocfg.dig_out_pin)
4921 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4922 if (spec->kctl_alloc)
4923 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4925 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4927 spec->num_mux_defs = 1;
4928 spec->input_mux = &spec->private_imux;
4930 /* check whether NID 0x04 is valid */
4931 wcap = get_wcaps(codec, 0x04);
4932 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4933 if (wcap != AC_WID_AUD_IN) {
4934 spec->adc_nids = alc260_adc_nids_alt;
4935 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4936 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4938 spec->adc_nids = alc260_adc_nids;
4939 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4940 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4947 /* additional initialization for auto-configuration model */
4948 static void alc260_auto_init(struct hda_codec *codec)
4950 alc260_auto_init_multi_out(codec);
4951 alc260_auto_init_analog_input(codec);
4954 #ifdef CONFIG_SND_HDA_POWER_SAVE
4955 static struct hda_amp_list alc260_loopbacks[] = {
4956 { 0x07, HDA_INPUT, 0 },
4957 { 0x07, HDA_INPUT, 1 },
4958 { 0x07, HDA_INPUT, 2 },
4959 { 0x07, HDA_INPUT, 3 },
4960 { 0x07, HDA_INPUT, 4 },
4966 * ALC260 configurations
4968 static const char *alc260_models[ALC260_MODEL_LAST] = {
4969 [ALC260_BASIC] = "basic",
4971 [ALC260_HP_3013] = "hp-3013",
4972 [ALC260_FUJITSU_S702X] = "fujitsu",
4973 [ALC260_ACER] = "acer",
4974 [ALC260_WILL] = "will",
4975 [ALC260_REPLACER_672V] = "replacer",
4976 #ifdef CONFIG_SND_DEBUG
4977 [ALC260_TEST] = "test",
4979 [ALC260_AUTO] = "auto",
4982 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4983 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4984 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4985 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4986 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4987 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4988 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4989 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4990 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4991 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4992 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4993 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4994 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4995 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4996 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4997 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4998 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4999 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5000 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5004 static struct alc_config_preset alc260_presets[] = {
5006 .mixers = { alc260_base_output_mixer,
5008 alc260_pc_beep_mixer,
5009 alc260_capture_mixer },
5010 .init_verbs = { alc260_init_verbs },
5011 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5012 .dac_nids = alc260_dac_nids,
5013 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5014 .adc_nids = alc260_adc_nids,
5015 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5016 .channel_mode = alc260_modes,
5017 .input_mux = &alc260_capture_source,
5020 .mixers = { alc260_hp_output_mixer,
5022 alc260_capture_alt_mixer },
5023 .init_verbs = { alc260_init_verbs,
5024 alc260_hp_unsol_verbs },
5025 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5026 .dac_nids = alc260_dac_nids,
5027 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5028 .adc_nids = alc260_hp_adc_nids,
5029 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5030 .channel_mode = alc260_modes,
5031 .input_mux = &alc260_capture_source,
5032 .unsol_event = alc260_hp_unsol_event,
5033 .init_hook = alc260_hp_automute,
5035 [ALC260_HP_3013] = {
5036 .mixers = { alc260_hp_3013_mixer,
5038 alc260_capture_alt_mixer },
5039 .init_verbs = { alc260_hp_3013_init_verbs,
5040 alc260_hp_3013_unsol_verbs },
5041 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5042 .dac_nids = alc260_dac_nids,
5043 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5044 .adc_nids = alc260_hp_adc_nids,
5045 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5046 .channel_mode = alc260_modes,
5047 .input_mux = &alc260_capture_source,
5048 .unsol_event = alc260_hp_3013_unsol_event,
5049 .init_hook = alc260_hp_3013_automute,
5051 [ALC260_FUJITSU_S702X] = {
5052 .mixers = { alc260_fujitsu_mixer,
5053 alc260_capture_mixer },
5054 .init_verbs = { alc260_fujitsu_init_verbs },
5055 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5056 .dac_nids = alc260_dac_nids,
5057 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5058 .adc_nids = alc260_dual_adc_nids,
5059 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5060 .channel_mode = alc260_modes,
5061 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5062 .input_mux = alc260_fujitsu_capture_sources,
5065 .mixers = { alc260_acer_mixer,
5066 alc260_capture_mixer },
5067 .init_verbs = { alc260_acer_init_verbs },
5068 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5069 .dac_nids = alc260_dac_nids,
5070 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5071 .adc_nids = alc260_dual_adc_nids,
5072 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5073 .channel_mode = alc260_modes,
5074 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5075 .input_mux = alc260_acer_capture_sources,
5078 .mixers = { alc260_will_mixer,
5079 alc260_capture_mixer },
5080 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5081 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5082 .dac_nids = alc260_dac_nids,
5083 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5084 .adc_nids = alc260_adc_nids,
5085 .dig_out_nid = ALC260_DIGOUT_NID,
5086 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5087 .channel_mode = alc260_modes,
5088 .input_mux = &alc260_capture_source,
5090 [ALC260_REPLACER_672V] = {
5091 .mixers = { alc260_replacer_672v_mixer,
5092 alc260_capture_mixer },
5093 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5094 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5095 .dac_nids = alc260_dac_nids,
5096 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5097 .adc_nids = alc260_adc_nids,
5098 .dig_out_nid = ALC260_DIGOUT_NID,
5099 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5100 .channel_mode = alc260_modes,
5101 .input_mux = &alc260_capture_source,
5102 .unsol_event = alc260_replacer_672v_unsol_event,
5103 .init_hook = alc260_replacer_672v_automute,
5105 #ifdef CONFIG_SND_DEBUG
5107 .mixers = { alc260_test_mixer,
5108 alc260_capture_mixer },
5109 .init_verbs = { alc260_test_init_verbs },
5110 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5111 .dac_nids = alc260_test_dac_nids,
5112 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5113 .adc_nids = alc260_test_adc_nids,
5114 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5115 .channel_mode = alc260_modes,
5116 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5117 .input_mux = alc260_test_capture_sources,
5122 static int patch_alc260(struct hda_codec *codec)
5124 struct alc_spec *spec;
5125 int err, board_config;
5127 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5133 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5136 if (board_config < 0) {
5137 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5138 "trying auto-probe from BIOS...\n");
5139 board_config = ALC260_AUTO;
5142 if (board_config == ALC260_AUTO) {
5143 /* automatic parse from the BIOS config */
5144 err = alc260_parse_auto_config(codec);
5150 "hda_codec: Cannot set up configuration "
5151 "from BIOS. Using base mode...\n");
5152 board_config = ALC260_BASIC;
5156 if (board_config != ALC260_AUTO)
5157 setup_preset(spec, &alc260_presets[board_config]);
5159 spec->stream_name_analog = "ALC260 Analog";
5160 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5161 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5163 spec->stream_name_digital = "ALC260 Digital";
5164 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5165 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5167 spec->vmaster_nid = 0x08;
5169 codec->patch_ops = alc_patch_ops;
5170 if (board_config == ALC260_AUTO)
5171 spec->init_hook = alc260_auto_init;
5172 #ifdef CONFIG_SND_HDA_POWER_SAVE
5173 if (!spec->loopback.amplist)
5174 spec->loopback.amplist = alc260_loopbacks;
5184 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5185 * configuration. Each pin widget can choose any input DACs and a mixer.
5186 * Each ADC is connected from a mixer of all inputs. This makes possible
5187 * 6-channel independent captures.
5189 * In addition, an independent DAC for the multi-playback (not used in this
5192 #define ALC882_DIGOUT_NID 0x06
5193 #define ALC882_DIGIN_NID 0x0a
5195 static struct hda_channel_mode alc882_ch_modes[1] = {
5199 static hda_nid_t alc882_dac_nids[4] = {
5200 /* front, rear, clfe, rear_surr */
5201 0x02, 0x03, 0x04, 0x05
5204 /* identical with ALC880 */
5205 #define alc882_adc_nids alc880_adc_nids
5206 #define alc882_adc_nids_alt alc880_adc_nids_alt
5209 /* FIXME: should be a matrix-type input source selection */
5211 static struct hda_input_mux alc882_capture_source = {
5215 { "Front Mic", 0x1 },
5220 #define alc882_mux_enum_info alc_mux_enum_info
5221 #define alc882_mux_enum_get alc_mux_enum_get
5223 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5224 struct snd_ctl_elem_value *ucontrol)
5226 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5227 struct alc_spec *spec = codec->spec;
5228 const struct hda_input_mux *imux = spec->input_mux;
5229 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5230 static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
5232 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5233 unsigned int i, idx;
5235 if (spec->num_adc_nids < 3)
5236 nid = capture_mixers[adc_idx + 1];
5238 nid = capture_mixers[adc_idx];
5239 idx = ucontrol->value.enumerated.item[0];
5240 if (idx >= imux->num_items)
5241 idx = imux->num_items - 1;
5242 if (*cur_val == idx)
5244 for (i = 0; i < imux->num_items; i++) {
5245 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5246 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5247 imux->items[i].index,
5257 static struct hda_verb alc882_3ST_ch2_init[] = {
5258 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5259 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5260 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5261 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5268 static struct hda_verb alc882_3ST_ch6_init[] = {
5269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5271 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5272 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5273 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5274 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5278 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5279 { 2, alc882_3ST_ch2_init },
5280 { 6, alc882_3ST_ch6_init },
5286 static struct hda_verb alc882_sixstack_ch6_init[] = {
5287 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5288 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5289 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5290 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5297 static struct hda_verb alc882_sixstack_ch8_init[] = {
5298 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5299 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5300 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5301 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5305 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5306 { 6, alc882_sixstack_ch6_init },
5307 { 8, alc882_sixstack_ch8_init },
5311 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5317 static struct hda_verb alc885_mbp_ch2_init[] = {
5318 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5319 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5320 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5327 static struct hda_verb alc885_mbp_ch6_init[] = {
5328 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5329 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5330 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5331 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5332 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5336 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5337 { 2, alc885_mbp_ch2_init },
5338 { 6, alc885_mbp_ch6_init },
5342 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5343 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5345 static struct snd_kcontrol_new alc882_base_mixer[] = {
5346 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5347 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5348 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5349 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5350 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5351 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5352 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5353 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5354 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5355 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5357 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5358 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5359 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5360 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5361 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5362 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5364 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5365 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5366 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5367 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5368 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5372 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5373 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5374 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5375 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5376 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5377 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5378 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5380 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5381 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5385 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5386 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5387 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5390 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5391 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5393 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5395 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5396 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5400 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5401 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5402 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5404 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5405 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5406 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5407 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5408 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5409 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5410 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5411 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5412 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5413 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5417 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5418 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5420 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5421 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5422 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5423 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5424 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5428 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5429 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5430 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5433 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5437 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5441 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5442 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5446 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5448 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5449 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5453 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5456 .name = "Channel Mode",
5457 .info = alc_ch_mode_info,
5458 .get = alc_ch_mode_get,
5459 .put = alc_ch_mode_put,
5464 static struct hda_verb alc882_init_verbs[] = {
5465 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5470 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5478 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5480 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5482 /* Front Pin: output 0 (0x0c) */
5483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5486 /* Rear Pin: output 1 (0x0d) */
5487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5489 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5490 /* CLFE Pin: output 2 (0x0e) */
5491 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5493 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5494 /* Side Pin: output 3 (0x0f) */
5495 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5496 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5497 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5498 /* Mic (rear) pin: input vref at 80% */
5499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5501 /* Front Mic pin: input vref at 80% */
5502 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5503 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5504 /* Line In pin: input */
5505 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5506 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5507 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5510 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5511 /* CD pin widget for input */
5512 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5514 /* FIXME: use matrix-type input source selection */
5515 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5516 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5524 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5529 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5531 /* ADC1: mute amp left and right */
5532 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5533 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5534 /* ADC2: mute amp left and right */
5535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5536 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5537 /* ADC3: mute amp left and right */
5538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5539 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5544 static struct hda_verb alc882_eapd_verbs[] = {
5545 /* change to EAPD mode */
5546 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5547 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5552 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5553 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5556 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5557 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5558 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5559 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5563 static struct hda_verb alc882_macpro_init_verbs[] = {
5564 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5568 /* Front Pin: output 0 (0x0c) */
5569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5571 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5572 /* Front Mic pin: input vref at 80% */
5573 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5574 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5575 /* Speaker: output */
5576 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5577 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5578 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5579 /* Headphone output (output 0 - 0x0c) */
5580 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5581 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5582 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5584 /* FIXME: use matrix-type input source selection */
5585 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5586 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5587 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5588 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5589 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5601 /* ADC1: mute amp left and right */
5602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5603 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5604 /* ADC2: mute amp left and right */
5605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5606 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5607 /* ADC3: mute amp left and right */
5608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5609 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5614 /* Macbook Pro rev3 */
5615 static struct hda_verb alc885_mbp3_init_verbs[] = {
5616 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5623 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5624 /* Front Pin: output 0 (0x0c) */
5625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5627 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5628 /* HP Pin: output 0 (0x0d) */
5629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5630 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5631 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5633 /* Mic (rear) pin: input vref at 80% */
5634 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5635 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5636 /* Front Mic pin: input vref at 80% */
5637 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5638 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5639 /* Line In pin: use output 1 when in LineOut mode */
5640 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5642 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5644 /* FIXME: use matrix-type input source selection */
5645 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5646 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5650 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5652 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5655 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5657 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5659 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5661 /* ADC1: mute amp left and right */
5662 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5663 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5664 /* ADC2: mute amp left and right */
5665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5667 /* ADC3: mute amp left and right */
5668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5669 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5674 /* iMac 24 mixer. */
5675 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5676 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5677 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5681 /* iMac 24 init verbs. */
5682 static struct hda_verb alc885_imac24_init_verbs[] = {
5683 /* Internal speakers: output 0 (0x0c) */
5684 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5685 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5686 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5687 /* Internal speakers: output 0 (0x0c) */
5688 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5690 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5691 /* Headphone: output 0 (0x0c) */
5692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5693 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5694 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5695 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5696 /* Front Mic: input vref at 80% */
5697 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5698 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5702 /* Toggle speaker-output according to the hp-jack state */
5703 static void alc885_imac24_automute(struct hda_codec *codec)
5705 unsigned int present;
5707 present = snd_hda_codec_read(codec, 0x14, 0,
5708 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5709 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5710 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5711 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5712 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5715 /* Processes unsolicited events. */
5716 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5719 /* Headphone insertion or removal. */
5720 if ((res >> 26) == ALC880_HP_EVENT)
5721 alc885_imac24_automute(codec);
5724 static void alc885_mbp3_automute(struct hda_codec *codec)
5726 unsigned int present;
5728 present = snd_hda_codec_read(codec, 0x15, 0,
5729 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5730 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5731 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5732 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5733 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5736 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5739 /* Headphone insertion or removal. */
5740 if ((res >> 26) == ALC880_HP_EVENT)
5741 alc885_mbp3_automute(codec);
5745 static struct hda_verb alc882_targa_verbs[] = {
5746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5750 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5752 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5753 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5754 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5756 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5757 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5759 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5763 /* toggle speaker-output according to the hp-jack state */
5764 static void alc882_targa_automute(struct hda_codec *codec)
5766 unsigned int present;
5768 present = snd_hda_codec_read(codec, 0x14, 0,
5769 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5770 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5771 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5772 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5776 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5778 /* Looks like the unsol event is incompatible with the standard
5779 * definition. 4bit tag is placed at 26 bit!
5781 if (((res >> 26) == ALC880_HP_EVENT)) {
5782 alc882_targa_automute(codec);
5786 static struct hda_verb alc882_asus_a7j_verbs[] = {
5787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5791 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5792 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5794 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5796 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5798 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5799 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5800 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5804 static struct hda_verb alc882_asus_a7m_verbs[] = {
5805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5809 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5810 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5812 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5813 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5814 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5816 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5817 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5822 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5824 unsigned int gpiostate, gpiomask, gpiodir;
5826 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5827 AC_VERB_GET_GPIO_DATA, 0);
5830 gpiostate |= (1 << pin);
5832 gpiostate &= ~(1 << pin);
5834 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5835 AC_VERB_GET_GPIO_MASK, 0);
5836 gpiomask |= (1 << pin);
5838 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5839 AC_VERB_GET_GPIO_DIRECTION, 0);
5840 gpiodir |= (1 << pin);
5843 snd_hda_codec_write(codec, codec->afg, 0,
5844 AC_VERB_SET_GPIO_MASK, gpiomask);
5845 snd_hda_codec_write(codec, codec->afg, 0,
5846 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5850 snd_hda_codec_write(codec, codec->afg, 0,
5851 AC_VERB_SET_GPIO_DATA, gpiostate);
5854 /* set up GPIO at initialization */
5855 static void alc885_macpro_init_hook(struct hda_codec *codec)
5857 alc882_gpio_mute(codec, 0, 0);
5858 alc882_gpio_mute(codec, 1, 0);
5861 /* set up GPIO and update auto-muting at initialization */
5862 static void alc885_imac24_init_hook(struct hda_codec *codec)
5864 alc885_macpro_init_hook(codec);
5865 alc885_imac24_automute(codec);
5869 * generic initialization of ADC, input mixers and output mixers
5871 static struct hda_verb alc882_auto_init_verbs[] = {
5873 * Unmute ADC0-2 and set the default input to mic-in
5875 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5877 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5878 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5879 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5880 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5882 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5884 * Note: PASD motherboards uses the Line In 2 as the input for
5885 * front panel mic (mic 2)
5887 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5888 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5889 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5890 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5895 * Set up output mixers (0x0c - 0x0f)
5897 /* set vol=0 to output mixers */
5898 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5900 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5902 /* set up input amps for analog loopback */
5903 /* Amp Indices: DAC = 0, mixer = 1 */
5904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5908 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5909 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5910 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5912 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5913 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5915 /* FIXME: use matrix-type input source selection */
5916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5936 /* capture mixer elements */
5937 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5938 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5939 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5940 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5941 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5944 /* The multiple "Capture Source" controls confuse alsamixer
5945 * So call somewhat different..
5947 /* .name = "Capture Source", */
5948 .name = "Input Source",
5950 .info = alc882_mux_enum_info,
5951 .get = alc882_mux_enum_get,
5952 .put = alc882_mux_enum_put,
5957 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5958 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5959 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5960 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5961 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5962 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5963 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5965 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5966 /* The multiple "Capture Source" controls confuse alsamixer
5967 * So call somewhat different..
5969 /* .name = "Capture Source", */
5970 .name = "Input Source",
5972 .info = alc882_mux_enum_info,
5973 .get = alc882_mux_enum_get,
5974 .put = alc882_mux_enum_put,
5979 #ifdef CONFIG_SND_HDA_POWER_SAVE
5980 #define alc882_loopbacks alc880_loopbacks
5983 /* pcm configuration: identiacal with ALC880 */
5984 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
5985 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
5986 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
5987 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
5990 * configuration and preset
5992 static const char *alc882_models[ALC882_MODEL_LAST] = {
5993 [ALC882_3ST_DIG] = "3stack-dig",
5994 [ALC882_6ST_DIG] = "6stack-dig",
5995 [ALC882_ARIMA] = "arima",
5996 [ALC882_W2JC] = "w2jc",
5997 [ALC882_TARGA] = "targa",
5998 [ALC882_ASUS_A7J] = "asus-a7j",
5999 [ALC882_ASUS_A7M] = "asus-a7m",
6000 [ALC885_MACPRO] = "macpro",
6001 [ALC885_MBP3] = "mbp3",
6002 [ALC885_IMAC24] = "imac24",
6003 [ALC882_AUTO] = "auto",
6006 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6007 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6008 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6009 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6010 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6011 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6012 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6013 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6014 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6015 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6016 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6017 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6018 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6022 static struct alc_config_preset alc882_presets[] = {
6023 [ALC882_3ST_DIG] = {
6024 .mixers = { alc882_base_mixer },
6025 .init_verbs = { alc882_init_verbs },
6026 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6027 .dac_nids = alc882_dac_nids,
6028 .dig_out_nid = ALC882_DIGOUT_NID,
6029 .dig_in_nid = ALC882_DIGIN_NID,
6030 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6031 .channel_mode = alc882_ch_modes,
6033 .input_mux = &alc882_capture_source,
6035 [ALC882_6ST_DIG] = {
6036 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6037 .init_verbs = { alc882_init_verbs },
6038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6039 .dac_nids = alc882_dac_nids,
6040 .dig_out_nid = ALC882_DIGOUT_NID,
6041 .dig_in_nid = ALC882_DIGIN_NID,
6042 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6043 .channel_mode = alc882_sixstack_modes,
6044 .input_mux = &alc882_capture_source,
6047 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6048 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6049 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6050 .dac_nids = alc882_dac_nids,
6051 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6052 .channel_mode = alc882_sixstack_modes,
6053 .input_mux = &alc882_capture_source,
6056 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6057 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6058 alc880_gpio1_init_verbs },
6059 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6060 .dac_nids = alc882_dac_nids,
6061 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6062 .channel_mode = alc880_threestack_modes,
6064 .input_mux = &alc882_capture_source,
6065 .dig_out_nid = ALC882_DIGOUT_NID,
6068 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6069 .init_verbs = { alc885_mbp3_init_verbs,
6070 alc880_gpio1_init_verbs },
6071 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6072 .dac_nids = alc882_dac_nids,
6073 .channel_mode = alc885_mbp_6ch_modes,
6074 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6075 .input_mux = &alc882_capture_source,
6076 .dig_out_nid = ALC882_DIGOUT_NID,
6077 .dig_in_nid = ALC882_DIGIN_NID,
6078 .unsol_event = alc885_mbp3_unsol_event,
6079 .init_hook = alc885_mbp3_automute,
6082 .mixers = { alc882_macpro_mixer },
6083 .init_verbs = { alc882_macpro_init_verbs },
6084 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6085 .dac_nids = alc882_dac_nids,
6086 .dig_out_nid = ALC882_DIGOUT_NID,
6087 .dig_in_nid = ALC882_DIGIN_NID,
6088 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6089 .channel_mode = alc882_ch_modes,
6090 .input_mux = &alc882_capture_source,
6091 .init_hook = alc885_macpro_init_hook,
6094 .mixers = { alc885_imac24_mixer },
6095 .init_verbs = { alc885_imac24_init_verbs },
6096 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6097 .dac_nids = alc882_dac_nids,
6098 .dig_out_nid = ALC882_DIGOUT_NID,
6099 .dig_in_nid = ALC882_DIGIN_NID,
6100 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6101 .channel_mode = alc882_ch_modes,
6102 .input_mux = &alc882_capture_source,
6103 .unsol_event = alc885_imac24_unsol_event,
6104 .init_hook = alc885_imac24_init_hook,
6107 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6108 alc882_capture_mixer },
6109 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6110 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6111 .dac_nids = alc882_dac_nids,
6112 .dig_out_nid = ALC882_DIGOUT_NID,
6113 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6114 .adc_nids = alc882_adc_nids,
6115 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6116 .channel_mode = alc882_3ST_6ch_modes,
6118 .input_mux = &alc882_capture_source,
6119 .unsol_event = alc882_targa_unsol_event,
6120 .init_hook = alc882_targa_automute,
6122 [ALC882_ASUS_A7J] = {
6123 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6124 alc882_capture_mixer },
6125 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6126 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6127 .dac_nids = alc882_dac_nids,
6128 .dig_out_nid = ALC882_DIGOUT_NID,
6129 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6130 .adc_nids = alc882_adc_nids,
6131 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6132 .channel_mode = alc882_3ST_6ch_modes,
6134 .input_mux = &alc882_capture_source,
6136 [ALC882_ASUS_A7M] = {
6137 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6138 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6139 alc880_gpio1_init_verbs,
6140 alc882_asus_a7m_verbs },
6141 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6142 .dac_nids = alc882_dac_nids,
6143 .dig_out_nid = ALC882_DIGOUT_NID,
6144 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6145 .channel_mode = alc880_threestack_modes,
6147 .input_mux = &alc882_capture_source,
6156 PINFIX_ABIT_AW9D_MAX
6159 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6160 { 0x15, 0x01080104 }, /* side */
6161 { 0x16, 0x01011012 }, /* rear */
6162 { 0x17, 0x01016011 }, /* clfe */
6166 static const struct alc_pincfg *alc882_pin_fixes[] = {
6167 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6170 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6171 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6176 * BIOS auto configuration
6178 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6179 hda_nid_t nid, int pin_type,
6183 struct alc_spec *spec = codec->spec;
6186 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6189 idx = spec->multiout.dac_nids[dac_idx] - 2;
6191 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6193 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
6195 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6199 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6201 struct alc_spec *spec = codec->spec;
6204 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6205 for (i = 0; i <= HDA_SIDE; i++) {
6206 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6207 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6209 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6214 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6216 struct alc_spec *spec = codec->spec;
6219 pin = spec->autocfg.hp_pins[0];
6220 if (pin) /* connect to front */
6222 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6225 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6226 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6228 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6230 struct alc_spec *spec = codec->spec;
6233 for (i = 0; i < AUTO_PIN_LAST; i++) {
6234 hda_nid_t nid = spec->autocfg.input_pins[i];
6235 if (alc882_is_input_pin(nid)) {
6236 snd_hda_codec_write(codec, nid, 0,
6237 AC_VERB_SET_PIN_WIDGET_CONTROL,
6238 i <= AUTO_PIN_FRONT_MIC ?
6239 PIN_VREF80 : PIN_IN);
6240 if (nid != ALC882_PIN_CD_NID)
6241 snd_hda_codec_write(codec, nid, 0,
6242 AC_VERB_SET_AMP_GAIN_MUTE,
6248 /* add mic boosts if needed */
6249 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6251 struct alc_spec *spec = codec->spec;
6255 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6256 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6257 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6259 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6263 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6264 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6265 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6267 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6274 /* almost identical with ALC880 parser... */
6275 static int alc882_parse_auto_config(struct hda_codec *codec)
6277 struct alc_spec *spec = codec->spec;
6278 int err = alc880_parse_auto_config(codec);
6283 return 0; /* no config found */
6285 err = alc_auto_add_mic_boost(codec);
6289 /* hack - override the init verbs */
6290 spec->init_verbs[0] = alc882_auto_init_verbs;
6292 return 1; /* config found */
6295 /* additional initialization for auto-configuration model */
6296 static void alc882_auto_init(struct hda_codec *codec)
6298 alc882_auto_init_multi_out(codec);
6299 alc882_auto_init_hp_out(codec);
6300 alc882_auto_init_analog_input(codec);
6303 static int patch_alc882(struct hda_codec *codec)
6305 struct alc_spec *spec;
6306 int err, board_config;
6308 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6314 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6318 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6319 /* Pick up systems that don't supply PCI SSID */
6320 switch (codec->subsystem_id) {
6321 case 0x106b0c00: /* Mac Pro */
6322 board_config = ALC885_MACPRO;
6324 case 0x106b1000: /* iMac 24 */
6325 board_config = ALC885_IMAC24;
6327 case 0x106b00a1: /* Macbook */
6328 case 0x106b2c00: /* Macbook Pro rev3 */
6329 board_config = ALC885_MBP3;
6332 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6333 "trying auto-probe from BIOS...\n");
6334 board_config = ALC882_AUTO;
6338 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6340 if (board_config == ALC882_AUTO) {
6341 /* automatic parse from the BIOS config */
6342 err = alc882_parse_auto_config(codec);
6348 "hda_codec: Cannot set up configuration "
6349 "from BIOS. Using base mode...\n");
6350 board_config = ALC882_3ST_DIG;
6354 if (board_config != ALC882_AUTO)
6355 setup_preset(spec, &alc882_presets[board_config]);
6357 spec->stream_name_analog = "ALC882 Analog";
6358 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6359 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6360 /* FIXME: setup DAC5 */
6361 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6362 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6364 spec->stream_name_digital = "ALC882 Digital";
6365 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6366 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6368 if (!spec->adc_nids && spec->input_mux) {
6369 /* check whether NID 0x07 is valid */
6370 unsigned int wcap = get_wcaps(codec, 0x07);
6372 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6373 if (wcap != AC_WID_AUD_IN) {
6374 spec->adc_nids = alc882_adc_nids_alt;
6375 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6376 spec->mixers[spec->num_mixers] =
6377 alc882_capture_alt_mixer;
6380 spec->adc_nids = alc882_adc_nids;
6381 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6382 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6387 spec->vmaster_nid = 0x0c;
6389 codec->patch_ops = alc_patch_ops;
6390 if (board_config == ALC882_AUTO)
6391 spec->init_hook = alc882_auto_init;
6392 #ifdef CONFIG_SND_HDA_POWER_SAVE
6393 if (!spec->loopback.amplist)
6394 spec->loopback.amplist = alc882_loopbacks;
6403 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6404 * configuration. Each pin widget can choose any input DACs and a mixer.
6405 * Each ADC is connected from a mixer of all inputs. This makes possible
6406 * 6-channel independent captures.
6408 * In addition, an independent DAC for the multi-playback (not used in this
6411 #define ALC883_DIGOUT_NID 0x06
6412 #define ALC883_DIGIN_NID 0x0a
6414 static hda_nid_t alc883_dac_nids[4] = {
6415 /* front, rear, clfe, rear_surr */
6416 0x02, 0x04, 0x03, 0x05
6419 static hda_nid_t alc883_adc_nids[2] = {
6425 /* FIXME: should be a matrix-type input source selection */
6427 static struct hda_input_mux alc883_capture_source = {
6431 { "Front Mic", 0x1 },
6437 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6445 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6455 #define alc883_mux_enum_info alc_mux_enum_info
6456 #define alc883_mux_enum_get alc_mux_enum_get
6458 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6459 struct snd_ctl_elem_value *ucontrol)
6461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6462 struct alc_spec *spec = codec->spec;
6463 const struct hda_input_mux *imux = spec->input_mux;
6464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6465 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
6466 hda_nid_t nid = capture_mixers[adc_idx];
6467 unsigned int *cur_val = &spec->cur_mux[adc_idx];
6468 unsigned int i, idx;
6470 idx = ucontrol->value.enumerated.item[0];
6471 if (idx >= imux->num_items)
6472 idx = imux->num_items - 1;
6473 if (*cur_val == idx)
6475 for (i = 0; i < imux->num_items; i++) {
6476 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6477 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6478 imux->items[i].index,
6488 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6495 static struct hda_verb alc883_3ST_ch2_init[] = {
6496 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6497 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6498 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6499 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6506 static struct hda_verb alc883_3ST_ch4_init[] = {
6507 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6508 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6509 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6510 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6511 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6518 static struct hda_verb alc883_3ST_ch6_init[] = {
6519 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6520 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6521 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6522 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6523 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6524 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6528 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6529 { 2, alc883_3ST_ch2_init },
6530 { 4, alc883_3ST_ch4_init },
6531 { 6, alc883_3ST_ch6_init },
6537 static struct hda_verb alc883_sixstack_ch6_init[] = {
6538 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6540 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6541 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6548 static struct hda_verb alc883_sixstack_ch8_init[] = {
6549 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6550 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6551 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6552 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6556 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6557 { 6, alc883_sixstack_ch6_init },
6558 { 8, alc883_sixstack_ch8_init },
6561 static struct hda_verb alc883_medion_eapd_verbs[] = {
6562 /* eanable EAPD on medion laptop */
6563 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6564 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6568 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6569 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6572 static struct snd_kcontrol_new alc883_base_mixer[] = {
6573 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6574 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6575 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6576 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6577 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6578 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6579 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6580 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6581 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6582 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6584 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6585 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6591 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6592 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6593 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6594 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6595 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6596 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6597 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6598 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6599 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6601 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6602 /* .name = "Capture Source", */
6603 .name = "Input Source",
6605 .info = alc883_mux_enum_info,
6606 .get = alc883_mux_enum_get,
6607 .put = alc883_mux_enum_put,
6612 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6613 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6614 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6615 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6616 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6617 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6618 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6620 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6621 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6622 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6624 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6625 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6626 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6627 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6628 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6629 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6631 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6632 /* .name = "Capture Source", */
6633 .name = "Input Source",
6635 .info = alc883_mux_enum_info,
6636 .get = alc883_mux_enum_get,
6637 .put = alc883_mux_enum_put,
6642 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6643 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6644 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6645 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6646 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6647 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6648 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6649 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6650 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6651 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6652 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6653 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6654 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6655 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6656 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6657 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6658 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6659 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6660 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6661 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6664 /* .name = "Capture Source", */
6665 .name = "Input Source",
6667 .info = alc883_mux_enum_info,
6668 .get = alc883_mux_enum_get,
6669 .put = alc883_mux_enum_put,
6674 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6675 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6676 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6677 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6678 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6679 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6680 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6681 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6682 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6684 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6685 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6686 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6687 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6688 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6689 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6691 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6692 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6694 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6695 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6696 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6697 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6698 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6699 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6702 /* .name = "Capture Source", */
6703 .name = "Input Source",
6705 .info = alc883_mux_enum_info,
6706 .get = alc883_mux_enum_get,
6707 .put = alc883_mux_enum_put,
6712 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6713 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6714 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6715 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6716 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6717 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6718 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6719 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6720 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6729 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6730 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6731 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6732 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6733 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6734 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6735 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6739 /* .name = "Capture Source", */
6740 .name = "Input Source",
6742 .info = alc883_mux_enum_info,
6743 .get = alc883_mux_enum_get,
6744 .put = alc883_mux_enum_put,
6749 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6750 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6751 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6752 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6753 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6754 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6755 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6756 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6757 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6758 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6759 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6760 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6761 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6762 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6764 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6766 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6767 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6768 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6769 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6771 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6772 /* .name = "Capture Source", */
6773 .name = "Input Source",
6775 .info = alc883_mux_enum_info,
6776 .get = alc883_mux_enum_get,
6777 .put = alc883_mux_enum_put,
6782 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6783 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6784 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6785 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6786 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6787 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6788 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6789 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6791 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6792 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6793 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6794 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6797 /* .name = "Capture Source", */
6798 .name = "Input Source",
6800 .info = alc883_mux_enum_info,
6801 .get = alc883_mux_enum_get,
6802 .put = alc883_mux_enum_put,
6807 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6808 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6809 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6810 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6811 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6812 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6814 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6816 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6817 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6820 /* .name = "Capture Source", */
6821 .name = "Input Source",
6823 .info = alc883_mux_enum_info,
6824 .get = alc883_mux_enum_get,
6825 .put = alc883_mux_enum_put,
6830 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6831 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6832 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6834 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6835 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6838 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6839 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6840 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6841 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6842 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6843 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6845 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6846 /* .name = "Capture Source", */
6847 .name = "Input Source",
6849 .info = alc883_mux_enum_info,
6850 .get = alc883_mux_enum_get,
6851 .put = alc883_mux_enum_put,
6856 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6857 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6859 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6860 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6861 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6866 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6867 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6868 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6869 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6872 /* .name = "Capture Source", */
6873 .name = "Input Source",
6875 .info = alc883_mux_enum_info,
6876 .get = alc883_mux_enum_get,
6877 .put = alc883_mux_enum_put,
6882 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6883 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6884 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6885 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6886 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6887 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6888 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6889 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6890 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6891 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6892 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6895 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6896 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6897 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6899 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6900 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6901 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6903 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6904 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6905 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6906 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6907 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6908 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6909 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6911 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6912 /* .name = "Capture Source", */
6913 .name = "Input Source",
6915 .info = alc883_mux_enum_info,
6916 .get = alc883_mux_enum_get,
6917 .put = alc883_mux_enum_put,
6922 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6924 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6925 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6926 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6927 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6928 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6929 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6930 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6937 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6939 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6940 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6941 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6942 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6943 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6944 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6945 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6946 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6947 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6949 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6950 /* .name = "Capture Source", */
6951 .name = "Input Source",
6953 .info = alc883_mux_enum_info,
6954 .get = alc883_mux_enum_get,
6955 .put = alc883_mux_enum_put,
6960 static struct snd_kcontrol_new alc888_6st_dell_mixer[] = {
6961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6963 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6964 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6965 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6977 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6980 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6982 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6983 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6984 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6985 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6986 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6987 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6989 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6990 /* .name = "Capture Source", */
6991 .name = "Input Source",
6993 .info = alc883_mux_enum_info,
6994 .get = alc883_mux_enum_get,
6995 .put = alc883_mux_enum_put,
7000 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7001 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7002 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7003 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7004 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7005 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7007 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7009 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7010 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7011 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7012 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7015 /* .name = "Capture Source", */
7016 .name = "Input Source",
7018 .info = alc883_mux_enum_info,
7019 .get = alc883_mux_enum_get,
7020 .put = alc883_mux_enum_put,
7025 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7028 .name = "Channel Mode",
7029 .info = alc_ch_mode_info,
7030 .get = alc_ch_mode_get,
7031 .put = alc_ch_mode_put,
7036 static struct hda_verb alc883_init_verbs[] = {
7037 /* ADC1: mute amp left and right */
7038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7039 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7040 /* ADC2: mute amp left and right */
7041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7042 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7043 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7050 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7052 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7053 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7054 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7057 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7060 /* mute analog input loopbacks */
7061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7067 /* Front Pin: output 0 (0x0c) */
7068 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7069 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7070 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7071 /* Rear Pin: output 1 (0x0d) */
7072 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7073 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7074 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7075 /* CLFE Pin: output 2 (0x0e) */
7076 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7077 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7078 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7079 /* Side Pin: output 3 (0x0f) */
7080 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7081 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7082 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7083 /* Mic (rear) pin: input vref at 80% */
7084 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7085 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7086 /* Front Mic pin: input vref at 80% */
7087 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7088 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7089 /* Line In pin: input */
7090 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7091 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7092 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7094 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7095 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7096 /* CD pin widget for input */
7097 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7099 /* FIXME: use matrix-type input source selection */
7100 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7102 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7103 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7104 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7105 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7108 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7114 /* toggle speaker-output according to the hp-jack state */
7115 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7117 unsigned int present;
7119 present = snd_hda_codec_read(codec, 0x15, 0,
7120 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7121 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7122 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7123 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7124 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7127 /* auto-toggle front mic */
7129 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7131 unsigned int present;
7134 present = snd_hda_codec_read(codec, 0x18, 0,
7135 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7136 bits = present ? HDA_AMP_MUTE : 0;
7137 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7141 static void alc883_mitac_automute(struct hda_codec *codec)
7143 alc883_mitac_hp_automute(codec);
7144 /* alc883_mitac_mic_automute(codec); */
7147 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7150 switch (res >> 26) {
7151 case ALC880_HP_EVENT:
7152 alc883_mitac_hp_automute(codec);
7154 case ALC880_MIC_EVENT:
7155 /* alc883_mitac_mic_automute(codec); */
7160 static struct hda_verb alc883_mitac_verbs[] = {
7162 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7165 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7166 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7168 /* enable unsolicited event */
7169 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7170 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7175 static struct hda_verb alc883_tagra_verbs[] = {
7176 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7177 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7182 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7183 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7184 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7187 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7188 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7189 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7194 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7196 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7197 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7201 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7204 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7209 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7210 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7212 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7213 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7218 static struct hda_verb alc883_haier_w66_verbs[] = {
7219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7224 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7226 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7231 static struct hda_verb alc888_6st_hp_verbs[] = {
7232 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7233 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 2 (0x0e) */
7234 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 1 (0x0d) */
7235 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7239 static struct hda_verb alc888_3st_hp_verbs[] = {
7240 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7241 {0x18, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7242 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7246 static struct hda_verb alc888_6st_dell_verbs[] = {
7247 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Rear : output 1 (0x0e) */
7249 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* CLFE : output 2 (0x0d) */
7250 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, /* Side : output 3 (0x0f) */
7251 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7255 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7256 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7257 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7258 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7259 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7263 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7264 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7265 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7266 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7267 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7271 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7272 { 2, alc888_3st_hp_2ch_init },
7273 { 6, alc888_3st_hp_6ch_init },
7276 /* toggle front-jack and RCA according to the hp-jack state */
7277 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7279 unsigned int present;
7281 present = snd_hda_codec_read(codec, 0x1b, 0,
7282 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7283 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7284 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7285 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7286 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7289 /* toggle RCA according to the front-jack state */
7290 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7292 unsigned int present;
7294 present = snd_hda_codec_read(codec, 0x14, 0,
7295 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7296 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7297 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7300 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7303 if ((res >> 26) == ALC880_HP_EVENT)
7304 alc888_lenovo_ms7195_front_automute(codec);
7305 if ((res >> 26) == ALC880_FRONT_EVENT)
7306 alc888_lenovo_ms7195_rca_automute(codec);
7309 static struct hda_verb alc883_medion_md2_verbs[] = {
7310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7315 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7319 /* toggle speaker-output according to the hp-jack state */
7320 static void alc883_medion_md2_automute(struct hda_codec *codec)
7322 unsigned int present;
7324 present = snd_hda_codec_read(codec, 0x14, 0,
7325 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7326 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7327 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7330 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7333 if ((res >> 26) == ALC880_HP_EVENT)
7334 alc883_medion_md2_automute(codec);
7337 /* toggle speaker-output according to the hp-jack state */
7338 static void alc883_tagra_automute(struct hda_codec *codec)
7340 unsigned int present;
7343 present = snd_hda_codec_read(codec, 0x14, 0,
7344 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7345 bits = present ? HDA_AMP_MUTE : 0;
7346 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7347 HDA_AMP_MUTE, bits);
7348 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7352 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7354 if ((res >> 26) == ALC880_HP_EVENT)
7355 alc883_tagra_automute(codec);
7358 static void alc883_haier_w66_automute(struct hda_codec *codec)
7360 unsigned int present;
7363 present = snd_hda_codec_read(codec, 0x1b, 0,
7364 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7365 bits = present ? 0x80 : 0;
7366 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7370 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7373 if ((res >> 26) == ALC880_HP_EVENT)
7374 alc883_haier_w66_automute(codec);
7377 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7379 unsigned int present;
7382 present = snd_hda_codec_read(codec, 0x14, 0,
7383 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7384 bits = present ? HDA_AMP_MUTE : 0;
7385 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7386 HDA_AMP_MUTE, bits);
7389 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7391 unsigned int present;
7394 present = snd_hda_codec_read(codec, 0x1b, 0,
7395 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7396 bits = present ? HDA_AMP_MUTE : 0;
7397 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7398 HDA_AMP_MUTE, bits);
7399 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7400 HDA_AMP_MUTE, bits);
7403 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7406 if ((res >> 26) == ALC880_HP_EVENT)
7407 alc883_lenovo_101e_all_automute(codec);
7408 if ((res >> 26) == ALC880_FRONT_EVENT)
7409 alc883_lenovo_101e_ispeaker_automute(codec);
7412 /* toggle speaker-output according to the hp-jack state */
7413 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7415 unsigned int present;
7417 present = snd_hda_codec_read(codec, 0x14, 0,
7418 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7419 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7421 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7422 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7425 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7428 if ((res >> 26) == ALC880_HP_EVENT)
7429 alc883_acer_aspire_automute(codec);
7432 static struct hda_verb alc883_acer_eapd_verbs[] = {
7433 /* HP Pin: output 0 (0x0c) */
7434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7437 /* Front Pin: output 0 (0x0c) */
7438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7439 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7440 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7441 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7442 /* eanable EAPD on medion laptop */
7443 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7444 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7445 /* enable unsolicited event */
7446 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7450 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7452 unsigned int present;
7454 present = snd_hda_codec_read(codec, 0x1b, 0,
7455 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7456 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7457 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7458 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7459 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7460 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7462 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7463 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7466 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7469 switch (res >> 26) {
7470 case ALC880_HP_EVENT:
7471 printk("hp_event\n");
7472 alc888_6st_dell_front_automute(codec);
7478 * generic initialization of ADC, input mixers and output mixers
7480 static struct hda_verb alc883_auto_init_verbs[] = {
7482 * Unmute ADC0-2 and set the default input to mic-in
7484 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7486 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7489 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7491 * Note: PASD motherboards uses the Line In 2 as the input for
7492 * front panel mic (mic 2)
7494 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7502 * Set up output mixers (0x0c - 0x0f)
7504 /* set vol=0 to output mixers */
7505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7506 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7508 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7509 /* set up input amps for analog loopback */
7510 /* Amp Indices: DAC = 0, mixer = 1 */
7511 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7517 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7519 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7520 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7522 /* FIXME: use matrix-type input source selection */
7523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7525 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7528 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7529 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7533 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7534 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7535 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7540 /* capture mixer elements */
7541 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7542 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7543 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7544 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7545 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7547 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7548 /* The multiple "Capture Source" controls confuse alsamixer
7549 * So call somewhat different..
7551 /* .name = "Capture Source", */
7552 .name = "Input Source",
7554 .info = alc882_mux_enum_info,
7555 .get = alc882_mux_enum_get,
7556 .put = alc882_mux_enum_put,
7561 #ifdef CONFIG_SND_HDA_POWER_SAVE
7562 #define alc883_loopbacks alc880_loopbacks
7565 /* pcm configuration: identiacal with ALC880 */
7566 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7567 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7568 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
7569 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7570 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
7573 * configuration and preset
7575 static const char *alc883_models[ALC883_MODEL_LAST] = {
7576 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7577 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7578 [ALC883_3ST_6ch] = "3stack-6ch",
7579 [ALC883_6ST_DIG] = "6stack-dig",
7580 [ALC883_TARGA_DIG] = "targa-dig",
7581 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
7582 [ALC883_ACER] = "acer",
7583 [ALC883_ACER_ASPIRE] = "acer-aspire",
7584 [ALC883_MEDION] = "medion",
7585 [ALC883_MEDION_MD2] = "medion-md2",
7586 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
7587 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7588 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7589 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7590 [ALC883_HAIER_W66] = "haier-w66",
7591 [ALC888_6ST_HP] = "6stack-hp",
7592 [ALC888_3ST_HP] = "3stack-hp",
7593 [ALC888_6ST_DELL] = "6stack-dell",
7594 [ALC883_MITAC] = "mitac",
7595 [ALC883_AUTO] = "auto",
7598 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7599 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7600 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7601 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7602 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7603 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7604 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7605 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7606 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7607 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7608 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7609 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7610 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7611 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7612 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7613 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7614 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7615 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7616 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7617 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7618 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7619 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7620 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7621 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7622 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7623 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7624 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7625 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7626 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7627 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7628 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7629 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7630 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7631 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7632 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7633 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7634 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7635 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7636 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7637 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7638 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7639 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7640 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7641 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7642 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7643 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7644 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7645 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7649 static struct alc_config_preset alc883_presets[] = {
7650 [ALC883_3ST_2ch_DIG] = {
7651 .mixers = { alc883_3ST_2ch_mixer },
7652 .init_verbs = { alc883_init_verbs },
7653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7654 .dac_nids = alc883_dac_nids,
7655 .dig_out_nid = ALC883_DIGOUT_NID,
7656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7657 .adc_nids = alc883_adc_nids,
7658 .dig_in_nid = ALC883_DIGIN_NID,
7659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7660 .channel_mode = alc883_3ST_2ch_modes,
7661 .input_mux = &alc883_capture_source,
7663 [ALC883_3ST_6ch_DIG] = {
7664 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7665 .init_verbs = { alc883_init_verbs },
7666 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7667 .dac_nids = alc883_dac_nids,
7668 .dig_out_nid = ALC883_DIGOUT_NID,
7669 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7670 .adc_nids = alc883_adc_nids,
7671 .dig_in_nid = ALC883_DIGIN_NID,
7672 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7673 .channel_mode = alc883_3ST_6ch_modes,
7675 .input_mux = &alc883_capture_source,
7677 [ALC883_3ST_6ch] = {
7678 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7679 .init_verbs = { alc883_init_verbs },
7680 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7681 .dac_nids = alc883_dac_nids,
7682 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7683 .adc_nids = alc883_adc_nids,
7684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7685 .channel_mode = alc883_3ST_6ch_modes,
7687 .input_mux = &alc883_capture_source,
7689 [ALC883_6ST_DIG] = {
7690 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7691 .init_verbs = { alc883_init_verbs },
7692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7693 .dac_nids = alc883_dac_nids,
7694 .dig_out_nid = ALC883_DIGOUT_NID,
7695 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7696 .adc_nids = alc883_adc_nids,
7697 .dig_in_nid = ALC883_DIGIN_NID,
7698 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7699 .channel_mode = alc883_sixstack_modes,
7700 .input_mux = &alc883_capture_source,
7702 [ALC883_TARGA_DIG] = {
7703 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7704 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7705 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7706 .dac_nids = alc883_dac_nids,
7707 .dig_out_nid = ALC883_DIGOUT_NID,
7708 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7709 .adc_nids = alc883_adc_nids,
7710 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7711 .channel_mode = alc883_3ST_6ch_modes,
7713 .input_mux = &alc883_capture_source,
7714 .unsol_event = alc883_tagra_unsol_event,
7715 .init_hook = alc883_tagra_automute,
7717 [ALC883_TARGA_2ch_DIG] = {
7718 .mixers = { alc883_tagra_2ch_mixer},
7719 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7720 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7721 .dac_nids = alc883_dac_nids,
7722 .dig_out_nid = ALC883_DIGOUT_NID,
7723 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7724 .adc_nids = alc883_adc_nids,
7725 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7726 .channel_mode = alc883_3ST_2ch_modes,
7727 .input_mux = &alc883_capture_source,
7728 .unsol_event = alc883_tagra_unsol_event,
7729 .init_hook = alc883_tagra_automute,
7732 .mixers = { alc883_base_mixer },
7733 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7734 * and the headphone jack. Turn this on and rely on the
7735 * standard mute methods whenever the user wants to turn
7736 * these outputs off.
7738 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7739 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7740 .dac_nids = alc883_dac_nids,
7741 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7742 .adc_nids = alc883_adc_nids,
7743 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7744 .channel_mode = alc883_3ST_2ch_modes,
7745 .input_mux = &alc883_capture_source,
7747 [ALC883_ACER_ASPIRE] = {
7748 .mixers = { alc883_acer_aspire_mixer },
7749 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7750 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7751 .dac_nids = alc883_dac_nids,
7752 .dig_out_nid = ALC883_DIGOUT_NID,
7753 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7754 .adc_nids = alc883_adc_nids,
7755 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7756 .channel_mode = alc883_3ST_2ch_modes,
7757 .input_mux = &alc883_capture_source,
7758 .unsol_event = alc883_acer_aspire_unsol_event,
7759 .init_hook = alc883_acer_aspire_automute,
7762 .mixers = { alc883_fivestack_mixer,
7763 alc883_chmode_mixer },
7764 .init_verbs = { alc883_init_verbs,
7765 alc883_medion_eapd_verbs },
7766 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7767 .dac_nids = alc883_dac_nids,
7768 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7769 .adc_nids = alc883_adc_nids,
7770 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7771 .channel_mode = alc883_sixstack_modes,
7772 .input_mux = &alc883_capture_source,
7774 [ALC883_MEDION_MD2] = {
7775 .mixers = { alc883_medion_md2_mixer},
7776 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7778 .dac_nids = alc883_dac_nids,
7779 .dig_out_nid = ALC883_DIGOUT_NID,
7780 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7781 .adc_nids = alc883_adc_nids,
7782 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7783 .channel_mode = alc883_3ST_2ch_modes,
7784 .input_mux = &alc883_capture_source,
7785 .unsol_event = alc883_medion_md2_unsol_event,
7786 .init_hook = alc883_medion_md2_automute,
7788 [ALC883_LAPTOP_EAPD] = {
7789 .mixers = { alc883_base_mixer },
7790 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7791 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7792 .dac_nids = alc883_dac_nids,
7793 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7794 .adc_nids = alc883_adc_nids,
7795 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7796 .channel_mode = alc883_3ST_2ch_modes,
7797 .input_mux = &alc883_capture_source,
7799 [ALC883_LENOVO_101E_2ch] = {
7800 .mixers = { alc883_lenovo_101e_2ch_mixer},
7801 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7802 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7803 .dac_nids = alc883_dac_nids,
7804 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7805 .adc_nids = alc883_adc_nids,
7806 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7807 .channel_mode = alc883_3ST_2ch_modes,
7808 .input_mux = &alc883_lenovo_101e_capture_source,
7809 .unsol_event = alc883_lenovo_101e_unsol_event,
7810 .init_hook = alc883_lenovo_101e_all_automute,
7812 [ALC883_LENOVO_NB0763] = {
7813 .mixers = { alc883_lenovo_nb0763_mixer },
7814 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7815 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7816 .dac_nids = alc883_dac_nids,
7817 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7818 .adc_nids = alc883_adc_nids,
7819 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7820 .channel_mode = alc883_3ST_2ch_modes,
7822 .input_mux = &alc883_lenovo_nb0763_capture_source,
7823 .unsol_event = alc883_medion_md2_unsol_event,
7824 .init_hook = alc883_medion_md2_automute,
7826 [ALC888_LENOVO_MS7195_DIG] = {
7827 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7828 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7829 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7830 .dac_nids = alc883_dac_nids,
7831 .dig_out_nid = ALC883_DIGOUT_NID,
7832 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7833 .adc_nids = alc883_adc_nids,
7834 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7835 .channel_mode = alc883_3ST_6ch_modes,
7837 .input_mux = &alc883_capture_source,
7838 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7839 .init_hook = alc888_lenovo_ms7195_front_automute,
7841 [ALC883_HAIER_W66] = {
7842 .mixers = { alc883_tagra_2ch_mixer},
7843 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7845 .dac_nids = alc883_dac_nids,
7846 .dig_out_nid = ALC883_DIGOUT_NID,
7847 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7848 .adc_nids = alc883_adc_nids,
7849 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7850 .channel_mode = alc883_3ST_2ch_modes,
7851 .input_mux = &alc883_capture_source,
7852 .unsol_event = alc883_haier_w66_unsol_event,
7853 .init_hook = alc883_haier_w66_automute,
7856 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7857 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7859 .dac_nids = alc883_dac_nids,
7860 .dig_out_nid = ALC883_DIGOUT_NID,
7861 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7862 .adc_nids = alc883_adc_nids,
7863 .dig_in_nid = ALC883_DIGIN_NID,
7864 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7865 .channel_mode = alc883_sixstack_modes,
7866 .input_mux = &alc883_capture_source,
7869 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7870 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7871 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7872 .dac_nids = alc883_dac_nids,
7873 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7874 .adc_nids = alc883_adc_nids,
7875 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7876 .channel_mode = alc888_3st_hp_modes,
7878 .input_mux = &alc883_capture_source,
7880 [ALC888_6ST_DELL] = {
7881 .mixers = { alc888_6st_dell_mixer, alc883_chmode_mixer },
7882 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7883 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7884 .dac_nids = alc883_dac_nids,
7885 .dig_out_nid = ALC883_DIGOUT_NID,
7886 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7887 .adc_nids = alc883_adc_nids,
7888 .dig_in_nid = ALC883_DIGIN_NID,
7889 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7890 .channel_mode = alc883_sixstack_modes,
7891 .input_mux = &alc883_capture_source,
7892 .unsol_event = alc888_6st_dell_unsol_event,
7893 .init_hook = alc888_6st_dell_front_automute,
7896 .mixers = { alc883_mitac_mixer },
7897 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
7898 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7899 .dac_nids = alc883_dac_nids,
7900 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7901 .adc_nids = alc883_adc_nids,
7902 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7903 .channel_mode = alc883_3ST_2ch_modes,
7904 .input_mux = &alc883_capture_source,
7905 .unsol_event = alc883_mitac_unsol_event,
7906 .init_hook = alc883_mitac_automute,
7912 * BIOS auto configuration
7914 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7915 hda_nid_t nid, int pin_type,
7919 struct alc_spec *spec = codec->spec;
7922 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7925 idx = spec->multiout.dac_nids[dac_idx] - 2;
7927 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7929 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7931 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7935 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7937 struct alc_spec *spec = codec->spec;
7940 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7941 for (i = 0; i <= HDA_SIDE; i++) {
7942 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7943 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7945 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7950 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7952 struct alc_spec *spec = codec->spec;
7955 pin = spec->autocfg.hp_pins[0];
7956 if (pin) /* connect to front */
7958 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7961 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
7962 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
7964 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7966 struct alc_spec *spec = codec->spec;
7969 for (i = 0; i < AUTO_PIN_LAST; i++) {
7970 hda_nid_t nid = spec->autocfg.input_pins[i];
7971 if (alc883_is_input_pin(nid)) {
7972 snd_hda_codec_write(codec, nid, 0,
7973 AC_VERB_SET_PIN_WIDGET_CONTROL,
7974 (i <= AUTO_PIN_FRONT_MIC ?
7975 PIN_VREF80 : PIN_IN));
7976 if (nid != ALC883_PIN_CD_NID)
7977 snd_hda_codec_write(codec, nid, 0,
7978 AC_VERB_SET_AMP_GAIN_MUTE,
7984 /* almost identical with ALC880 parser... */
7985 static int alc883_parse_auto_config(struct hda_codec *codec)
7987 struct alc_spec *spec = codec->spec;
7988 int err = alc880_parse_auto_config(codec);
7993 return 0; /* no config found */
7995 err = alc_auto_add_mic_boost(codec);
7999 /* hack - override the init verbs */
8000 spec->init_verbs[0] = alc883_auto_init_verbs;
8001 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8004 return 1; /* config found */
8007 /* additional initialization for auto-configuration model */
8008 static void alc883_auto_init(struct hda_codec *codec)
8010 alc883_auto_init_multi_out(codec);
8011 alc883_auto_init_hp_out(codec);
8012 alc883_auto_init_analog_input(codec);
8015 static int patch_alc883(struct hda_codec *codec)
8017 struct alc_spec *spec;
8018 int err, board_config;
8020 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8026 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8029 if (board_config < 0) {
8030 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8031 "trying auto-probe from BIOS...\n");
8032 board_config = ALC883_AUTO;
8035 if (board_config == ALC883_AUTO) {
8036 /* automatic parse from the BIOS config */
8037 err = alc883_parse_auto_config(codec);
8043 "hda_codec: Cannot set up configuration "
8044 "from BIOS. Using base mode...\n");
8045 board_config = ALC883_3ST_2ch_DIG;
8049 if (board_config != ALC883_AUTO)
8050 setup_preset(spec, &alc883_presets[board_config]);
8052 spec->stream_name_analog = "ALC883 Analog";
8053 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8054 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8055 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8057 spec->stream_name_digital = "ALC883 Digital";
8058 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8059 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8061 if (!spec->adc_nids && spec->input_mux) {
8062 spec->adc_nids = alc883_adc_nids;
8063 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8066 spec->vmaster_nid = 0x0c;
8068 codec->patch_ops = alc_patch_ops;
8069 if (board_config == ALC883_AUTO)
8070 spec->init_hook = alc883_auto_init;
8071 #ifdef CONFIG_SND_HDA_POWER_SAVE
8072 if (!spec->loopback.amplist)
8073 spec->loopback.amplist = alc883_loopbacks;
8083 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8084 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8086 #define alc262_dac_nids alc260_dac_nids
8087 #define alc262_adc_nids alc882_adc_nids
8088 #define alc262_adc_nids_alt alc882_adc_nids_alt
8090 #define alc262_modes alc260_modes
8091 #define alc262_capture_source alc882_capture_source
8093 static struct snd_kcontrol_new alc262_base_mixer[] = {
8094 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8095 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8102 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8104 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8105 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8106 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8107 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8110 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8111 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8115 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8117 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8118 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8119 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8120 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8121 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8124 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8125 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8126 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8127 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8128 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8129 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8130 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8135 /* update HP, line and mono-out pins according to the master switch */
8136 static void alc262_hp_master_update(struct hda_codec *codec)
8138 struct alc_spec *spec = codec->spec;
8139 int val = spec->master_sw;
8142 snd_hda_codec_write_cache(codec, 0x1b, 0,
8143 AC_VERB_SET_PIN_WIDGET_CONTROL,
8145 snd_hda_codec_write_cache(codec, 0x15, 0,
8146 AC_VERB_SET_PIN_WIDGET_CONTROL,
8148 /* mono (speaker) depending on the HP jack sense */
8149 val = val && !spec->jack_present;
8150 snd_hda_codec_write_cache(codec, 0x16, 0,
8151 AC_VERB_SET_PIN_WIDGET_CONTROL,
8155 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8157 struct alc_spec *spec = codec->spec;
8158 unsigned int presence;
8159 presence = snd_hda_codec_read(codec, 0x1b, 0,
8160 AC_VERB_GET_PIN_SENSE, 0);
8161 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8162 alc262_hp_master_update(codec);
8165 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8167 if ((res >> 26) != ALC880_HP_EVENT)
8169 alc262_hp_bpc_automute(codec);
8172 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8174 struct alc_spec *spec = codec->spec;
8175 unsigned int presence;
8176 presence = snd_hda_codec_read(codec, 0x15, 0,
8177 AC_VERB_GET_PIN_SENSE, 0);
8178 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8179 alc262_hp_master_update(codec);
8182 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8185 if ((res >> 26) != ALC880_HP_EVENT)
8187 alc262_hp_wildwest_automute(codec);
8190 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8191 struct snd_ctl_elem_value *ucontrol)
8193 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8194 struct alc_spec *spec = codec->spec;
8195 *ucontrol->value.integer.value = spec->master_sw;
8199 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8200 struct snd_ctl_elem_value *ucontrol)
8202 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8203 struct alc_spec *spec = codec->spec;
8204 int val = !!*ucontrol->value.integer.value;
8206 if (val == spec->master_sw)
8208 spec->master_sw = val;
8209 alc262_hp_master_update(codec);
8213 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8215 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8216 .name = "Master Playback Switch",
8217 .info = snd_ctl_boolean_mono_info,
8218 .get = alc262_hp_master_sw_get,
8219 .put = alc262_hp_master_sw_put,
8221 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8222 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8223 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8224 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8226 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8228 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8230 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8231 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8233 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8235 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8236 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8237 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8238 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8239 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8240 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8241 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8245 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8247 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8248 .name = "Master Playback Switch",
8249 .info = snd_ctl_boolean_mono_info,
8250 .get = alc262_hp_master_sw_get,
8251 .put = alc262_hp_master_sw_put,
8253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8254 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8255 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8256 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8257 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8259 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8261 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8263 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8266 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8267 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8268 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8269 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8273 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8274 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8275 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8276 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8280 /* mute/unmute internal speaker according to the hp jack and mute state */
8281 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8283 struct alc_spec *spec = codec->spec;
8285 if (force || !spec->sense_updated) {
8286 unsigned int present;
8287 present = snd_hda_codec_read(codec, 0x15, 0,
8288 AC_VERB_GET_PIN_SENSE, 0);
8289 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8290 spec->sense_updated = 1;
8292 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8293 spec->jack_present ? HDA_AMP_MUTE : 0);
8296 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8299 if ((res >> 26) != ALC880_HP_EVENT)
8301 alc262_hp_t5735_automute(codec, 1);
8304 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8306 alc262_hp_t5735_automute(codec, 1);
8309 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8310 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8311 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8312 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8316 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8320 static struct hda_verb alc262_hp_t5735_verbs[] = {
8321 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8322 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8328 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8329 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8332 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8338 static struct hda_verb alc262_hp_rp5700_verbs[] = {
8339 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8340 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8341 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8342 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8343 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8344 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8345 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8347 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8352 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8359 /* bind hp and internal speaker mute (with plug check) */
8360 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8361 struct snd_ctl_elem_value *ucontrol)
8363 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8364 long *valp = ucontrol->value.integer.value;
8367 /* change hp mute */
8368 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8370 valp[0] ? 0 : HDA_AMP_MUTE);
8371 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8373 valp[1] ? 0 : HDA_AMP_MUTE);
8375 /* change speaker according to HP jack state */
8376 struct alc_spec *spec = codec->spec;
8378 if (spec->jack_present)
8379 mute = HDA_AMP_MUTE;
8381 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8383 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8384 HDA_AMP_MUTE, mute);
8389 static struct snd_kcontrol_new alc262_sony_mixer[] = {
8390 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8393 .name = "Master Playback Switch",
8394 .info = snd_hda_mixer_amp_switch_info,
8395 .get = snd_hda_mixer_amp_switch_get,
8396 .put = alc262_sony_master_sw_put,
8397 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8399 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8401 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8402 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8406 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8407 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8408 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8409 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8412 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8413 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8417 #define alc262_capture_mixer alc882_capture_mixer
8418 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8421 * generic initialization of ADC, input mixers and output mixers
8423 static struct hda_verb alc262_init_verbs[] = {
8425 * Unmute ADC0-2 and set the default input to mic-in
8427 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8429 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8431 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8434 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8436 * Note: PASD motherboards uses the Line In 2 as the input for
8437 * front panel mic (mic 2)
8439 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8440 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8441 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8442 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8443 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8444 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8447 * Set up output mixers (0x0c - 0x0e)
8449 /* set vol=0 to output mixers */
8450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8451 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8452 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8453 /* set up input amps for analog loopback */
8454 /* Amp Indices: DAC = 0, mixer = 1 */
8455 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8457 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8459 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8460 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8464 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8465 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8466 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8467 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8469 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8470 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8471 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8472 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8473 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8475 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8478 /* FIXME: use matrix-type input source selection */
8479 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8480 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8481 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8482 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8486 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8487 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8488 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8489 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8491 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8492 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8493 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8499 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8500 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8501 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8505 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8506 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8507 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8508 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8510 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8515 static struct hda_verb alc262_sony_unsol_verbs[] = {
8516 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8518 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8520 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8524 /* mute/unmute internal speaker according to the hp jack and mute state */
8525 static void alc262_hippo_automute(struct hda_codec *codec)
8527 struct alc_spec *spec = codec->spec;
8529 unsigned int present;
8531 /* need to execute and sync at first */
8532 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8533 present = snd_hda_codec_read(codec, 0x15, 0,
8534 AC_VERB_GET_PIN_SENSE, 0);
8535 spec->jack_present = (present & 0x80000000) != 0;
8536 if (spec->jack_present) {
8537 /* mute internal speaker */
8538 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8539 HDA_AMP_MUTE, HDA_AMP_MUTE);
8541 /* unmute internal speaker if necessary */
8542 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8543 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8544 HDA_AMP_MUTE, mute);
8548 /* unsolicited event for HP jack sensing */
8549 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8552 if ((res >> 26) != ALC880_HP_EVENT)
8554 alc262_hippo_automute(codec);
8557 static void alc262_hippo1_automute(struct hda_codec *codec)
8560 unsigned int present;
8562 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8563 present = snd_hda_codec_read(codec, 0x1b, 0,
8564 AC_VERB_GET_PIN_SENSE, 0);
8565 present = (present & 0x80000000) != 0;
8567 /* mute internal speaker */
8568 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8569 HDA_AMP_MUTE, HDA_AMP_MUTE);
8571 /* unmute internal speaker if necessary */
8572 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8573 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8574 HDA_AMP_MUTE, mute);
8578 /* unsolicited event for HP jack sensing */
8579 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8582 if ((res >> 26) != ALC880_HP_EVENT)
8584 alc262_hippo1_automute(codec);
8589 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
8592 #define ALC_HP_EVENT 0x37
8594 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8596 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8600 static struct hda_input_mux alc262_fujitsu_capture_source = {
8609 static struct hda_input_mux alc262_HP_capture_source = {
8613 { "Front Mic", 0x1 },
8620 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8624 { "Front Mic", 0x2 },
8630 /* mute/unmute internal speaker according to the hp jack and mute state */
8631 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8633 struct alc_spec *spec = codec->spec;
8636 if (force || !spec->sense_updated) {
8637 unsigned int present;
8638 /* need to execute and sync at first */
8639 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8640 present = snd_hda_codec_read(codec, 0x14, 0,
8641 AC_VERB_GET_PIN_SENSE, 0);
8642 spec->jack_present = (present & 0x80000000) != 0;
8643 spec->sense_updated = 1;
8645 if (spec->jack_present) {
8646 /* mute internal speaker */
8647 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8648 HDA_AMP_MUTE, HDA_AMP_MUTE);
8650 /* unmute internal speaker if necessary */
8651 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8652 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8653 HDA_AMP_MUTE, mute);
8657 /* unsolicited event for HP jack sensing */
8658 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8661 if ((res >> 26) != ALC_HP_EVENT)
8663 alc262_fujitsu_automute(codec, 1);
8666 /* bind volumes of both NID 0x0c and 0x0d */
8667 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8668 .ops = &snd_hda_bind_vol,
8670 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8671 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8676 /* bind hp and internal speaker mute (with plug check) */
8677 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8678 struct snd_ctl_elem_value *ucontrol)
8680 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8681 long *valp = ucontrol->value.integer.value;
8684 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8686 valp[0] ? 0 : HDA_AMP_MUTE);
8687 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8689 valp[1] ? 0 : HDA_AMP_MUTE);
8691 alc262_fujitsu_automute(codec, 0);
8695 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8696 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8699 .name = "Master Playback Switch",
8700 .info = snd_hda_mixer_amp_switch_info,
8701 .get = snd_hda_mixer_amp_switch_get,
8702 .put = alc262_fujitsu_master_sw_put,
8703 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8705 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8706 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8707 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8708 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8710 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8711 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8712 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8716 /* additional init verbs for Benq laptops */
8717 static struct hda_verb alc262_EAPD_verbs[] = {
8718 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8719 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8723 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8724 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8725 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8727 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8728 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8732 /* Samsung Q1 Ultra Vista model setup */
8733 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8734 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8735 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8736 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8737 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8738 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8739 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8743 static struct hda_verb alc262_ultra_verbs[] = {
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8747 /* Mic is on Node 0x19 */
8748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8749 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
8750 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8751 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
8752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8753 {0x24, AC_VERB_SET_CONNECT_SEL, 0x01},
8754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8758 static struct hda_input_mux alc262_ultra_capture_source = {
8765 /* mute/unmute internal speaker according to the hp jack and mute state */
8766 static void alc262_ultra_automute(struct hda_codec *codec)
8768 struct alc_spec *spec = codec->spec;
8770 unsigned int present;
8772 /* need to execute and sync at first */
8773 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8774 present = snd_hda_codec_read(codec, 0x15, 0,
8775 AC_VERB_GET_PIN_SENSE, 0);
8776 spec->jack_present = (present & 0x80000000) != 0;
8777 if (spec->jack_present) {
8778 /* mute internal speaker */
8779 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8780 HDA_AMP_MUTE, HDA_AMP_MUTE);
8782 /* unmute internal speaker if necessary */
8783 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8784 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8785 HDA_AMP_MUTE, mute);
8789 /* unsolicited event for HP jack sensing */
8790 static void alc262_ultra_unsol_event(struct hda_codec *codec,
8793 if ((res >> 26) != ALC880_HP_EVENT)
8795 alc262_ultra_automute(codec);
8798 /* add playback controls from the parsed DAC table */
8799 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8800 const struct auto_pin_cfg *cfg)
8805 spec->multiout.num_dacs = 1; /* only use one dac */
8806 spec->multiout.dac_nids = spec->private_dac_nids;
8807 spec->multiout.dac_nids[0] = 2;
8809 nid = cfg->line_out_pins[0];
8811 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8812 "Front Playback Volume",
8813 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8816 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8817 "Front Playback Switch",
8818 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8823 nid = cfg->speaker_pins[0];
8826 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8827 "Speaker Playback Volume",
8828 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8832 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8833 "Speaker Playback Switch",
8834 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8839 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8840 "Speaker Playback Switch",
8841 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8847 nid = cfg->hp_pins[0];
8849 /* spec->multiout.hp_nid = 2; */
8851 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8852 "Headphone Playback Volume",
8853 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8857 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8858 "Headphone Playback Switch",
8859 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8864 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8865 "Headphone Playback Switch",
8866 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8875 /* identical with ALC880 */
8876 #define alc262_auto_create_analog_input_ctls \
8877 alc880_auto_create_analog_input_ctls
8880 * generic initialization of ADC, input mixers and output mixers
8882 static struct hda_verb alc262_volume_init_verbs[] = {
8884 * Unmute ADC0-2 and set the default input to mic-in
8886 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8888 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8889 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8890 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8891 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8893 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8895 * Note: PASD motherboards uses the Line In 2 as the input for
8896 * front panel mic (mic 2)
8898 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8899 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8903 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8906 * Set up output mixers (0x0c - 0x0f)
8908 /* set vol=0 to output mixers */
8909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8913 /* set up input amps for analog loopback */
8914 /* Amp Indices: DAC = 0, mixer = 1 */
8915 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8916 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8917 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8918 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8919 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8922 /* FIXME: use matrix-type input source selection */
8923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8943 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8945 * Unmute ADC0-2 and set the default input to mic-in
8947 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8948 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8949 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8950 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8951 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8954 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8956 * Note: PASD motherboards uses the Line In 2 as the input for
8957 * front panel mic (mic 2)
8959 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8960 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8961 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8962 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8963 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8964 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8965 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8966 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8969 * Set up output mixers (0x0c - 0x0e)
8971 /* set vol=0 to output mixers */
8972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8974 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8976 /* set up input amps for analog loopback */
8977 /* Amp Indices: DAC = 0, mixer = 1 */
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8979 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8980 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8981 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8982 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8985 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8987 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8989 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8992 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8993 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9001 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9003 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9005 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9006 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9009 /* FIXME: use matrix-type input source selection */
9010 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9011 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9015 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9023 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9024 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9027 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9032 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9034 * Unmute ADC0-2 and set the default input to mic-in
9036 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9038 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9040 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9045 * Note: PASD motherboards uses the Line In 2 as the input for front
9048 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9049 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9050 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9051 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9052 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9053 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9054 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9055 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9056 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9058 * Set up output mixers (0x0c - 0x0e)
9060 /* set vol=0 to output mixers */
9061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9063 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9065 /* set up input amps for analog loopback */
9066 /* Amp Indices: DAC = 0, mixer = 1 */
9067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9069 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9072 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9076 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9078 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9079 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9081 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9086 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9087 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9089 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9090 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9092 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9093 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9094 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9096 /* FIXME: use matrix-type input source selection */
9097 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9098 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9099 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9100 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9101 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9102 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9103 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9104 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9105 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9107 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9108 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9109 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9110 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9111 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9112 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9113 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9115 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9120 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9128 #ifdef CONFIG_SND_HDA_POWER_SAVE
9129 #define alc262_loopbacks alc880_loopbacks
9132 /* pcm configuration: identiacal with ALC880 */
9133 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
9134 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
9135 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
9136 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
9139 * BIOS auto configuration
9141 static int alc262_parse_auto_config(struct hda_codec *codec)
9143 struct alc_spec *spec = codec->spec;
9145 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9147 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9151 if (!spec->autocfg.line_outs)
9152 return 0; /* can't find valid BIOS pin config */
9153 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9156 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9160 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9162 if (spec->autocfg.dig_out_pin)
9163 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9164 if (spec->autocfg.dig_in_pin)
9165 spec->dig_in_nid = ALC262_DIGIN_NID;
9167 if (spec->kctl_alloc)
9168 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9170 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9171 spec->num_mux_defs = 1;
9172 spec->input_mux = &spec->private_imux;
9174 err = alc_auto_add_mic_boost(codec);
9181 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
9182 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
9183 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
9186 /* init callback for auto-configuration model -- overriding the default init */
9187 static void alc262_auto_init(struct hda_codec *codec)
9189 alc262_auto_init_multi_out(codec);
9190 alc262_auto_init_hp_out(codec);
9191 alc262_auto_init_analog_input(codec);
9195 * configuration and preset
9197 static const char *alc262_models[ALC262_MODEL_LAST] = {
9198 [ALC262_BASIC] = "basic",
9199 [ALC262_HIPPO] = "hippo",
9200 [ALC262_HIPPO_1] = "hippo_1",
9201 [ALC262_FUJITSU] = "fujitsu",
9202 [ALC262_HP_BPC] = "hp-bpc",
9203 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9204 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
9205 [ALC262_HP_RP5700] = "hp-rp5700",
9206 [ALC262_BENQ_ED8] = "benq",
9207 [ALC262_BENQ_T31] = "benq-t31",
9208 [ALC262_SONY_ASSAMD] = "sony-assamd",
9209 [ALC262_ULTRA] = "ultra",
9210 [ALC262_AUTO] = "auto",
9213 static struct snd_pci_quirk alc262_cfg_tbl[] = {
9214 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9215 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9216 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9217 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9218 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9219 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9220 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9221 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9222 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9223 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9224 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9225 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9226 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9227 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9228 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9229 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9230 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9231 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9232 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9233 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9234 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9235 ALC262_HP_TC_T5735),
9236 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9237 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9238 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9239 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9240 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9241 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9242 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9243 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9244 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9245 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9246 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9247 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9251 static struct alc_config_preset alc262_presets[] = {
9253 .mixers = { alc262_base_mixer },
9254 .init_verbs = { alc262_init_verbs },
9255 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9256 .dac_nids = alc262_dac_nids,
9258 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9259 .channel_mode = alc262_modes,
9260 .input_mux = &alc262_capture_source,
9263 .mixers = { alc262_base_mixer },
9264 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9265 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9266 .dac_nids = alc262_dac_nids,
9268 .dig_out_nid = ALC262_DIGOUT_NID,
9269 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9270 .channel_mode = alc262_modes,
9271 .input_mux = &alc262_capture_source,
9272 .unsol_event = alc262_hippo_unsol_event,
9273 .init_hook = alc262_hippo_automute,
9275 [ALC262_HIPPO_1] = {
9276 .mixers = { alc262_hippo1_mixer },
9277 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9278 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9279 .dac_nids = alc262_dac_nids,
9281 .dig_out_nid = ALC262_DIGOUT_NID,
9282 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9283 .channel_mode = alc262_modes,
9284 .input_mux = &alc262_capture_source,
9285 .unsol_event = alc262_hippo1_unsol_event,
9286 .init_hook = alc262_hippo1_automute,
9288 [ALC262_FUJITSU] = {
9289 .mixers = { alc262_fujitsu_mixer },
9290 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9291 alc262_fujitsu_unsol_verbs },
9292 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9293 .dac_nids = alc262_dac_nids,
9295 .dig_out_nid = ALC262_DIGOUT_NID,
9296 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9297 .channel_mode = alc262_modes,
9298 .input_mux = &alc262_fujitsu_capture_source,
9299 .unsol_event = alc262_fujitsu_unsol_event,
9302 .mixers = { alc262_HP_BPC_mixer },
9303 .init_verbs = { alc262_HP_BPC_init_verbs },
9304 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9305 .dac_nids = alc262_dac_nids,
9307 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9308 .channel_mode = alc262_modes,
9309 .input_mux = &alc262_HP_capture_source,
9310 .unsol_event = alc262_hp_bpc_unsol_event,
9311 .init_hook = alc262_hp_bpc_automute,
9313 [ALC262_HP_BPC_D7000_WF] = {
9314 .mixers = { alc262_HP_BPC_WildWest_mixer },
9315 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9316 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9317 .dac_nids = alc262_dac_nids,
9319 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9320 .channel_mode = alc262_modes,
9321 .input_mux = &alc262_HP_D7000_capture_source,
9322 .unsol_event = alc262_hp_wildwest_unsol_event,
9323 .init_hook = alc262_hp_wildwest_automute,
9325 [ALC262_HP_BPC_D7000_WL] = {
9326 .mixers = { alc262_HP_BPC_WildWest_mixer,
9327 alc262_HP_BPC_WildWest_option_mixer },
9328 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9329 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9330 .dac_nids = alc262_dac_nids,
9332 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9333 .channel_mode = alc262_modes,
9334 .input_mux = &alc262_HP_D7000_capture_source,
9335 .unsol_event = alc262_hp_wildwest_unsol_event,
9336 .init_hook = alc262_hp_wildwest_automute,
9338 [ALC262_HP_TC_T5735] = {
9339 .mixers = { alc262_hp_t5735_mixer },
9340 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9342 .dac_nids = alc262_dac_nids,
9344 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9345 .channel_mode = alc262_modes,
9346 .input_mux = &alc262_capture_source,
9347 .unsol_event = alc262_hp_t5735_unsol_event,
9348 .init_hook = alc262_hp_t5735_init_hook,
9350 [ALC262_HP_RP5700] = {
9351 .mixers = { alc262_hp_rp5700_mixer },
9352 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9353 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9354 .dac_nids = alc262_dac_nids,
9355 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9356 .channel_mode = alc262_modes,
9357 .input_mux = &alc262_hp_rp5700_capture_source,
9359 [ALC262_BENQ_ED8] = {
9360 .mixers = { alc262_base_mixer },
9361 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9362 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9363 .dac_nids = alc262_dac_nids,
9365 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9366 .channel_mode = alc262_modes,
9367 .input_mux = &alc262_capture_source,
9369 [ALC262_SONY_ASSAMD] = {
9370 .mixers = { alc262_sony_mixer },
9371 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9372 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9373 .dac_nids = alc262_dac_nids,
9375 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9376 .channel_mode = alc262_modes,
9377 .input_mux = &alc262_capture_source,
9378 .unsol_event = alc262_hippo_unsol_event,
9379 .init_hook = alc262_hippo_automute,
9381 [ALC262_BENQ_T31] = {
9382 .mixers = { alc262_benq_t31_mixer },
9383 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9384 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9385 .dac_nids = alc262_dac_nids,
9387 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9388 .channel_mode = alc262_modes,
9389 .input_mux = &alc262_capture_source,
9390 .unsol_event = alc262_hippo_unsol_event,
9391 .init_hook = alc262_hippo_automute,
9394 .mixers = { alc262_ultra_mixer },
9395 .init_verbs = { alc262_init_verbs, alc262_ultra_verbs },
9396 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9397 .dac_nids = alc262_dac_nids,
9399 .dig_out_nid = ALC262_DIGOUT_NID,
9400 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9401 .channel_mode = alc262_modes,
9402 .input_mux = &alc262_ultra_capture_source,
9403 .unsol_event = alc262_ultra_unsol_event,
9404 .init_hook = alc262_ultra_automute,
9408 static int patch_alc262(struct hda_codec *codec)
9410 struct alc_spec *spec;
9414 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9420 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9425 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9426 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9427 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9428 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9432 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9436 if (board_config < 0) {
9437 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9438 "trying auto-probe from BIOS...\n");
9439 board_config = ALC262_AUTO;
9442 if (board_config == ALC262_AUTO) {
9443 /* automatic parse from the BIOS config */
9444 err = alc262_parse_auto_config(codec);
9450 "hda_codec: Cannot set up configuration "
9451 "from BIOS. Using base mode...\n");
9452 board_config = ALC262_BASIC;
9456 if (board_config != ALC262_AUTO)
9457 setup_preset(spec, &alc262_presets[board_config]);
9459 spec->stream_name_analog = "ALC262 Analog";
9460 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9461 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9463 spec->stream_name_digital = "ALC262 Digital";
9464 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9465 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9467 if (!spec->adc_nids && spec->input_mux) {
9468 /* check whether NID 0x07 is valid */
9469 unsigned int wcap = get_wcaps(codec, 0x07);
9472 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9473 if (wcap != AC_WID_AUD_IN) {
9474 spec->adc_nids = alc262_adc_nids_alt;
9475 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9476 spec->mixers[spec->num_mixers] =
9477 alc262_capture_alt_mixer;
9480 spec->adc_nids = alc262_adc_nids;
9481 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9482 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9487 spec->vmaster_nid = 0x0c;
9489 codec->patch_ops = alc_patch_ops;
9490 if (board_config == ALC262_AUTO)
9491 spec->init_hook = alc262_auto_init;
9492 #ifdef CONFIG_SND_HDA_POWER_SAVE
9493 if (!spec->loopback.amplist)
9494 spec->loopback.amplist = alc262_loopbacks;
9501 * ALC268 channel source setting (2 channel)
9503 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9504 #define alc268_modes alc260_modes
9506 static hda_nid_t alc268_dac_nids[2] = {
9511 static hda_nid_t alc268_adc_nids[2] = {
9516 static hda_nid_t alc268_adc_nids_alt[1] = {
9521 static struct snd_kcontrol_new alc268_base_mixer[] = {
9522 /* output mixer control */
9523 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9524 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9525 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9527 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9528 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9529 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9533 static struct hda_verb alc268_eapd_verbs[] = {
9534 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9535 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9539 /* Toshiba specific */
9540 #define alc268_toshiba_automute alc262_hippo_automute
9542 static struct hda_verb alc268_toshiba_verbs[] = {
9543 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9548 /* bind volumes of both NID 0x02 and 0x03 */
9549 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9550 .ops = &snd_hda_bind_vol,
9552 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9553 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9558 /* mute/unmute internal speaker according to the hp jack and mute state */
9559 static void alc268_acer_automute(struct hda_codec *codec, int force)
9561 struct alc_spec *spec = codec->spec;
9564 if (force || !spec->sense_updated) {
9565 unsigned int present;
9566 present = snd_hda_codec_read(codec, 0x14, 0,
9567 AC_VERB_GET_PIN_SENSE, 0);
9568 spec->jack_present = (present & 0x80000000) != 0;
9569 spec->sense_updated = 1;
9571 if (spec->jack_present)
9572 mute = HDA_AMP_MUTE; /* mute internal speaker */
9573 else /* unmute internal speaker if necessary */
9574 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9575 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9576 HDA_AMP_MUTE, mute);
9580 /* bind hp and internal speaker mute (with plug check) */
9581 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9582 struct snd_ctl_elem_value *ucontrol)
9584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9585 long *valp = ucontrol->value.integer.value;
9588 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9590 valp[0] ? 0 : HDA_AMP_MUTE);
9591 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9593 valp[1] ? 0 : HDA_AMP_MUTE);
9595 alc268_acer_automute(codec, 0);
9599 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9600 /* output mixer control */
9601 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9604 .name = "Master Playback Switch",
9605 .info = snd_hda_mixer_amp_switch_info,
9606 .get = snd_hda_mixer_amp_switch_get,
9607 .put = alc268_acer_master_sw_put,
9608 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9610 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9611 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9612 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9616 static struct hda_verb alc268_acer_verbs[] = {
9617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9618 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9620 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9624 /* unsolicited event for HP jack sensing */
9625 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9628 if ((res >> 26) != ALC880_HP_EVENT)
9630 alc268_toshiba_automute(codec);
9633 static void alc268_acer_unsol_event(struct hda_codec *codec,
9636 if ((res >> 26) != ALC880_HP_EVENT)
9638 alc268_acer_automute(codec, 1);
9641 static void alc268_acer_init_hook(struct hda_codec *codec)
9643 alc268_acer_automute(codec, 1);
9646 static struct snd_kcontrol_new alc268_dell_mixer[] = {
9647 /* output mixer control */
9648 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9649 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9650 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9652 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9653 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9657 static struct hda_verb alc268_dell_verbs[] = {
9658 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9659 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9664 /* mute/unmute internal speaker according to the hp jack and mute state */
9665 static void alc268_dell_automute(struct hda_codec *codec)
9667 unsigned int present;
9670 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9671 if (present & 0x80000000)
9672 mute = HDA_AMP_MUTE;
9674 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9675 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9676 HDA_AMP_MUTE, mute);
9679 static void alc268_dell_unsol_event(struct hda_codec *codec,
9682 if ((res >> 26) != ALC880_HP_EVENT)
9684 alc268_dell_automute(codec);
9687 #define alc268_dell_init_hook alc268_dell_automute
9690 * generic initialization of ADC, input mixers and output mixers
9692 static struct hda_verb alc268_base_init_verbs[] = {
9693 /* Unmute DAC0-1 and set vol = 0 */
9694 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9695 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9696 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9697 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9698 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9699 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9702 * Set up output mixers (0x0c - 0x0e)
9704 /* set vol=0 to output mixers */
9705 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9706 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9707 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9708 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
9710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9711 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9714 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9715 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9718 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9719 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9720 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9722 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9723 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9724 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9725 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9726 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9727 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9728 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9729 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9731 /* Unmute Selector 23h,24h and set the default input to mic-in */
9733 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
9734 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9735 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
9736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9742 * generic initialization of ADC, input mixers and output mixers
9744 static struct hda_verb alc268_volume_init_verbs[] = {
9745 /* set output DAC */
9746 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9747 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9748 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9751 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9752 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9754 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9755 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9757 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9758 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9759 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9760 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9761 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9765 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9766 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9768 /* set PCBEEP vol = 0 */
9769 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
9774 #define alc268_mux_enum_info alc_mux_enum_info
9775 #define alc268_mux_enum_get alc_mux_enum_get
9777 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
9778 struct snd_ctl_elem_value *ucontrol)
9780 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9781 struct alc_spec *spec = codec->spec;
9783 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
9784 static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
9785 hda_nid_t nid = capture_mixers[adc_idx];
9787 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
9789 &spec->cur_mux[adc_idx]);
9792 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9793 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9794 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9797 /* The multiple "Capture Source" controls confuse alsamixer
9798 * So call somewhat different..
9800 /* .name = "Capture Source", */
9801 .name = "Input Source",
9803 .info = alc268_mux_enum_info,
9804 .get = alc268_mux_enum_get,
9805 .put = alc268_mux_enum_put,
9810 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9811 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9812 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9813 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9814 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9816 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9817 /* The multiple "Capture Source" controls confuse alsamixer
9818 * So call somewhat different..
9820 /* .name = "Capture Source", */
9821 .name = "Input Source",
9823 .info = alc268_mux_enum_info,
9824 .get = alc268_mux_enum_get,
9825 .put = alc268_mux_enum_put,
9830 static struct hda_input_mux alc268_capture_source = {
9834 { "Front Mic", 0x1 },
9840 #ifdef CONFIG_SND_DEBUG
9841 static struct snd_kcontrol_new alc268_test_mixer[] = {
9842 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9843 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9844 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9845 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9847 /* Volume widgets */
9848 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9849 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9850 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9851 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
9852 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
9853 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
9854 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
9855 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
9856 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
9857 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
9858 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
9859 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
9860 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
9861 /* The below appears problematic on some hardwares */
9862 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
9863 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9864 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
9865 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
9866 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
9868 /* Modes for retasking pin widgets */
9869 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
9870 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
9871 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
9872 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
9874 /* Controls for GPIO pins, assuming they are configured as outputs */
9875 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
9876 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
9877 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
9878 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
9880 /* Switches to allow the digital SPDIF output pin to be enabled.
9881 * The ALC268 does not have an SPDIF input.
9883 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
9885 /* A switch allowing EAPD to be enabled. Some laptops seem to use
9886 * this output to turn on an external amplifier.
9888 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
9889 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
9895 /* create input playback/capture controls for the given pin */
9896 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9897 const char *ctlname, int idx)
9902 sprintf(name, "%s Playback Volume", ctlname);
9904 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9905 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9909 } else if (nid == 0x15) {
9910 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9911 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9917 sprintf(name, "%s Playback Switch", ctlname);
9918 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9919 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9925 /* add playback controls from the parsed DAC table */
9926 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9927 const struct auto_pin_cfg *cfg)
9932 spec->multiout.num_dacs = 2; /* only use one dac */
9933 spec->multiout.dac_nids = spec->private_dac_nids;
9934 spec->multiout.dac_nids[0] = 2;
9935 spec->multiout.dac_nids[1] = 3;
9937 nid = cfg->line_out_pins[0];
9939 alc268_new_analog_output(spec, nid, "Front", 0);
9941 nid = cfg->speaker_pins[0];
9943 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9944 "Speaker Playback Volume",
9945 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9949 nid = cfg->hp_pins[0];
9951 alc268_new_analog_output(spec, nid, "Headphone", 0);
9953 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9955 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9956 "Mono Playback Switch",
9957 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9964 /* create playback/capture controls for input pins */
9965 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9966 const struct auto_pin_cfg *cfg)
9968 struct hda_input_mux *imux = &spec->private_imux;
9971 for (i = 0; i < AUTO_PIN_LAST; i++) {
9972 switch(cfg->input_pins[i]) {
9974 idx1 = 0; /* Mic 1 */
9977 idx1 = 1; /* Mic 2 */
9980 idx1 = 2; /* Line In */
9988 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9989 imux->items[imux->num_items].index = idx1;
9995 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9997 struct alc_spec *spec = codec->spec;
9998 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9999 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10000 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10001 unsigned int dac_vol1, dac_vol2;
10004 snd_hda_codec_write(codec, speaker_nid, 0,
10005 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10006 snd_hda_codec_write(codec, 0x0f, 0,
10007 AC_VERB_SET_AMP_GAIN_MUTE,
10009 snd_hda_codec_write(codec, 0x10, 0,
10010 AC_VERB_SET_AMP_GAIN_MUTE,
10013 snd_hda_codec_write(codec, 0x0f, 0,
10014 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10015 snd_hda_codec_write(codec, 0x10, 0,
10016 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10019 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10020 if (line_nid == 0x14)
10021 dac_vol2 = AMP_OUT_ZERO;
10022 else if (line_nid == 0x15)
10023 dac_vol1 = AMP_OUT_ZERO;
10024 if (hp_nid == 0x14)
10025 dac_vol2 = AMP_OUT_ZERO;
10026 else if (hp_nid == 0x15)
10027 dac_vol1 = AMP_OUT_ZERO;
10028 if (line_nid != 0x16 || hp_nid != 0x16 ||
10029 spec->autocfg.line_out_pins[1] != 0x16 ||
10030 spec->autocfg.line_out_pins[2] != 0x16)
10031 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10033 snd_hda_codec_write(codec, 0x02, 0,
10034 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10035 snd_hda_codec_write(codec, 0x03, 0,
10036 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10039 /* pcm configuration: identiacal with ALC880 */
10040 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
10041 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
10042 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
10043 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
10046 * BIOS auto configuration
10048 static int alc268_parse_auto_config(struct hda_codec *codec)
10050 struct alc_spec *spec = codec->spec;
10052 static hda_nid_t alc268_ignore[] = { 0 };
10054 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10058 if (!spec->autocfg.line_outs)
10059 return 0; /* can't find valid BIOS pin config */
10061 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10064 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10068 spec->multiout.max_channels = 2;
10070 /* digital only support output */
10071 if (spec->autocfg.dig_out_pin)
10072 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10074 if (spec->kctl_alloc)
10075 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10077 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10078 spec->num_mux_defs = 1;
10079 spec->input_mux = &spec->private_imux;
10081 err = alc_auto_add_mic_boost(codec);
10088 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
10089 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
10090 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
10092 /* init callback for auto-configuration model -- overriding the default init */
10093 static void alc268_auto_init(struct hda_codec *codec)
10095 alc268_auto_init_multi_out(codec);
10096 alc268_auto_init_hp_out(codec);
10097 alc268_auto_init_mono_speaker_out(codec);
10098 alc268_auto_init_analog_input(codec);
10102 * configuration and preset
10104 static const char *alc268_models[ALC268_MODEL_LAST] = {
10105 [ALC268_3ST] = "3stack",
10106 [ALC268_TOSHIBA] = "toshiba",
10107 [ALC268_ACER] = "acer",
10108 [ALC268_DELL] = "dell",
10109 [ALC268_ZEPTO] = "zepto",
10110 #ifdef CONFIG_SND_DEBUG
10111 [ALC268_TEST] = "test",
10113 [ALC268_AUTO] = "auto",
10116 static struct snd_pci_quirk alc268_cfg_tbl[] = {
10117 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10118 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10119 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10120 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10121 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10122 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10123 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10124 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10125 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10126 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10127 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10131 static struct alc_config_preset alc268_presets[] = {
10133 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10134 .init_verbs = { alc268_base_init_verbs },
10135 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10136 .dac_nids = alc268_dac_nids,
10137 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10138 .adc_nids = alc268_adc_nids_alt,
10140 .dig_out_nid = ALC268_DIGOUT_NID,
10141 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10142 .channel_mode = alc268_modes,
10143 .input_mux = &alc268_capture_source,
10145 [ALC268_TOSHIBA] = {
10146 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10147 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10148 alc268_toshiba_verbs },
10149 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10150 .dac_nids = alc268_dac_nids,
10151 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10152 .adc_nids = alc268_adc_nids_alt,
10154 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10155 .channel_mode = alc268_modes,
10156 .input_mux = &alc268_capture_source,
10157 .unsol_event = alc268_toshiba_unsol_event,
10158 .init_hook = alc268_toshiba_automute,
10161 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
10162 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10163 alc268_acer_verbs },
10164 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10165 .dac_nids = alc268_dac_nids,
10166 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10167 .adc_nids = alc268_adc_nids_alt,
10169 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10170 .channel_mode = alc268_modes,
10171 .input_mux = &alc268_capture_source,
10172 .unsol_event = alc268_acer_unsol_event,
10173 .init_hook = alc268_acer_init_hook,
10176 .mixers = { alc268_dell_mixer },
10177 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10178 alc268_dell_verbs },
10179 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10180 .dac_nids = alc268_dac_nids,
10182 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10183 .channel_mode = alc268_modes,
10184 .unsol_event = alc268_dell_unsol_event,
10185 .init_hook = alc268_dell_init_hook,
10186 .input_mux = &alc268_capture_source,
10189 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
10190 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10191 alc268_toshiba_verbs },
10192 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10193 .dac_nids = alc268_dac_nids,
10194 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10195 .adc_nids = alc268_adc_nids_alt,
10197 .dig_out_nid = ALC268_DIGOUT_NID,
10198 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10199 .channel_mode = alc268_modes,
10200 .input_mux = &alc268_capture_source,
10201 .unsol_event = alc268_toshiba_unsol_event,
10202 .init_hook = alc268_toshiba_automute
10204 #ifdef CONFIG_SND_DEBUG
10206 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10207 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10208 alc268_volume_init_verbs },
10209 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10210 .dac_nids = alc268_dac_nids,
10211 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10212 .adc_nids = alc268_adc_nids_alt,
10214 .dig_out_nid = ALC268_DIGOUT_NID,
10215 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10216 .channel_mode = alc268_modes,
10217 .input_mux = &alc268_capture_source,
10222 static int patch_alc268(struct hda_codec *codec)
10224 struct alc_spec *spec;
10228 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10232 codec->spec = spec;
10234 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10238 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10239 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10240 "trying auto-probe from BIOS...\n");
10241 board_config = ALC268_AUTO;
10244 if (board_config == ALC268_AUTO) {
10245 /* automatic parse from the BIOS config */
10246 err = alc268_parse_auto_config(codec);
10252 "hda_codec: Cannot set up configuration "
10253 "from BIOS. Using base mode...\n");
10254 board_config = ALC268_3ST;
10258 if (board_config != ALC268_AUTO)
10259 setup_preset(spec, &alc268_presets[board_config]);
10261 spec->stream_name_analog = "ALC268 Analog";
10262 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10263 spec->stream_analog_capture = &alc268_pcm_analog_capture;
10264 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10266 spec->stream_name_digital = "ALC268 Digital";
10267 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10269 if (!spec->adc_nids && spec->input_mux) {
10270 /* check whether NID 0x07 is valid */
10271 unsigned int wcap = get_wcaps(codec, 0x07);
10274 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10275 if (wcap != AC_WID_AUD_IN) {
10276 spec->adc_nids = alc268_adc_nids_alt;
10277 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10278 spec->mixers[spec->num_mixers] =
10279 alc268_capture_alt_mixer;
10280 spec->num_mixers++;
10282 spec->adc_nids = alc268_adc_nids;
10283 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10284 spec->mixers[spec->num_mixers] =
10285 alc268_capture_mixer;
10286 spec->num_mixers++;
10290 spec->vmaster_nid = 0x02;
10292 codec->patch_ops = alc_patch_ops;
10293 if (board_config == ALC268_AUTO)
10294 spec->init_hook = alc268_auto_init;
10300 * ALC269 channel source setting (2 channel)
10302 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10304 #define alc269_dac_nids alc260_dac_nids
10306 static hda_nid_t alc269_adc_nids[1] = {
10311 #define alc269_modes alc260_modes
10312 #define alc269_capture_source alc880_lg_lw_capture_source
10314 static struct snd_kcontrol_new alc269_base_mixer[] = {
10315 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10316 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10317 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10318 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10321 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10322 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10323 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10324 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10326 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10330 /* capture mixer elements */
10331 static struct snd_kcontrol_new alc269_capture_mixer[] = {
10332 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10333 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10336 /* The multiple "Capture Source" controls confuse alsamixer
10337 * So call somewhat different..
10339 /* .name = "Capture Source", */
10340 .name = "Input Source",
10342 .info = alc_mux_enum_info,
10343 .get = alc_mux_enum_get,
10344 .put = alc_mux_enum_put,
10350 * generic initialization of ADC, input mixers and output mixers
10352 static struct hda_verb alc269_init_verbs[] = {
10354 * Unmute ADC0 and set the default input to mic-in
10356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10358 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10359 * analog-loopback mixer widget
10360 * Note: PASD motherboards uses the Line In 2 as the input for
10361 * front panel mic (mic 2)
10363 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10364 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10365 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10366 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10367 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10368 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10371 * Set up output mixers (0x0c - 0x0e)
10373 /* set vol=0 to output mixers */
10374 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10375 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10377 /* set up input amps for analog loopback */
10378 /* Amp Indices: DAC = 0, mixer = 1 */
10379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10381 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10382 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10383 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10384 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10388 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10389 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10390 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10394 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10396 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10397 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10398 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10399 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10400 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10402 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10403 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10405 /* FIXME: use matrix-type input source selection */
10406 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10407 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10414 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10415 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10419 /* add playback controls from the parsed DAC table */
10420 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10421 const struct auto_pin_cfg *cfg)
10426 spec->multiout.num_dacs = 1; /* only use one dac */
10427 spec->multiout.dac_nids = spec->private_dac_nids;
10428 spec->multiout.dac_nids[0] = 2;
10430 nid = cfg->line_out_pins[0];
10432 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10433 "Front Playback Volume",
10434 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10437 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10438 "Front Playback Switch",
10439 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10444 nid = cfg->speaker_pins[0];
10446 if (!cfg->line_out_pins[0]) {
10447 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10448 "Speaker Playback Volume",
10449 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10455 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10456 "Speaker Playback Switch",
10457 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10462 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10463 "Speaker Playback Switch",
10464 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10470 nid = cfg->hp_pins[0];
10472 /* spec->multiout.hp_nid = 2; */
10473 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10474 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10475 "Headphone Playback Volume",
10476 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10482 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10483 "Headphone Playback Switch",
10484 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10489 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10490 "Headphone Playback Switch",
10491 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10500 #define alc269_auto_create_analog_input_ctls \
10501 alc880_auto_create_analog_input_ctls
10503 #ifdef CONFIG_SND_HDA_POWER_SAVE
10504 #define alc269_loopbacks alc880_loopbacks
10507 /* pcm configuration: identiacal with ALC880 */
10508 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
10509 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
10510 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
10511 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
10514 * BIOS auto configuration
10516 static int alc269_parse_auto_config(struct hda_codec *codec)
10518 struct alc_spec *spec = codec->spec;
10520 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10522 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10527 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10530 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10534 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10536 if (spec->autocfg.dig_out_pin)
10537 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10539 if (spec->kctl_alloc)
10540 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10542 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10543 spec->num_mux_defs = 1;
10544 spec->input_mux = &spec->private_imux;
10546 err = alc_auto_add_mic_boost(codec);
10553 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
10554 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
10555 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
10558 /* init callback for auto-configuration model -- overriding the default init */
10559 static void alc269_auto_init(struct hda_codec *codec)
10561 alc269_auto_init_multi_out(codec);
10562 alc269_auto_init_hp_out(codec);
10563 alc269_auto_init_analog_input(codec);
10567 * configuration and preset
10569 static const char *alc269_models[ALC269_MODEL_LAST] = {
10570 [ALC269_BASIC] = "basic",
10573 static struct snd_pci_quirk alc269_cfg_tbl[] = {
10577 static struct alc_config_preset alc269_presets[] = {
10579 .mixers = { alc269_base_mixer },
10580 .init_verbs = { alc269_init_verbs },
10581 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
10582 .dac_nids = alc269_dac_nids,
10584 .num_channel_mode = ARRAY_SIZE(alc269_modes),
10585 .channel_mode = alc269_modes,
10586 .input_mux = &alc269_capture_source,
10590 static int patch_alc269(struct hda_codec *codec)
10592 struct alc_spec *spec;
10596 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10600 codec->spec = spec;
10602 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
10606 if (board_config < 0) {
10607 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
10608 "trying auto-probe from BIOS...\n");
10609 board_config = ALC269_AUTO;
10612 if (board_config == ALC269_AUTO) {
10613 /* automatic parse from the BIOS config */
10614 err = alc269_parse_auto_config(codec);
10620 "hda_codec: Cannot set up configuration "
10621 "from BIOS. Using base mode...\n");
10622 board_config = ALC269_BASIC;
10626 if (board_config != ALC269_AUTO)
10627 setup_preset(spec, &alc269_presets[board_config]);
10629 spec->stream_name_analog = "ALC269 Analog";
10630 spec->stream_analog_playback = &alc269_pcm_analog_playback;
10631 spec->stream_analog_capture = &alc269_pcm_analog_capture;
10633 spec->stream_name_digital = "ALC269 Digital";
10634 spec->stream_digital_playback = &alc269_pcm_digital_playback;
10635 spec->stream_digital_capture = &alc269_pcm_digital_capture;
10637 spec->adc_nids = alc269_adc_nids;
10638 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
10639 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
10640 spec->num_mixers++;
10642 codec->patch_ops = alc_patch_ops;
10643 if (board_config == ALC269_AUTO)
10644 spec->init_hook = alc269_auto_init;
10645 #ifdef CONFIG_SND_HDA_POWER_SAVE
10646 if (!spec->loopback.amplist)
10647 spec->loopback.amplist = alc269_loopbacks;
10654 * ALC861 channel source setting (2/6 channel selection for 3-stack)
10658 * set the path ways for 2 channel output
10659 * need to set the codec line out and mic 1 pin widgets to inputs
10661 static struct hda_verb alc861_threestack_ch2_init[] = {
10662 /* set pin widget 1Ah (line in) for input */
10663 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10664 /* set pin widget 18h (mic1/2) for input, for mic also enable
10667 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10669 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10671 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10672 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10678 * need to set the codec line out and mic 1 pin widgets to outputs
10680 static struct hda_verb alc861_threestack_ch6_init[] = {
10681 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10682 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10683 /* set pin widget 18h (mic1) for output (CLFE)*/
10684 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10686 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10687 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10689 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10691 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10692 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10697 static struct hda_channel_mode alc861_threestack_modes[2] = {
10698 { 2, alc861_threestack_ch2_init },
10699 { 6, alc861_threestack_ch6_init },
10701 /* Set mic1 as input and unmute the mixer */
10702 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
10703 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10704 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10707 /* Set mic1 as output and mute mixer */
10708 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
10709 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10710 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10714 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
10715 { 2, alc861_uniwill_m31_ch2_init },
10716 { 4, alc861_uniwill_m31_ch4_init },
10719 /* Set mic1 and line-in as input and unmute the mixer */
10720 static struct hda_verb alc861_asus_ch2_init[] = {
10721 /* set pin widget 1Ah (line in) for input */
10722 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10723 /* set pin widget 18h (mic1/2) for input, for mic also enable
10726 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10728 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
10730 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
10731 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
10735 /* Set mic1 nad line-in as output and mute mixer */
10736 static struct hda_verb alc861_asus_ch6_init[] = {
10737 /* set pin widget 1Ah (line in) for output (Back Surround)*/
10738 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10739 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10740 /* set pin widget 18h (mic1) for output (CLFE)*/
10741 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10742 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
10743 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
10744 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
10746 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
10748 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
10749 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
10754 static struct hda_channel_mode alc861_asus_modes[2] = {
10755 { 2, alc861_asus_ch2_init },
10756 { 6, alc861_asus_ch6_init },
10761 static struct snd_kcontrol_new alc861_base_mixer[] = {
10762 /* output mixer control */
10763 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10764 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10765 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10766 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10767 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10769 /*Input mixer control */
10770 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10771 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10772 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10773 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10774 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10775 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10777 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10778 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10779 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10781 /* Capture mixer control */
10782 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10783 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10786 .name = "Capture Source",
10788 .info = alc_mux_enum_info,
10789 .get = alc_mux_enum_get,
10790 .put = alc_mux_enum_put,
10795 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
10796 /* output mixer control */
10797 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10798 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10799 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10800 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10801 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10803 /* Input mixer control */
10804 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10805 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10806 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10807 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10808 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10809 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10811 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10812 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10813 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10815 /* Capture mixer control */
10816 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10817 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10819 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10820 .name = "Capture Source",
10822 .info = alc_mux_enum_info,
10823 .get = alc_mux_enum_get,
10824 .put = alc_mux_enum_put,
10827 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10828 .name = "Channel Mode",
10829 .info = alc_ch_mode_info,
10830 .get = alc_ch_mode_get,
10831 .put = alc_ch_mode_put,
10832 .private_value = ARRAY_SIZE(alc861_threestack_modes),
10837 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
10838 /* output mixer control */
10839 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10840 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10841 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10843 /*Capture mixer control */
10844 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10845 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10848 .name = "Capture Source",
10850 .info = alc_mux_enum_info,
10851 .get = alc_mux_enum_get,
10852 .put = alc_mux_enum_put,
10858 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
10859 /* output mixer control */
10860 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10861 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10862 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10863 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10864 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
10866 /* Input mixer control */
10867 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10868 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
10869 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10870 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10871 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10872 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10874 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10875 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10876 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
10878 /* Capture mixer control */
10879 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10880 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10882 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10883 .name = "Capture Source",
10885 .info = alc_mux_enum_info,
10886 .get = alc_mux_enum_get,
10887 .put = alc_mux_enum_put,
10890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10891 .name = "Channel Mode",
10892 .info = alc_ch_mode_info,
10893 .get = alc_ch_mode_get,
10894 .put = alc_ch_mode_put,
10895 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
10900 static struct snd_kcontrol_new alc861_asus_mixer[] = {
10901 /* output mixer control */
10902 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
10903 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
10904 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
10905 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
10906 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
10908 /* Input mixer control */
10909 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
10910 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10911 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10912 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10913 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
10914 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
10915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
10916 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
10917 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
10918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
10920 /* Capture mixer control */
10921 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10922 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10925 .name = "Capture Source",
10927 .info = alc_mux_enum_info,
10928 .get = alc_mux_enum_get,
10929 .put = alc_mux_enum_put,
10932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10933 .name = "Channel Mode",
10934 .info = alc_ch_mode_info,
10935 .get = alc_ch_mode_get,
10936 .put = alc_ch_mode_put,
10937 .private_value = ARRAY_SIZE(alc861_asus_modes),
10942 /* additional mixer */
10943 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
10944 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
10945 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
10946 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
10947 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
10952 * generic initialization of ADC, input mixers and output mixers
10954 static struct hda_verb alc861_base_init_verbs[] = {
10956 * Unmute ADC0 and set the default input to mic-in
10958 /* port-A for surround (rear panel) */
10959 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10960 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
10961 /* port-B for mic-in (rear panel) with vref */
10962 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10963 /* port-C for line-in (rear panel) */
10964 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10965 /* port-D for Front */
10966 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10967 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
10968 /* port-E for HP out (front panel) */
10969 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
10970 /* route front PCM to HP */
10971 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10972 /* port-F for mic-in (front panel) with vref */
10973 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
10974 /* port-G for CLFE (rear panel) */
10975 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10976 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
10977 /* port-H for side (rear panel) */
10978 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
10979 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
10981 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
10982 /* route front mic to ADC1*/
10983 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10984 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10986 /* Unmute DAC0~3 & spdif out*/
10987 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10988 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10989 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10990 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10993 /* Unmute Mixer 14 (mic) 1c (Line in)*/
10994 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10995 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10996 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10997 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10999 /* Unmute Stereo Mixer 15 */
11000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11001 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11005 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11007 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11009 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11011 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11013 /* hp used DAC 3 (Front) */
11014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11015 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11020 static struct hda_verb alc861_threestack_init_verbs[] = {
11022 * Unmute ADC0 and set the default input to mic-in
11024 /* port-A for surround (rear panel) */
11025 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11026 /* port-B for mic-in (rear panel) with vref */
11027 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11028 /* port-C for line-in (rear panel) */
11029 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11030 /* port-D for Front */
11031 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11032 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11033 /* port-E for HP out (front panel) */
11034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11035 /* route front PCM to HP */
11036 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11037 /* port-F for mic-in (front panel) with vref */
11038 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11039 /* port-G for CLFE (rear panel) */
11040 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11041 /* port-H for side (rear panel) */
11042 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11044 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11045 /* route front mic to ADC1*/
11046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11048 /* Unmute DAC0~3 & spdif out*/
11049 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11050 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11052 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11053 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11055 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11056 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11058 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11061 /* Unmute Stereo Mixer 15 */
11062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11067 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11069 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11071 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11073 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11075 /* hp used DAC 3 (Front) */
11076 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11081 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11083 * Unmute ADC0 and set the default input to mic-in
11085 /* port-A for surround (rear panel) */
11086 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11087 /* port-B for mic-in (rear panel) with vref */
11088 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11089 /* port-C for line-in (rear panel) */
11090 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11091 /* port-D for Front */
11092 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11093 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11094 /* port-E for HP out (front panel) */
11095 /* this has to be set to VREF80 */
11096 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11097 /* route front PCM to HP */
11098 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11099 /* port-F for mic-in (front panel) with vref */
11100 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11101 /* port-G for CLFE (rear panel) */
11102 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11103 /* port-H for side (rear panel) */
11104 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11106 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11107 /* route front mic to ADC1*/
11108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11109 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11110 /* Unmute DAC0~3 & spdif out*/
11111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11114 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11117 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11118 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11120 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11123 /* Unmute Stereo Mixer 15 */
11124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11129 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11131 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11133 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11137 /* hp used DAC 3 (Front) */
11138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11143 static struct hda_verb alc861_asus_init_verbs[] = {
11145 * Unmute ADC0 and set the default input to mic-in
11147 /* port-A for surround (rear panel)
11148 * according to codec#0 this is the HP jack
11150 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11151 /* route front PCM to HP */
11152 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11153 /* port-B for mic-in (rear panel) with vref */
11154 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11155 /* port-C for line-in (rear panel) */
11156 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11157 /* port-D for Front */
11158 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11159 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11160 /* port-E for HP out (front panel) */
11161 /* this has to be set to VREF80 */
11162 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11163 /* route front PCM to HP */
11164 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11165 /* port-F for mic-in (front panel) with vref */
11166 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11167 /* port-G for CLFE (rear panel) */
11168 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11169 /* port-H for side (rear panel) */
11170 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11172 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11173 /* route front mic to ADC1*/
11174 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11175 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11176 /* Unmute DAC0~3 & spdif out*/
11177 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11178 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11179 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11180 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11181 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11182 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11183 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11184 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11185 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11186 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11188 /* Unmute Stereo Mixer 15 */
11189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11191 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11192 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11194 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11195 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11196 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11197 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11199 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11202 /* hp used DAC 3 (Front) */
11203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11204 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11208 /* additional init verbs for ASUS laptops */
11209 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11210 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11211 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11216 * generic initialization of ADC, input mixers and output mixers
11218 static struct hda_verb alc861_auto_init_verbs[] = {
11220 * Unmute ADC0 and set the default input to mic-in
11222 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
11223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11225 /* Unmute DAC0~3 & spdif out*/
11226 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11227 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11228 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11229 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11232 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11233 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11234 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11235 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11236 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11238 /* Unmute Stereo Mixer 15 */
11239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11240 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11242 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11244 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11246 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11247 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11249 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11255 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11256 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11258 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11259 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11260 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11262 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
11267 static struct hda_verb alc861_toshiba_init_verbs[] = {
11268 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11273 /* toggle speaker-output according to the hp-jack state */
11274 static void alc861_toshiba_automute(struct hda_codec *codec)
11276 unsigned int present;
11278 present = snd_hda_codec_read(codec, 0x0f, 0,
11279 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11280 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11281 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11282 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11283 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
11286 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11289 if ((res >> 26) == ALC880_HP_EVENT)
11290 alc861_toshiba_automute(codec);
11293 /* pcm configuration: identiacal with ALC880 */
11294 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
11295 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
11296 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
11297 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
11300 #define ALC861_DIGOUT_NID 0x07
11302 static struct hda_channel_mode alc861_8ch_modes[1] = {
11306 static hda_nid_t alc861_dac_nids[4] = {
11307 /* front, surround, clfe, side */
11308 0x03, 0x06, 0x05, 0x04
11311 static hda_nid_t alc660_dac_nids[3] = {
11312 /* front, clfe, surround */
11316 static hda_nid_t alc861_adc_nids[1] = {
11321 static struct hda_input_mux alc861_capture_source = {
11325 { "Front Mic", 0x3 },
11332 /* fill in the dac_nids table from the parsed pin configuration */
11333 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11334 const struct auto_pin_cfg *cfg)
11339 spec->multiout.dac_nids = spec->private_dac_nids;
11340 for (i = 0; i < cfg->line_outs; i++) {
11341 nid = cfg->line_out_pins[i];
11343 if (i >= ARRAY_SIZE(alc861_dac_nids))
11345 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11348 spec->multiout.num_dacs = cfg->line_outs;
11352 /* add playback controls from the parsed DAC table */
11353 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11354 const struct auto_pin_cfg *cfg)
11357 static const char *chname[4] = {
11358 "Front", "Surround", NULL /*CLFE*/, "Side"
11363 for (i = 0; i < cfg->line_outs; i++) {
11364 nid = spec->multiout.dac_nids[i];
11369 err = add_control(spec, ALC_CTL_BIND_MUTE,
11370 "Center Playback Switch",
11371 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11375 err = add_control(spec, ALC_CTL_BIND_MUTE,
11376 "LFE Playback Switch",
11377 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11382 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11384 if (nid == alc861_dac_nids[idx])
11386 sprintf(name, "%s Playback Switch", chname[idx]);
11387 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11388 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11397 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11405 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11407 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11408 "Headphone Playback Switch",
11409 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11412 spec->multiout.hp_nid = nid;
11417 /* create playback/capture controls for input pins */
11418 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11419 const struct auto_pin_cfg *cfg)
11421 struct hda_input_mux *imux = &spec->private_imux;
11422 int i, err, idx, idx1;
11424 for (i = 0; i < AUTO_PIN_LAST; i++) {
11425 switch (cfg->input_pins[i]) {
11428 idx = 2; /* Line In */
11432 idx = 2; /* Line In */
11436 idx = 1; /* Mic In */
11440 idx = 1; /* Mic In */
11450 err = new_analog_input(spec, cfg->input_pins[i],
11451 auto_pin_cfg_labels[i], idx, 0x15);
11455 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11456 imux->items[imux->num_items].index = idx1;
11462 static struct snd_kcontrol_new alc861_capture_mixer[] = {
11463 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11464 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11467 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11468 /* The multiple "Capture Source" controls confuse alsamixer
11469 * So call somewhat different..
11471 /* .name = "Capture Source", */
11472 .name = "Input Source",
11474 .info = alc_mux_enum_info,
11475 .get = alc_mux_enum_get,
11476 .put = alc_mux_enum_put,
11481 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11483 int pin_type, int dac_idx)
11485 /* set as output */
11487 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11489 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11494 static void alc861_auto_init_multi_out(struct hda_codec *codec)
11496 struct alc_spec *spec = codec->spec;
11499 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
11500 for (i = 0; i < spec->autocfg.line_outs; i++) {
11501 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11502 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11504 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11505 spec->multiout.dac_nids[i]);
11509 static void alc861_auto_init_hp_out(struct hda_codec *codec)
11511 struct alc_spec *spec = codec->spec;
11514 pin = spec->autocfg.hp_pins[0];
11515 if (pin) /* connect to front */
11516 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11517 spec->multiout.dac_nids[0]);
11520 static void alc861_auto_init_analog_input(struct hda_codec *codec)
11522 struct alc_spec *spec = codec->spec;
11525 for (i = 0; i < AUTO_PIN_LAST; i++) {
11526 hda_nid_t nid = spec->autocfg.input_pins[i];
11527 if (nid >= 0x0c && nid <= 0x11) {
11528 snd_hda_codec_write(codec, nid, 0,
11529 AC_VERB_SET_PIN_WIDGET_CONTROL,
11530 i <= AUTO_PIN_FRONT_MIC ?
11531 PIN_VREF80 : PIN_IN);
11536 /* parse the BIOS configuration and set up the alc_spec */
11537 /* return 1 if successful, 0 if the proper config is not found,
11538 * or a negative error code
11540 static int alc861_parse_auto_config(struct hda_codec *codec)
11542 struct alc_spec *spec = codec->spec;
11544 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11546 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11550 if (!spec->autocfg.line_outs)
11551 return 0; /* can't find valid BIOS pin config */
11553 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11556 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11559 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11562 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11566 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11568 if (spec->autocfg.dig_out_pin)
11569 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
11571 if (spec->kctl_alloc)
11572 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11574 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
11576 spec->num_mux_defs = 1;
11577 spec->input_mux = &spec->private_imux;
11579 spec->adc_nids = alc861_adc_nids;
11580 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
11581 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
11582 spec->num_mixers++;
11587 /* additional initialization for auto-configuration model */
11588 static void alc861_auto_init(struct hda_codec *codec)
11590 alc861_auto_init_multi_out(codec);
11591 alc861_auto_init_hp_out(codec);
11592 alc861_auto_init_analog_input(codec);
11595 #ifdef CONFIG_SND_HDA_POWER_SAVE
11596 static struct hda_amp_list alc861_loopbacks[] = {
11597 { 0x15, HDA_INPUT, 0 },
11598 { 0x15, HDA_INPUT, 1 },
11599 { 0x15, HDA_INPUT, 2 },
11600 { 0x15, HDA_INPUT, 3 },
11607 * configuration and preset
11609 static const char *alc861_models[ALC861_MODEL_LAST] = {
11610 [ALC861_3ST] = "3stack",
11611 [ALC660_3ST] = "3stack-660",
11612 [ALC861_3ST_DIG] = "3stack-dig",
11613 [ALC861_6ST_DIG] = "6stack-dig",
11614 [ALC861_UNIWILL_M31] = "uniwill-m31",
11615 [ALC861_TOSHIBA] = "toshiba",
11616 [ALC861_ASUS] = "asus",
11617 [ALC861_ASUS_LAPTOP] = "asus-laptop",
11618 [ALC861_AUTO] = "auto",
11621 static struct snd_pci_quirk alc861_cfg_tbl[] = {
11622 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
11623 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11624 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
11625 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
11626 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
11627 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
11628 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
11629 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
11630 * Any other models that need this preset?
11632 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
11633 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
11634 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
11635 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
11636 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
11637 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
11638 /* FIXME: the below seems conflict */
11639 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
11640 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
11641 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
11645 static struct alc_config_preset alc861_presets[] = {
11647 .mixers = { alc861_3ST_mixer },
11648 .init_verbs = { alc861_threestack_init_verbs },
11649 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11650 .dac_nids = alc861_dac_nids,
11651 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11652 .channel_mode = alc861_threestack_modes,
11654 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11655 .adc_nids = alc861_adc_nids,
11656 .input_mux = &alc861_capture_source,
11658 [ALC861_3ST_DIG] = {
11659 .mixers = { alc861_base_mixer },
11660 .init_verbs = { alc861_threestack_init_verbs },
11661 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11662 .dac_nids = alc861_dac_nids,
11663 .dig_out_nid = ALC861_DIGOUT_NID,
11664 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11665 .channel_mode = alc861_threestack_modes,
11667 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11668 .adc_nids = alc861_adc_nids,
11669 .input_mux = &alc861_capture_source,
11671 [ALC861_6ST_DIG] = {
11672 .mixers = { alc861_base_mixer },
11673 .init_verbs = { alc861_base_init_verbs },
11674 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11675 .dac_nids = alc861_dac_nids,
11676 .dig_out_nid = ALC861_DIGOUT_NID,
11677 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
11678 .channel_mode = alc861_8ch_modes,
11679 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11680 .adc_nids = alc861_adc_nids,
11681 .input_mux = &alc861_capture_source,
11684 .mixers = { alc861_3ST_mixer },
11685 .init_verbs = { alc861_threestack_init_verbs },
11686 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
11687 .dac_nids = alc660_dac_nids,
11688 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
11689 .channel_mode = alc861_threestack_modes,
11691 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11692 .adc_nids = alc861_adc_nids,
11693 .input_mux = &alc861_capture_source,
11695 [ALC861_UNIWILL_M31] = {
11696 .mixers = { alc861_uniwill_m31_mixer },
11697 .init_verbs = { alc861_uniwill_m31_init_verbs },
11698 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11699 .dac_nids = alc861_dac_nids,
11700 .dig_out_nid = ALC861_DIGOUT_NID,
11701 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
11702 .channel_mode = alc861_uniwill_m31_modes,
11704 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11705 .adc_nids = alc861_adc_nids,
11706 .input_mux = &alc861_capture_source,
11708 [ALC861_TOSHIBA] = {
11709 .mixers = { alc861_toshiba_mixer },
11710 .init_verbs = { alc861_base_init_verbs,
11711 alc861_toshiba_init_verbs },
11712 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11713 .dac_nids = alc861_dac_nids,
11714 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11715 .channel_mode = alc883_3ST_2ch_modes,
11716 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11717 .adc_nids = alc861_adc_nids,
11718 .input_mux = &alc861_capture_source,
11719 .unsol_event = alc861_toshiba_unsol_event,
11720 .init_hook = alc861_toshiba_automute,
11723 .mixers = { alc861_asus_mixer },
11724 .init_verbs = { alc861_asus_init_verbs },
11725 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11726 .dac_nids = alc861_dac_nids,
11727 .dig_out_nid = ALC861_DIGOUT_NID,
11728 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
11729 .channel_mode = alc861_asus_modes,
11732 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11733 .adc_nids = alc861_adc_nids,
11734 .input_mux = &alc861_capture_source,
11736 [ALC861_ASUS_LAPTOP] = {
11737 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
11738 .init_verbs = { alc861_asus_init_verbs,
11739 alc861_asus_laptop_init_verbs },
11740 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
11741 .dac_nids = alc861_dac_nids,
11742 .dig_out_nid = ALC861_DIGOUT_NID,
11743 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
11744 .channel_mode = alc883_3ST_2ch_modes,
11746 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
11747 .adc_nids = alc861_adc_nids,
11748 .input_mux = &alc861_capture_source,
11753 static int patch_alc861(struct hda_codec *codec)
11755 struct alc_spec *spec;
11759 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11763 codec->spec = spec;
11765 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
11769 if (board_config < 0) {
11770 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
11771 "trying auto-probe from BIOS...\n");
11772 board_config = ALC861_AUTO;
11775 if (board_config == ALC861_AUTO) {
11776 /* automatic parse from the BIOS config */
11777 err = alc861_parse_auto_config(codec);
11783 "hda_codec: Cannot set up configuration "
11784 "from BIOS. Using base mode...\n");
11785 board_config = ALC861_3ST_DIG;
11789 if (board_config != ALC861_AUTO)
11790 setup_preset(spec, &alc861_presets[board_config]);
11792 spec->stream_name_analog = "ALC861 Analog";
11793 spec->stream_analog_playback = &alc861_pcm_analog_playback;
11794 spec->stream_analog_capture = &alc861_pcm_analog_capture;
11796 spec->stream_name_digital = "ALC861 Digital";
11797 spec->stream_digital_playback = &alc861_pcm_digital_playback;
11798 spec->stream_digital_capture = &alc861_pcm_digital_capture;
11800 spec->vmaster_nid = 0x03;
11802 codec->patch_ops = alc_patch_ops;
11803 if (board_config == ALC861_AUTO)
11804 spec->init_hook = alc861_auto_init;
11805 #ifdef CONFIG_SND_HDA_POWER_SAVE
11806 if (!spec->loopback.amplist)
11807 spec->loopback.amplist = alc861_loopbacks;
11814 * ALC861-VD support
11818 * In addition, an independent DAC
11820 #define ALC861VD_DIGOUT_NID 0x06
11822 static hda_nid_t alc861vd_dac_nids[4] = {
11823 /* front, surr, clfe, side surr */
11824 0x02, 0x03, 0x04, 0x05
11827 /* dac_nids for ALC660vd are in a different order - according to
11828 * Realtek's driver.
11829 * This should probably tesult in a different mixer for 6stack models
11830 * of ALC660vd codecs, but for now there is only 3stack mixer
11831 * - and it is the same as in 861vd.
11832 * adc_nids in ALC660vd are (is) the same as in 861vd
11834 static hda_nid_t alc660vd_dac_nids[3] = {
11835 /* front, rear, clfe, rear_surr */
11839 static hda_nid_t alc861vd_adc_nids[1] = {
11845 /* FIXME: should be a matrix-type input source selection */
11846 static struct hda_input_mux alc861vd_capture_source = {
11850 { "Front Mic", 0x1 },
11856 static struct hda_input_mux alc861vd_dallas_capture_source = {
11859 { "Front Mic", 0x0 },
11860 { "ATAPI Mic", 0x1 },
11861 { "Line In", 0x5 },
11865 static struct hda_input_mux alc861vd_hp_capture_source = {
11868 { "Front Mic", 0x0 },
11869 { "ATAPI Mic", 0x1 },
11873 #define alc861vd_mux_enum_info alc_mux_enum_info
11874 #define alc861vd_mux_enum_get alc_mux_enum_get
11876 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
11877 struct snd_ctl_elem_value *ucontrol)
11879 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11880 struct alc_spec *spec = codec->spec;
11881 const struct hda_input_mux *imux = spec->input_mux;
11882 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11883 static hda_nid_t capture_mixers[1] = { 0x22 };
11884 hda_nid_t nid = capture_mixers[adc_idx];
11885 unsigned int *cur_val = &spec->cur_mux[adc_idx];
11886 unsigned int i, idx;
11888 idx = ucontrol->value.enumerated.item[0];
11889 if (idx >= imux->num_items)
11890 idx = imux->num_items - 1;
11891 if (*cur_val == idx)
11893 for (i = 0; i < imux->num_items; i++) {
11894 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11895 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11896 imux->items[i].index,
11906 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
11913 static struct hda_verb alc861vd_6stack_ch6_init[] = {
11914 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11915 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11916 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11917 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11924 static struct hda_verb alc861vd_6stack_ch8_init[] = {
11925 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11926 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11927 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11928 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11932 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
11933 { 6, alc861vd_6stack_ch6_init },
11934 { 8, alc861vd_6stack_ch8_init },
11937 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
11939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11940 .name = "Channel Mode",
11941 .info = alc_ch_mode_info,
11942 .get = alc_ch_mode_get,
11943 .put = alc_ch_mode_put,
11948 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
11949 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11950 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11953 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11954 /* The multiple "Capture Source" controls confuse alsamixer
11955 * So call somewhat different..
11957 /* .name = "Capture Source", */
11958 .name = "Input Source",
11960 .info = alc861vd_mux_enum_info,
11961 .get = alc861vd_mux_enum_get,
11962 .put = alc861vd_mux_enum_put,
11967 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11968 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11970 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
11971 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
11974 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11975 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
11977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
11979 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
11981 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11982 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
11984 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
11985 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
11987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11989 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11993 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11994 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11995 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11997 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11998 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12000 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12001 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12003 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12004 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12009 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12010 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12011 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12015 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12019 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12023 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12024 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12026 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12027 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12029 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12030 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12035 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12036 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12037 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12038 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12040 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12042 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12046 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12048 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12050 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12051 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12056 /* Pin assignment: Front=0x14, HP = 0x15,
12057 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
12059 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12060 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12061 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12062 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12063 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12064 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12065 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12066 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12067 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
12069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
12073 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
12074 * Front Mic=0x18, ATAPI Mic = 0x19,
12076 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12077 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12078 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12079 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12080 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12081 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12082 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12083 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12084 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12090 * generic initialization of ADC, input mixers and output mixers
12092 static struct hda_verb alc861vd_volume_init_verbs[] = {
12094 * Unmute ADC0 and set the default input to mic-in
12096 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12097 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12099 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12100 * the analog-loopback mixer widget
12102 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12109 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12113 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12116 * Set up output mixers (0x02 - 0x05)
12118 /* set vol=0 to output mixers */
12119 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12120 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12121 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12122 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12124 /* set up input amps for analog loopback */
12125 /* Amp Indices: DAC = 0, mixer = 1 */
12126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12130 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12131 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12132 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12133 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12139 * 3-stack pin configuration:
12140 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12142 static struct hda_verb alc861vd_3stack_init_verbs[] = {
12144 * Set pin mode and muting
12146 /* set front pin widgets 0x14 for output */
12147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12148 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12149 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12151 /* Mic (rear) pin: input vref at 80% */
12152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12153 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12154 /* Front Mic pin: input vref at 80% */
12155 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12156 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12157 /* Line In pin: input */
12158 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12159 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12160 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12161 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12162 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12163 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12164 /* CD pin widget for input */
12165 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12171 * 6-stack pin configuration:
12173 static struct hda_verb alc861vd_6stack_init_verbs[] = {
12175 * Set pin mode and muting
12177 /* set front pin widgets 0x14 for output */
12178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12179 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12180 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12182 /* Rear Pin: output 1 (0x0d) */
12183 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12184 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12185 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12186 /* CLFE Pin: output 2 (0x0e) */
12187 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12188 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12189 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12190 /* Side Pin: output 3 (0x0f) */
12191 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12192 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12193 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12195 /* Mic (rear) pin: input vref at 80% */
12196 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12198 /* Front Mic pin: input vref at 80% */
12199 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12201 /* Line In pin: input */
12202 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12203 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12204 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12206 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12208 /* CD pin widget for input */
12209 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12214 static struct hda_verb alc861vd_eapd_verbs[] = {
12215 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12219 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12222 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12224 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12228 /* toggle speaker-output according to the hp-jack state */
12229 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12231 unsigned int present;
12232 unsigned char bits;
12234 present = snd_hda_codec_read(codec, 0x1b, 0,
12235 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12236 bits = present ? HDA_AMP_MUTE : 0;
12237 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12238 HDA_AMP_MUTE, bits);
12241 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12243 unsigned int present;
12244 unsigned char bits;
12246 present = snd_hda_codec_read(codec, 0x18, 0,
12247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12248 bits = present ? HDA_AMP_MUTE : 0;
12249 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12250 HDA_AMP_MUTE, bits);
12253 static void alc861vd_lenovo_automute(struct hda_codec *codec)
12255 alc861vd_lenovo_hp_automute(codec);
12256 alc861vd_lenovo_mic_automute(codec);
12259 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12262 switch (res >> 26) {
12263 case ALC880_HP_EVENT:
12264 alc861vd_lenovo_hp_automute(codec);
12266 case ALC880_MIC_EVENT:
12267 alc861vd_lenovo_mic_automute(codec);
12272 static struct hda_verb alc861vd_dallas_verbs[] = {
12273 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12274 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12275 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12276 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12278 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12280 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12282 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12283 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12284 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12285 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12291 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12292 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12296 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12297 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12298 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12299 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12302 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12303 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12305 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12310 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12311 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12312 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12317 /* toggle speaker-output according to the hp-jack state */
12318 static void alc861vd_dallas_automute(struct hda_codec *codec)
12320 unsigned int present;
12322 present = snd_hda_codec_read(codec, 0x15, 0,
12323 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12324 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12325 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12328 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12330 if ((res >> 26) == ALC880_HP_EVENT)
12331 alc861vd_dallas_automute(codec);
12334 #ifdef CONFIG_SND_HDA_POWER_SAVE
12335 #define alc861vd_loopbacks alc880_loopbacks
12338 /* pcm configuration: identiacal with ALC880 */
12339 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12340 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12341 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12342 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12345 * configuration and preset
12347 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12348 [ALC660VD_3ST] = "3stack-660",
12349 [ALC660VD_3ST_DIG] = "3stack-660-digout",
12350 [ALC861VD_3ST] = "3stack",
12351 [ALC861VD_3ST_DIG] = "3stack-digout",
12352 [ALC861VD_6ST_DIG] = "6stack-digout",
12353 [ALC861VD_LENOVO] = "lenovo",
12354 [ALC861VD_DALLAS] = "dallas",
12355 [ALC861VD_HP] = "hp",
12356 [ALC861VD_AUTO] = "auto",
12359 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
12360 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12361 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
12362 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
12363 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
12364 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
12365 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
12366 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
12367 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
12368 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
12369 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
12370 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12371 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12372 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
12373 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12377 static struct alc_config_preset alc861vd_presets[] = {
12379 .mixers = { alc861vd_3st_mixer },
12380 .init_verbs = { alc861vd_volume_init_verbs,
12381 alc861vd_3stack_init_verbs },
12382 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12383 .dac_nids = alc660vd_dac_nids,
12384 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12385 .adc_nids = alc861vd_adc_nids,
12386 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12387 .channel_mode = alc861vd_3stack_2ch_modes,
12388 .input_mux = &alc861vd_capture_source,
12390 [ALC660VD_3ST_DIG] = {
12391 .mixers = { alc861vd_3st_mixer },
12392 .init_verbs = { alc861vd_volume_init_verbs,
12393 alc861vd_3stack_init_verbs },
12394 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12395 .dac_nids = alc660vd_dac_nids,
12396 .dig_out_nid = ALC861VD_DIGOUT_NID,
12397 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12398 .adc_nids = alc861vd_adc_nids,
12399 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12400 .channel_mode = alc861vd_3stack_2ch_modes,
12401 .input_mux = &alc861vd_capture_source,
12404 .mixers = { alc861vd_3st_mixer },
12405 .init_verbs = { alc861vd_volume_init_verbs,
12406 alc861vd_3stack_init_verbs },
12407 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12408 .dac_nids = alc861vd_dac_nids,
12409 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12410 .channel_mode = alc861vd_3stack_2ch_modes,
12411 .input_mux = &alc861vd_capture_source,
12413 [ALC861VD_3ST_DIG] = {
12414 .mixers = { alc861vd_3st_mixer },
12415 .init_verbs = { alc861vd_volume_init_verbs,
12416 alc861vd_3stack_init_verbs },
12417 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12418 .dac_nids = alc861vd_dac_nids,
12419 .dig_out_nid = ALC861VD_DIGOUT_NID,
12420 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12421 .channel_mode = alc861vd_3stack_2ch_modes,
12422 .input_mux = &alc861vd_capture_source,
12424 [ALC861VD_6ST_DIG] = {
12425 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12426 .init_verbs = { alc861vd_volume_init_verbs,
12427 alc861vd_6stack_init_verbs },
12428 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12429 .dac_nids = alc861vd_dac_nids,
12430 .dig_out_nid = ALC861VD_DIGOUT_NID,
12431 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12432 .channel_mode = alc861vd_6stack_modes,
12433 .input_mux = &alc861vd_capture_source,
12435 [ALC861VD_LENOVO] = {
12436 .mixers = { alc861vd_lenovo_mixer },
12437 .init_verbs = { alc861vd_volume_init_verbs,
12438 alc861vd_3stack_init_verbs,
12439 alc861vd_eapd_verbs,
12440 alc861vd_lenovo_unsol_verbs },
12441 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12442 .dac_nids = alc660vd_dac_nids,
12443 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12444 .adc_nids = alc861vd_adc_nids,
12445 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12446 .channel_mode = alc861vd_3stack_2ch_modes,
12447 .input_mux = &alc861vd_capture_source,
12448 .unsol_event = alc861vd_lenovo_unsol_event,
12449 .init_hook = alc861vd_lenovo_automute,
12451 [ALC861VD_DALLAS] = {
12452 .mixers = { alc861vd_dallas_mixer },
12453 .init_verbs = { alc861vd_dallas_verbs },
12454 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12455 .dac_nids = alc861vd_dac_nids,
12456 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12457 .adc_nids = alc861vd_adc_nids,
12458 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12459 .channel_mode = alc861vd_3stack_2ch_modes,
12460 .input_mux = &alc861vd_dallas_capture_source,
12461 .unsol_event = alc861vd_dallas_unsol_event,
12462 .init_hook = alc861vd_dallas_automute,
12465 .mixers = { alc861vd_hp_mixer },
12466 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12467 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12468 .dac_nids = alc861vd_dac_nids,
12469 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12470 .dig_out_nid = ALC861VD_DIGOUT_NID,
12471 .adc_nids = alc861vd_adc_nids,
12472 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12473 .channel_mode = alc861vd_3stack_2ch_modes,
12474 .input_mux = &alc861vd_hp_capture_source,
12475 .unsol_event = alc861vd_dallas_unsol_event,
12476 .init_hook = alc861vd_dallas_automute,
12481 * BIOS auto configuration
12483 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12484 hda_nid_t nid, int pin_type, int dac_idx)
12486 /* set as output */
12487 snd_hda_codec_write(codec, nid, 0,
12488 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12489 snd_hda_codec_write(codec, nid, 0,
12490 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12493 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12495 struct alc_spec *spec = codec->spec;
12498 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
12499 for (i = 0; i <= HDA_SIDE; i++) {
12500 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12501 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12503 alc861vd_auto_set_output_and_unmute(codec, nid,
12509 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12511 struct alc_spec *spec = codec->spec;
12514 pin = spec->autocfg.hp_pins[0];
12515 if (pin) /* connect to front and use dac 0 */
12516 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12519 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12520 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12522 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12524 struct alc_spec *spec = codec->spec;
12527 for (i = 0; i < AUTO_PIN_LAST; i++) {
12528 hda_nid_t nid = spec->autocfg.input_pins[i];
12529 if (alc861vd_is_input_pin(nid)) {
12530 snd_hda_codec_write(codec, nid, 0,
12531 AC_VERB_SET_PIN_WIDGET_CONTROL,
12532 i <= AUTO_PIN_FRONT_MIC ?
12533 PIN_VREF80 : PIN_IN);
12534 if (nid != ALC861VD_PIN_CD_NID)
12535 snd_hda_codec_write(codec, nid, 0,
12536 AC_VERB_SET_AMP_GAIN_MUTE,
12542 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12543 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12545 /* add playback controls from the parsed DAC table */
12546 /* Based on ALC880 version. But ALC861VD has separate,
12547 * different NIDs for mute/unmute switch and volume control */
12548 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12549 const struct auto_pin_cfg *cfg)
12552 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12553 hda_nid_t nid_v, nid_s;
12556 for (i = 0; i < cfg->line_outs; i++) {
12557 if (!spec->multiout.dac_nids[i])
12559 nid_v = alc861vd_idx_to_mixer_vol(
12561 spec->multiout.dac_nids[i]));
12562 nid_s = alc861vd_idx_to_mixer_switch(
12564 spec->multiout.dac_nids[i]));
12568 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12569 "Center Playback Volume",
12570 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12574 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12575 "LFE Playback Volume",
12576 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12580 err = add_control(spec, ALC_CTL_BIND_MUTE,
12581 "Center Playback Switch",
12582 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12586 err = add_control(spec, ALC_CTL_BIND_MUTE,
12587 "LFE Playback Switch",
12588 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12593 sprintf(name, "%s Playback Volume", chname[i]);
12594 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12595 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
12599 sprintf(name, "%s Playback Switch", chname[i]);
12600 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12601 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
12610 /* add playback controls for speaker and HP outputs */
12611 /* Based on ALC880 version. But ALC861VD has separate,
12612 * different NIDs for mute/unmute switch and volume control */
12613 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
12614 hda_nid_t pin, const char *pfx)
12616 hda_nid_t nid_v, nid_s;
12623 if (alc880_is_fixed_pin(pin)) {
12624 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12625 /* specify the DAC as the extra output */
12626 if (!spec->multiout.hp_nid)
12627 spec->multiout.hp_nid = nid_v;
12629 spec->multiout.extra_out_nid[0] = nid_v;
12630 /* control HP volume/switch on the output mixer amp */
12631 nid_v = alc861vd_idx_to_mixer_vol(
12632 alc880_fixed_pin_idx(pin));
12633 nid_s = alc861vd_idx_to_mixer_switch(
12634 alc880_fixed_pin_idx(pin));
12636 sprintf(name, "%s Playback Volume", pfx);
12637 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12638 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
12641 sprintf(name, "%s Playback Switch", pfx);
12642 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12643 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
12646 } else if (alc880_is_multi_pin(pin)) {
12647 /* set manual connection */
12648 /* we have only a switch on HP-out PIN */
12649 sprintf(name, "%s Playback Switch", pfx);
12650 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12651 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12658 /* parse the BIOS configuration and set up the alc_spec
12659 * return 1 if successful, 0 if the proper config is not found,
12660 * or a negative error code
12661 * Based on ALC880 version - had to change it to override
12662 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
12663 static int alc861vd_parse_auto_config(struct hda_codec *codec)
12665 struct alc_spec *spec = codec->spec;
12667 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
12669 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12673 if (!spec->autocfg.line_outs)
12674 return 0; /* can't find valid BIOS pin config */
12676 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12679 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
12682 err = alc861vd_auto_create_extra_out(spec,
12683 spec->autocfg.speaker_pins[0],
12687 err = alc861vd_auto_create_extra_out(spec,
12688 spec->autocfg.hp_pins[0],
12692 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
12696 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12698 if (spec->autocfg.dig_out_pin)
12699 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
12701 if (spec->kctl_alloc)
12702 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12704 spec->init_verbs[spec->num_init_verbs++]
12705 = alc861vd_volume_init_verbs;
12707 spec->num_mux_defs = 1;
12708 spec->input_mux = &spec->private_imux;
12710 err = alc_auto_add_mic_boost(codec);
12717 /* additional initialization for auto-configuration model */
12718 static void alc861vd_auto_init(struct hda_codec *codec)
12720 alc861vd_auto_init_multi_out(codec);
12721 alc861vd_auto_init_hp_out(codec);
12722 alc861vd_auto_init_analog_input(codec);
12725 static int patch_alc861vd(struct hda_codec *codec)
12727 struct alc_spec *spec;
12728 int err, board_config;
12730 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12734 codec->spec = spec;
12736 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
12740 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
12741 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
12742 "ALC861VD, trying auto-probe from BIOS...\n");
12743 board_config = ALC861VD_AUTO;
12746 if (board_config == ALC861VD_AUTO) {
12747 /* automatic parse from the BIOS config */
12748 err = alc861vd_parse_auto_config(codec);
12754 "hda_codec: Cannot set up configuration "
12755 "from BIOS. Using base mode...\n");
12756 board_config = ALC861VD_3ST;
12760 if (board_config != ALC861VD_AUTO)
12761 setup_preset(spec, &alc861vd_presets[board_config]);
12763 spec->stream_name_analog = "ALC861VD Analog";
12764 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
12765 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
12767 spec->stream_name_digital = "ALC861VD Digital";
12768 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
12769 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
12771 spec->adc_nids = alc861vd_adc_nids;
12772 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
12774 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
12775 spec->num_mixers++;
12777 spec->vmaster_nid = 0x02;
12779 codec->patch_ops = alc_patch_ops;
12781 if (board_config == ALC861VD_AUTO)
12782 spec->init_hook = alc861vd_auto_init;
12783 #ifdef CONFIG_SND_HDA_POWER_SAVE
12784 if (!spec->loopback.amplist)
12785 spec->loopback.amplist = alc861vd_loopbacks;
12794 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
12795 * configuration. Each pin widget can choose any input DACs and a mixer.
12796 * Each ADC is connected from a mixer of all inputs. This makes possible
12797 * 6-channel independent captures.
12799 * In addition, an independent DAC for the multi-playback (not used in this
12802 #define ALC662_DIGOUT_NID 0x06
12803 #define ALC662_DIGIN_NID 0x0a
12805 static hda_nid_t alc662_dac_nids[4] = {
12806 /* front, rear, clfe, rear_surr */
12810 static hda_nid_t alc662_adc_nids[1] = {
12815 /* FIXME: should be a matrix-type input source selection */
12817 static struct hda_input_mux alc662_capture_source = {
12821 { "Front Mic", 0x1 },
12827 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
12835 static struct hda_input_mux alc662_eeepc_capture_source = {
12843 #define alc662_mux_enum_info alc_mux_enum_info
12844 #define alc662_mux_enum_get alc_mux_enum_get
12846 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
12847 struct snd_ctl_elem_value *ucontrol)
12849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12850 struct alc_spec *spec = codec->spec;
12851 const struct hda_input_mux *imux = spec->input_mux;
12852 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
12853 static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
12854 hda_nid_t nid = capture_mixers[adc_idx];
12855 unsigned int *cur_val = &spec->cur_mux[adc_idx];
12856 unsigned int i, idx;
12858 idx = ucontrol->value.enumerated.item[0];
12859 if (idx >= imux->num_items)
12860 idx = imux->num_items - 1;
12861 if (*cur_val == idx)
12863 for (i = 0; i < imux->num_items; i++) {
12864 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
12865 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
12866 imux->items[i].index,
12875 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
12882 static struct hda_verb alc662_3ST_ch2_init[] = {
12883 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
12884 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12885 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
12886 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
12893 static struct hda_verb alc662_3ST_ch6_init[] = {
12894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12896 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
12897 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12898 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12899 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
12903 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
12904 { 2, alc662_3ST_ch2_init },
12905 { 6, alc662_3ST_ch6_init },
12911 static struct hda_verb alc662_sixstack_ch6_init[] = {
12912 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12913 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12914 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12921 static struct hda_verb alc662_sixstack_ch8_init[] = {
12922 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12923 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12924 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12928 static struct hda_channel_mode alc662_5stack_modes[2] = {
12929 { 2, alc662_sixstack_ch6_init },
12930 { 6, alc662_sixstack_ch8_init },
12933 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12934 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12937 static struct snd_kcontrol_new alc662_base_mixer[] = {
12938 /* output mixer control */
12939 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12940 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
12941 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12942 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12949 /*Input mixer control */
12950 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
12951 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
12952 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
12953 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
12954 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
12955 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
12956 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
12957 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
12961 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
12962 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12963 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12965 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12966 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12971 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12972 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12973 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12974 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12978 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
12979 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12980 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
12981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12982 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12985 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12986 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12988 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12989 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12990 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12991 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12994 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12995 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12996 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12997 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13001 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13002 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13003 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13004 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13005 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13006 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13009 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13014 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13015 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13017 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13018 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13020 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13021 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13022 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13024 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13025 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13026 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13030 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13031 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13032 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13033 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13034 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13035 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13036 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13037 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13038 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13039 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13040 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13041 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13042 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13048 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13050 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13051 .name = "Channel Mode",
13052 .info = alc_ch_mode_info,
13053 .get = alc_ch_mode_get,
13054 .put = alc_ch_mode_put,
13059 static struct hda_verb alc662_init_verbs[] = {
13060 /* ADC: mute amp left and right */
13061 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13062 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13063 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13065 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13066 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13071 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13072 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13073 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13074 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13075 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13076 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13078 /* Front Pin: output 0 (0x0c) */
13079 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13080 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13082 /* Rear Pin: output 1 (0x0d) */
13083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13086 /* CLFE Pin: output 2 (0x0e) */
13087 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13088 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13090 /* Mic (rear) pin: input vref at 80% */
13091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13093 /* Front Mic pin: input vref at 80% */
13094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13095 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13096 /* Line In pin: input */
13097 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13098 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13099 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13102 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13103 /* CD pin widget for input */
13104 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13106 /* FIXME: use matrix-type input source selection */
13107 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13109 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13110 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13111 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13112 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13114 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13121 static struct hda_verb alc662_sue_init_verbs[] = {
13122 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13123 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13127 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13128 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13129 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13133 /* Set Unsolicited Event*/
13134 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13135 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13136 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13141 * generic initialization of ADC, input mixers and output mixers
13143 static struct hda_verb alc662_auto_init_verbs[] = {
13145 * Unmute ADC and set the default input to mic-in
13147 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13148 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13150 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13152 * Note: PASD motherboards uses the Line In 2 as the input for front
13153 * panel mic (mic 2)
13155 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13163 * Set up output mixers (0x0c - 0x0f)
13165 /* set vol=0 to output mixers */
13166 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13167 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13168 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13170 /* set up input amps for analog loopback */
13171 /* Amp Indices: DAC = 0, mixer = 1 */
13172 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13173 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13174 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13175 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13176 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13177 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13180 /* FIXME: use matrix-type input source selection */
13181 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13184 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13188 /* capture mixer elements */
13189 static struct snd_kcontrol_new alc662_capture_mixer[] = {
13190 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13191 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13194 /* The multiple "Capture Source" controls confuse alsamixer
13195 * So call somewhat different..
13197 /* .name = "Capture Source", */
13198 .name = "Input Source",
13200 .info = alc662_mux_enum_info,
13201 .get = alc662_mux_enum_get,
13202 .put = alc662_mux_enum_put,
13207 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13209 unsigned int present;
13210 unsigned char bits;
13212 present = snd_hda_codec_read(codec, 0x14, 0,
13213 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13214 bits = present ? HDA_AMP_MUTE : 0;
13215 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13216 HDA_AMP_MUTE, bits);
13219 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13221 unsigned int present;
13222 unsigned char bits;
13224 present = snd_hda_codec_read(codec, 0x1b, 0,
13225 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13226 bits = present ? HDA_AMP_MUTE : 0;
13227 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13228 HDA_AMP_MUTE, bits);
13229 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13230 HDA_AMP_MUTE, bits);
13233 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13236 if ((res >> 26) == ALC880_HP_EVENT)
13237 alc662_lenovo_101e_all_automute(codec);
13238 if ((res >> 26) == ALC880_FRONT_EVENT)
13239 alc662_lenovo_101e_ispeaker_automute(codec);
13242 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13244 unsigned int present;
13246 present = snd_hda_codec_read(codec, 0x18, 0,
13247 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13248 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13249 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13250 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13251 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13252 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13253 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13254 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13255 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13258 /* unsolicited event for HP jack sensing */
13259 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13262 if ((res >> 26) == ALC880_HP_EVENT)
13263 alc262_hippo1_automute( codec );
13265 if ((res >> 26) == ALC880_MIC_EVENT)
13266 alc662_eeepc_mic_automute(codec);
13269 static void alc662_eeepc_inithook(struct hda_codec *codec)
13271 alc262_hippo1_automute( codec );
13272 alc662_eeepc_mic_automute(codec);
13275 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13278 unsigned int present;
13280 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13281 present = snd_hda_codec_read(codec, 0x14, 0,
13282 AC_VERB_GET_PIN_SENSE, 0);
13283 present = (present & 0x80000000) != 0;
13285 /* mute internal speaker */
13286 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13287 HDA_AMP_MUTE, HDA_AMP_MUTE);
13289 /* unmute internal speaker if necessary */
13290 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13291 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13292 HDA_AMP_MUTE, mute);
13296 /* unsolicited event for HP jack sensing */
13297 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13300 if ((res >> 26) == ALC880_HP_EVENT)
13301 alc662_eeepc_ep20_automute(codec);
13304 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13306 alc662_eeepc_ep20_automute(codec);
13309 #ifdef CONFIG_SND_HDA_POWER_SAVE
13310 #define alc662_loopbacks alc880_loopbacks
13314 /* pcm configuration: identiacal with ALC880 */
13315 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
13316 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
13317 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
13318 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
13321 * configuration and preset
13323 static const char *alc662_models[ALC662_MODEL_LAST] = {
13324 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13325 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13326 [ALC662_3ST_6ch] = "3stack-6ch",
13327 [ALC662_5ST_DIG] = "6stack-dig",
13328 [ALC662_LENOVO_101E] = "lenovo-101e",
13329 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
13330 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
13331 [ALC662_AUTO] = "auto",
13334 static struct snd_pci_quirk alc662_cfg_tbl[] = {
13335 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
13336 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
13337 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
13341 static struct alc_config_preset alc662_presets[] = {
13342 [ALC662_3ST_2ch_DIG] = {
13343 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
13344 .init_verbs = { alc662_init_verbs },
13345 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13346 .dac_nids = alc662_dac_nids,
13347 .dig_out_nid = ALC662_DIGOUT_NID,
13348 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13349 .adc_nids = alc662_adc_nids,
13350 .dig_in_nid = ALC662_DIGIN_NID,
13351 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13352 .channel_mode = alc662_3ST_2ch_modes,
13353 .input_mux = &alc662_capture_source,
13355 [ALC662_3ST_6ch_DIG] = {
13356 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13357 alc662_capture_mixer },
13358 .init_verbs = { alc662_init_verbs },
13359 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13360 .dac_nids = alc662_dac_nids,
13361 .dig_out_nid = ALC662_DIGOUT_NID,
13362 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13363 .adc_nids = alc662_adc_nids,
13364 .dig_in_nid = ALC662_DIGIN_NID,
13365 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13366 .channel_mode = alc662_3ST_6ch_modes,
13368 .input_mux = &alc662_capture_source,
13370 [ALC662_3ST_6ch] = {
13371 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13372 alc662_capture_mixer },
13373 .init_verbs = { alc662_init_verbs },
13374 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13375 .dac_nids = alc662_dac_nids,
13376 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13377 .adc_nids = alc662_adc_nids,
13378 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13379 .channel_mode = alc662_3ST_6ch_modes,
13381 .input_mux = &alc662_capture_source,
13383 [ALC662_5ST_DIG] = {
13384 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13385 alc662_capture_mixer },
13386 .init_verbs = { alc662_init_verbs },
13387 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13388 .dac_nids = alc662_dac_nids,
13389 .dig_out_nid = ALC662_DIGOUT_NID,
13390 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13391 .adc_nids = alc662_adc_nids,
13392 .dig_in_nid = ALC662_DIGIN_NID,
13393 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13394 .channel_mode = alc662_5stack_modes,
13395 .input_mux = &alc662_capture_source,
13397 [ALC662_LENOVO_101E] = {
13398 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
13399 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13400 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13401 .dac_nids = alc662_dac_nids,
13402 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13403 .adc_nids = alc662_adc_nids,
13404 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13405 .channel_mode = alc662_3ST_2ch_modes,
13406 .input_mux = &alc662_lenovo_101e_capture_source,
13407 .unsol_event = alc662_lenovo_101e_unsol_event,
13408 .init_hook = alc662_lenovo_101e_all_automute,
13410 [ALC662_ASUS_EEEPC_P701] = {
13411 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13412 .init_verbs = { alc662_init_verbs,
13413 alc662_eeepc_sue_init_verbs },
13414 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13415 .dac_nids = alc662_dac_nids,
13416 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
13417 .adc_nids = alc662_adc_nids,
13418 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13419 .channel_mode = alc662_3ST_2ch_modes,
13420 .input_mux = &alc662_eeepc_capture_source,
13421 .unsol_event = alc662_eeepc_unsol_event,
13422 .init_hook = alc662_eeepc_inithook,
13424 [ALC662_ASUS_EEEPC_EP20] = {
13425 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13426 alc662_chmode_mixer },
13427 .init_verbs = { alc662_init_verbs,
13428 alc662_eeepc_ep20_sue_init_verbs },
13429 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13430 .dac_nids = alc662_dac_nids,
13431 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
13432 .adc_nids = alc662_adc_nids,
13433 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13434 .channel_mode = alc662_3ST_6ch_modes,
13435 .input_mux = &alc662_lenovo_101e_capture_source,
13436 .unsol_event = alc662_eeepc_ep20_unsol_event,
13437 .init_hook = alc662_eeepc_ep20_inithook,
13444 * BIOS auto configuration
13447 /* add playback controls from the parsed DAC table */
13448 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13449 const struct auto_pin_cfg *cfg)
13452 static const char *chname[4] = {
13453 "Front", "Surround", NULL /*CLFE*/, "Side"
13458 for (i = 0; i < cfg->line_outs; i++) {
13459 if (!spec->multiout.dac_nids[i])
13461 nid = alc880_idx_to_dac(i);
13464 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13465 "Center Playback Volume",
13466 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13470 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13471 "LFE Playback Volume",
13472 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13476 err = add_control(spec, ALC_CTL_BIND_MUTE,
13477 "Center Playback Switch",
13478 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13482 err = add_control(spec, ALC_CTL_BIND_MUTE,
13483 "LFE Playback Switch",
13484 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13489 sprintf(name, "%s Playback Volume", chname[i]);
13490 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13491 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13495 sprintf(name, "%s Playback Switch", chname[i]);
13496 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13497 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13506 /* add playback controls for speaker and HP outputs */
13507 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13517 if (alc880_is_fixed_pin(pin)) {
13518 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13519 /* printk("DAC nid=%x\n",nid); */
13520 /* specify the DAC as the extra output */
13521 if (!spec->multiout.hp_nid)
13522 spec->multiout.hp_nid = nid;
13524 spec->multiout.extra_out_nid[0] = nid;
13525 /* control HP volume/switch on the output mixer amp */
13526 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13527 sprintf(name, "%s Playback Volume", pfx);
13528 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13529 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13532 sprintf(name, "%s Playback Switch", pfx);
13533 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13534 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13537 } else if (alc880_is_multi_pin(pin)) {
13538 /* set manual connection */
13539 /* we have only a switch on HP-out PIN */
13540 sprintf(name, "%s Playback Switch", pfx);
13541 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13542 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13549 /* create playback/capture controls for input pins */
13550 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13551 const struct auto_pin_cfg *cfg)
13553 struct hda_input_mux *imux = &spec->private_imux;
13556 for (i = 0; i < AUTO_PIN_LAST; i++) {
13557 if (alc880_is_input_pin(cfg->input_pins[i])) {
13558 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13559 err = new_analog_input(spec, cfg->input_pins[i],
13560 auto_pin_cfg_labels[i],
13564 imux->items[imux->num_items].label =
13565 auto_pin_cfg_labels[i];
13566 imux->items[imux->num_items].index =
13567 alc880_input_pin_idx(cfg->input_pins[i]);
13574 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13575 hda_nid_t nid, int pin_type,
13578 /* set as output */
13579 snd_hda_codec_write(codec, nid, 0,
13580 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
13581 snd_hda_codec_write(codec, nid, 0,
13582 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
13583 /* need the manual connection? */
13584 if (alc880_is_multi_pin(nid)) {
13585 struct alc_spec *spec = codec->spec;
13586 int idx = alc880_multi_pin_idx(nid);
13587 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13588 AC_VERB_SET_CONNECT_SEL,
13589 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13593 static void alc662_auto_init_multi_out(struct hda_codec *codec)
13595 struct alc_spec *spec = codec->spec;
13598 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13599 for (i = 0; i <= HDA_SIDE; i++) {
13600 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13601 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13603 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13608 static void alc662_auto_init_hp_out(struct hda_codec *codec)
13610 struct alc_spec *spec = codec->spec;
13613 pin = spec->autocfg.hp_pins[0];
13614 if (pin) /* connect to front */
13616 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13619 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13620 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13622 static void alc662_auto_init_analog_input(struct hda_codec *codec)
13624 struct alc_spec *spec = codec->spec;
13627 for (i = 0; i < AUTO_PIN_LAST; i++) {
13628 hda_nid_t nid = spec->autocfg.input_pins[i];
13629 if (alc662_is_input_pin(nid)) {
13630 snd_hda_codec_write(codec, nid, 0,
13631 AC_VERB_SET_PIN_WIDGET_CONTROL,
13632 (i <= AUTO_PIN_FRONT_MIC ?
13633 PIN_VREF80 : PIN_IN));
13634 if (nid != ALC662_PIN_CD_NID)
13635 snd_hda_codec_write(codec, nid, 0,
13636 AC_VERB_SET_AMP_GAIN_MUTE,
13642 static int alc662_parse_auto_config(struct hda_codec *codec)
13644 struct alc_spec *spec = codec->spec;
13646 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
13648 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13652 if (!spec->autocfg.line_outs)
13653 return 0; /* can't find valid BIOS pin config */
13655 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13658 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
13661 err = alc662_auto_create_extra_out(spec,
13662 spec->autocfg.speaker_pins[0],
13666 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
13670 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
13674 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13676 if (spec->autocfg.dig_out_pin)
13677 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
13679 if (spec->kctl_alloc)
13680 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13682 spec->num_mux_defs = 1;
13683 spec->input_mux = &spec->private_imux;
13685 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
13686 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
13687 spec->num_mixers++;
13691 /* additional initialization for auto-configuration model */
13692 static void alc662_auto_init(struct hda_codec *codec)
13694 alc662_auto_init_multi_out(codec);
13695 alc662_auto_init_hp_out(codec);
13696 alc662_auto_init_analog_input(codec);
13699 static int patch_alc662(struct hda_codec *codec)
13701 struct alc_spec *spec;
13702 int err, board_config;
13704 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13708 codec->spec = spec;
13710 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
13713 if (board_config < 0) {
13714 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
13715 "trying auto-probe from BIOS...\n");
13716 board_config = ALC662_AUTO;
13719 if (board_config == ALC662_AUTO) {
13720 /* automatic parse from the BIOS config */
13721 err = alc662_parse_auto_config(codec);
13727 "hda_codec: Cannot set up configuration "
13728 "from BIOS. Using base mode...\n");
13729 board_config = ALC662_3ST_2ch_DIG;
13733 if (board_config != ALC662_AUTO)
13734 setup_preset(spec, &alc662_presets[board_config]);
13736 spec->stream_name_analog = "ALC662 Analog";
13737 spec->stream_analog_playback = &alc662_pcm_analog_playback;
13738 spec->stream_analog_capture = &alc662_pcm_analog_capture;
13740 spec->stream_name_digital = "ALC662 Digital";
13741 spec->stream_digital_playback = &alc662_pcm_digital_playback;
13742 spec->stream_digital_capture = &alc662_pcm_digital_capture;
13744 if (!spec->adc_nids && spec->input_mux) {
13745 spec->adc_nids = alc662_adc_nids;
13746 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
13749 spec->vmaster_nid = 0x02;
13751 codec->patch_ops = alc_patch_ops;
13752 if (board_config == ALC662_AUTO)
13753 spec->init_hook = alc662_auto_init;
13754 #ifdef CONFIG_SND_HDA_POWER_SAVE
13755 if (!spec->loopback.amplist)
13756 spec->loopback.amplist = alc662_loopbacks;
13765 struct hda_codec_preset snd_hda_preset_realtek[] = {
13766 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
13767 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
13768 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
13769 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
13770 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
13771 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
13772 .patch = patch_alc861 },
13773 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
13774 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
13775 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
13776 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
13777 .patch = patch_alc883 },
13778 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
13779 .patch = patch_alc662 },
13780 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
13781 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
13782 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
13783 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
13784 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
13785 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
13786 {} /* terminator */