2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_patch.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST /* last tag */
80 #ifdef CONFIG_SND_DEBUG
84 ALC260_MODEL_LAST /* last tag */
94 ALC262_HP_BPC_D7000_WL,
95 ALC262_HP_BPC_D7000_WF,
104 ALC262_MODEL_LAST /* last tag */
115 #ifdef CONFIG_SND_DEBUG
119 ALC268_MODEL_LAST /* last tag */
126 ALC269_MODEL_LAST /* last tag */
143 /* ALC861-VD models */
164 ALC662_ASUS_EEEPC_P701,
165 ALC662_ASUS_EEEPC_EP20,
193 ALC883_TARGA_2ch_DIG,
199 ALC883_LENOVO_101E_2ch,
200 ALC883_LENOVO_NB0763,
201 ALC888_LENOVO_MS7195_DIG,
207 ALC883_FUJITSU_PI2515,
213 #define GPIO_MASK 0x03
216 /* codec parameterization */
217 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
218 unsigned int num_mixers;
220 const struct hda_verb *init_verbs[5]; /* initialization verbs
224 unsigned int num_init_verbs;
226 char *stream_name_analog; /* analog PCM stream */
227 struct hda_pcm_stream *stream_analog_playback;
228 struct hda_pcm_stream *stream_analog_capture;
229 struct hda_pcm_stream *stream_analog_alt_playback;
230 struct hda_pcm_stream *stream_analog_alt_capture;
232 char *stream_name_digital; /* digital PCM stream */
233 struct hda_pcm_stream *stream_digital_playback;
234 struct hda_pcm_stream *stream_digital_capture;
237 struct hda_multi_out multiout; /* playback set-up
238 * max_channels, dacs must be set
239 * dig_out_nid and hp_nid are optional
241 hda_nid_t alt_dac_nid;
244 unsigned int num_adc_nids;
246 hda_nid_t *capsrc_nids;
247 hda_nid_t dig_in_nid; /* digital-in NID; optional */
250 unsigned int num_mux_defs;
251 const struct hda_input_mux *input_mux;
252 unsigned int cur_mux[3];
255 const struct hda_channel_mode *channel_mode;
256 int num_channel_mode;
259 /* PCM information */
260 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
262 /* dynamic controls, init_verbs and input_mux */
263 struct auto_pin_cfg autocfg;
264 unsigned int num_kctl_alloc, num_kctl_used;
265 struct snd_kcontrol_new *kctl_alloc;
266 struct hda_input_mux private_imux;
267 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
270 void (*init_hook)(struct hda_codec *codec);
271 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
273 /* for pin sensing */
274 unsigned int sense_updated: 1;
275 unsigned int jack_present: 1;
276 unsigned int master_sw: 1;
278 /* for virtual master */
279 hda_nid_t vmaster_nid;
280 #ifdef CONFIG_SND_HDA_POWER_SAVE
281 struct hda_loopback_check loopback;
286 * configuration template - to be copied to the spec instance
288 struct alc_config_preset {
289 struct snd_kcontrol_new *mixers[5]; /* should be identical size
292 const struct hda_verb *init_verbs[5];
293 unsigned int num_dacs;
295 hda_nid_t dig_out_nid; /* optional */
296 hda_nid_t hp_nid; /* optional */
297 unsigned int num_adc_nids;
299 hda_nid_t *capsrc_nids;
300 hda_nid_t dig_in_nid;
301 unsigned int num_channel_mode;
302 const struct hda_channel_mode *channel_mode;
304 unsigned int num_mux_defs;
305 const struct hda_input_mux *input_mux;
306 void (*unsol_event)(struct hda_codec *, unsigned int);
307 void (*init_hook)(struct hda_codec *);
308 #ifdef CONFIG_SND_HDA_POWER_SAVE
309 struct hda_amp_list *loopbacks;
317 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
318 struct snd_ctl_elem_info *uinfo)
320 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
321 struct alc_spec *spec = codec->spec;
322 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
323 if (mux_idx >= spec->num_mux_defs)
325 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
328 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
329 struct snd_ctl_elem_value *ucontrol)
331 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
332 struct alc_spec *spec = codec->spec;
333 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
335 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
339 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
340 struct snd_ctl_elem_value *ucontrol)
342 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
343 struct alc_spec *spec = codec->spec;
344 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
345 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
346 hda_nid_t nid = spec->capsrc_nids ?
347 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
348 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
349 nid, &spec->cur_mux[adc_idx]);
354 * channel mode setting
356 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
357 struct snd_ctl_elem_info *uinfo)
359 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
360 struct alc_spec *spec = codec->spec;
361 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
362 spec->num_channel_mode);
365 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
368 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct alc_spec *spec = codec->spec;
370 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
371 spec->num_channel_mode,
372 spec->multiout.max_channels);
375 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
378 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
379 struct alc_spec *spec = codec->spec;
380 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
381 spec->num_channel_mode,
382 &spec->multiout.max_channels);
383 if (err >= 0 && spec->need_dac_fix)
384 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
389 * Control the mode of pin widget settings via the mixer. "pc" is used
390 * instead of "%" to avoid consequences of accidently treating the % as
391 * being part of a format specifier. Maximum allowed length of a value is
392 * 63 characters plus NULL terminator.
394 * Note: some retasking pin complexes seem to ignore requests for input
395 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
396 * are requested. Therefore order this list so that this behaviour will not
397 * cause problems when mixer clients move through the enum sequentially.
398 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
401 static char *alc_pin_mode_names[] = {
402 "Mic 50pc bias", "Mic 80pc bias",
403 "Line in", "Line out", "Headphone out",
405 static unsigned char alc_pin_mode_values[] = {
406 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
408 /* The control can present all 5 options, or it can limit the options based
409 * in the pin being assumed to be exclusively an input or an output pin. In
410 * addition, "input" pins may or may not process the mic bias option
411 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
412 * accept requests for bias as of chip versions up to March 2006) and/or
413 * wiring in the computer.
415 #define ALC_PIN_DIR_IN 0x00
416 #define ALC_PIN_DIR_OUT 0x01
417 #define ALC_PIN_DIR_INOUT 0x02
418 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
419 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
421 /* Info about the pin modes supported by the different pin direction modes.
422 * For each direction the minimum and maximum values are given.
424 static signed char alc_pin_mode_dir_info[5][2] = {
425 { 0, 2 }, /* ALC_PIN_DIR_IN */
426 { 3, 4 }, /* ALC_PIN_DIR_OUT */
427 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
428 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
429 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
431 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
432 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
433 #define alc_pin_mode_n_items(_dir) \
434 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
436 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
437 struct snd_ctl_elem_info *uinfo)
439 unsigned int item_num = uinfo->value.enumerated.item;
440 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
442 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
444 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
446 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
447 item_num = alc_pin_mode_min(dir);
448 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
452 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 hda_nid_t nid = kcontrol->private_value & 0xffff;
458 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
459 long *valp = ucontrol->value.integer.value;
460 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
461 AC_VERB_GET_PIN_WIDGET_CONTROL,
464 /* Find enumerated value for current pinctl setting */
465 i = alc_pin_mode_min(dir);
466 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
468 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
472 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477 hda_nid_t nid = kcontrol->private_value & 0xffff;
478 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
479 long val = *ucontrol->value.integer.value;
480 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
481 AC_VERB_GET_PIN_WIDGET_CONTROL,
484 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
485 val = alc_pin_mode_min(dir);
487 change = pinctl != alc_pin_mode_values[val];
489 /* Set pin mode to that requested */
490 snd_hda_codec_write_cache(codec, nid, 0,
491 AC_VERB_SET_PIN_WIDGET_CONTROL,
492 alc_pin_mode_values[val]);
494 /* Also enable the retasking pin's input/output as required
495 * for the requested pin mode. Enum values of 2 or less are
498 * Dynamically switching the input/output buffers probably
499 * reduces noise slightly (particularly on input) so we'll
500 * do it. However, having both input and output buffers
501 * enabled simultaneously doesn't seem to be problematic if
502 * this turns out to be necessary in the future.
505 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
506 HDA_AMP_MUTE, HDA_AMP_MUTE);
507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
510 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
511 HDA_AMP_MUTE, HDA_AMP_MUTE);
512 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
519 #define ALC_PIN_MODE(xname, nid, dir) \
520 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
521 .info = alc_pin_mode_info, \
522 .get = alc_pin_mode_get, \
523 .put = alc_pin_mode_put, \
524 .private_value = nid | (dir<<16) }
526 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
527 * together using a mask with more than one bit set. This control is
528 * currently used only by the ALC260 test model. At this stage they are not
529 * needed for any "production" models.
531 #ifdef CONFIG_SND_DEBUG
532 #define alc_gpio_data_info snd_ctl_boolean_mono_info
534 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
535 struct snd_ctl_elem_value *ucontrol)
537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538 hda_nid_t nid = kcontrol->private_value & 0xffff;
539 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
540 long *valp = ucontrol->value.integer.value;
541 unsigned int val = snd_hda_codec_read(codec, nid, 0,
542 AC_VERB_GET_GPIO_DATA, 0x00);
544 *valp = (val & mask) != 0;
547 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
552 hda_nid_t nid = kcontrol->private_value & 0xffff;
553 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
554 long val = *ucontrol->value.integer.value;
555 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
556 AC_VERB_GET_GPIO_DATA,
559 /* Set/unset the masked GPIO bit(s) as needed */
560 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
565 snd_hda_codec_write_cache(codec, nid, 0,
566 AC_VERB_SET_GPIO_DATA, gpio_data);
570 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
571 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
572 .info = alc_gpio_data_info, \
573 .get = alc_gpio_data_get, \
574 .put = alc_gpio_data_put, \
575 .private_value = nid | (mask<<16) }
576 #endif /* CONFIG_SND_DEBUG */
578 /* A switch control to allow the enabling of the digital IO pins on the
579 * ALC260. This is incredibly simplistic; the intention of this control is
580 * to provide something in the test model allowing digital outputs to be
581 * identified if present. If models are found which can utilise these
582 * outputs a more complete mixer control can be devised for those models if
585 #ifdef CONFIG_SND_DEBUG
586 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
588 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
589 struct snd_ctl_elem_value *ucontrol)
591 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
592 hda_nid_t nid = kcontrol->private_value & 0xffff;
593 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
594 long *valp = ucontrol->value.integer.value;
595 unsigned int val = snd_hda_codec_read(codec, nid, 0,
596 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
598 *valp = (val & mask) != 0;
601 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
602 struct snd_ctl_elem_value *ucontrol)
605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
606 hda_nid_t nid = kcontrol->private_value & 0xffff;
607 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
608 long val = *ucontrol->value.integer.value;
609 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
610 AC_VERB_GET_DIGI_CONVERT_1,
613 /* Set/unset the masked control bit(s) as needed */
614 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
619 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
624 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
625 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
626 .info = alc_spdif_ctrl_info, \
627 .get = alc_spdif_ctrl_get, \
628 .put = alc_spdif_ctrl_put, \
629 .private_value = nid | (mask<<16) }
630 #endif /* CONFIG_SND_DEBUG */
632 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
633 * Again, this is only used in the ALC26x test models to help identify when
634 * the EAPD line must be asserted for features to work.
636 #ifdef CONFIG_SND_DEBUG
637 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
639 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
643 hda_nid_t nid = kcontrol->private_value & 0xffff;
644 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
645 long *valp = ucontrol->value.integer.value;
646 unsigned int val = snd_hda_codec_read(codec, nid, 0,
647 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
649 *valp = (val & mask) != 0;
653 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
654 struct snd_ctl_elem_value *ucontrol)
657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
658 hda_nid_t nid = kcontrol->private_value & 0xffff;
659 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
660 long val = *ucontrol->value.integer.value;
661 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
662 AC_VERB_GET_EAPD_BTLENABLE,
665 /* Set/unset the masked control bit(s) as needed */
666 change = (!val ? 0 : mask) != (ctrl_data & mask);
671 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
677 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
678 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
679 .info = alc_eapd_ctrl_info, \
680 .get = alc_eapd_ctrl_get, \
681 .put = alc_eapd_ctrl_put, \
682 .private_value = nid | (mask<<16) }
683 #endif /* CONFIG_SND_DEBUG */
686 * set up from the preset table
688 static void setup_preset(struct alc_spec *spec,
689 const struct alc_config_preset *preset)
693 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
694 spec->mixers[spec->num_mixers++] = preset->mixers[i];
695 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
697 spec->init_verbs[spec->num_init_verbs++] =
698 preset->init_verbs[i];
700 spec->channel_mode = preset->channel_mode;
701 spec->num_channel_mode = preset->num_channel_mode;
702 spec->need_dac_fix = preset->need_dac_fix;
704 spec->multiout.max_channels = spec->channel_mode[0].channels;
706 spec->multiout.num_dacs = preset->num_dacs;
707 spec->multiout.dac_nids = preset->dac_nids;
708 spec->multiout.dig_out_nid = preset->dig_out_nid;
709 spec->multiout.hp_nid = preset->hp_nid;
711 spec->num_mux_defs = preset->num_mux_defs;
712 if (!spec->num_mux_defs)
713 spec->num_mux_defs = 1;
714 spec->input_mux = preset->input_mux;
716 spec->num_adc_nids = preset->num_adc_nids;
717 spec->adc_nids = preset->adc_nids;
718 spec->capsrc_nids = preset->capsrc_nids;
719 spec->dig_in_nid = preset->dig_in_nid;
721 spec->unsol_event = preset->unsol_event;
722 spec->init_hook = preset->init_hook;
723 #ifdef CONFIG_SND_HDA_POWER_SAVE
724 spec->loopback.amplist = preset->loopbacks;
728 /* Enable GPIO mask and set output */
729 static struct hda_verb alc_gpio1_init_verbs[] = {
730 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
731 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
732 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
736 static struct hda_verb alc_gpio2_init_verbs[] = {
737 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
738 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
739 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
743 static struct hda_verb alc_gpio3_init_verbs[] = {
744 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
745 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
746 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
750 static void alc_sku_automute(struct hda_codec *codec)
752 struct alc_spec *spec = codec->spec;
753 unsigned int present;
754 unsigned int hp_nid = spec->autocfg.hp_pins[0];
755 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
757 /* need to execute and sync at first */
758 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
759 present = snd_hda_codec_read(codec, hp_nid, 0,
760 AC_VERB_GET_PIN_SENSE, 0);
761 spec->jack_present = (present & 0x80000000) != 0;
762 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
763 spec->jack_present ? 0 : PIN_OUT);
766 /* unsolicited event for HP jack sensing */
767 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
769 if (codec->vendor_id == 0x10ec0880)
773 if (res != ALC880_HP_EVENT)
776 alc_sku_automute(codec);
779 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
780 * 31 ~ 16 : Manufacture ID
782 * 7 ~ 0 : Assembly ID
783 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
785 static void alc_subsystem_id(struct hda_codec *codec,
786 unsigned int porta, unsigned int porte,
789 unsigned int ass, tmp, i;
791 struct alc_spec *spec = codec->spec;
793 ass = codec->subsystem_id & 0xffff;
794 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
798 * 31~30 : port conetcivity
801 * 19~16 : Check sum (15:1)
806 if (codec->vendor_id == 0x10ec0260)
808 ass = snd_hda_codec_read(codec, nid, 0,
809 AC_VERB_GET_CONFIG_DEFAULT, 0);
810 if (!(ass & 1) && !(ass & 0x100000))
812 if ((ass >> 30) != 1) /* no physical connection */
817 for (i = 1; i < 16; i++) {
821 if (((ass >> 16) & 0xf) != tmp)
827 * 2 : 0 --> Desktop, 1 --> Laptop
828 * 3~5 : External Amplifier control
831 tmp = (ass & 0x38) >> 3; /* external Amp control */
834 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
837 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
840 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
842 case 5: /* set EAPD output high */
843 switch (codec->vendor_id) {
845 snd_hda_codec_write(codec, 0x0f, 0,
846 AC_VERB_SET_EAPD_BTLENABLE, 2);
847 snd_hda_codec_write(codec, 0x10, 0,
848 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,
882 snd_hda_codec_write(codec, 0x20, 0,
883 AC_VERB_SET_COEF_INDEX, 7);
884 tmp = snd_hda_codec_read(codec, 0x20, 0,
885 AC_VERB_GET_PROC_COEF, 0);
886 snd_hda_codec_write(codec, 0x20, 0,
887 AC_VERB_SET_COEF_INDEX, 7);
888 snd_hda_codec_write(codec, 0x20, 0,
889 AC_VERB_SET_PROC_COEF,
894 snd_hda_codec_write(codec, 0x20, 0,
895 AC_VERB_SET_COEF_INDEX, 7);
896 tmp = snd_hda_codec_read(codec, 0x20, 0,
897 AC_VERB_GET_PROC_COEF, 0);
898 snd_hda_codec_write(codec, 0x20, 0,
899 AC_VERB_SET_COEF_INDEX, 7);
900 snd_hda_codec_write(codec, 0x20, 0,
901 AC_VERB_SET_PROC_COEF,
909 /* is laptop or Desktop and enable the function "Mute internal speaker
910 * when the external headphone out jack is plugged"
915 * 10~8 : Jack location
916 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
918 * 15 : 1 --> enable the function "Mute internal speaker
919 * when the external headphone out jack is plugged"
921 if (!spec->autocfg.speaker_pins[0]) {
922 if (spec->autocfg.line_out_pins[0])
923 spec->autocfg.speaker_pins[0] =
924 spec->autocfg.line_out_pins[0];
929 if (!spec->autocfg.hp_pins[0]) {
930 tmp = (ass >> 11) & 0x3; /* HP to chassis */
932 spec->autocfg.hp_pins[0] = porta;
934 spec->autocfg.hp_pins[0] = porte;
936 spec->autocfg.hp_pins[0] = portd;
941 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
942 AC_VERB_SET_UNSOLICITED_ENABLE,
943 AC_USRSP_EN | ALC880_HP_EVENT);
944 spec->unsol_event = alc_sku_unsol_event;
945 spec->init_hook = alc_sku_automute;
949 * Fix-up pin default configurations
957 static void alc_fix_pincfg(struct hda_codec *codec,
958 const struct snd_pci_quirk *quirk,
959 const struct alc_pincfg **pinfix)
961 const struct alc_pincfg *cfg;
963 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
967 cfg = pinfix[quirk->value];
968 for (; cfg->nid; cfg++) {
971 for (i = 0; i < 4; i++) {
972 snd_hda_codec_write(codec, cfg->nid, 0,
973 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
981 * ALC880 3-stack model
983 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
984 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
985 * F-Mic = 0x1b, HP = 0x19
988 static hda_nid_t alc880_dac_nids[4] = {
989 /* front, rear, clfe, rear_surr */
990 0x02, 0x05, 0x04, 0x03
993 static hda_nid_t alc880_adc_nids[3] = {
998 /* The datasheet says the node 0x07 is connected from inputs,
999 * but it shows zero connection in the real implementation on some devices.
1000 * Note: this is a 915GAV bug, fixed on 915GLV
1002 static hda_nid_t alc880_adc_nids_alt[2] = {
1007 #define ALC880_DIGOUT_NID 0x06
1008 #define ALC880_DIGIN_NID 0x0a
1010 static struct hda_input_mux alc880_capture_source = {
1014 { "Front Mic", 0x3 },
1020 /* channel source setting (2/6 channel selection for 3-stack) */
1022 static struct hda_verb alc880_threestack_ch2_init[] = {
1023 /* set line-in to input, mute it */
1024 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1025 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1026 /* set mic-in to input vref 80%, mute it */
1027 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1028 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1033 static struct hda_verb alc880_threestack_ch6_init[] = {
1034 /* set line-in to output, unmute it */
1035 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1036 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1037 /* set mic-in to output, unmute it */
1038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1043 static struct hda_channel_mode alc880_threestack_modes[2] = {
1044 { 2, alc880_threestack_ch2_init },
1045 { 6, alc880_threestack_ch6_init },
1048 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1049 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1050 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1051 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1052 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1053 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1054 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1055 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1056 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1063 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1064 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1065 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1066 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1070 .name = "Channel Mode",
1071 .info = alc_ch_mode_info,
1072 .get = alc_ch_mode_get,
1073 .put = alc_ch_mode_put,
1078 /* capture mixer elements */
1079 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1080 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1081 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1082 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1083 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1084 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1085 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1087 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1088 /* The multiple "Capture Source" controls confuse alsamixer
1089 * So call somewhat different..
1091 /* .name = "Capture Source", */
1092 .name = "Input Source",
1094 .info = alc_mux_enum_info,
1095 .get = alc_mux_enum_get,
1096 .put = alc_mux_enum_put,
1101 /* capture mixer elements (in case NID 0x07 not available) */
1102 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1103 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1104 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1105 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1106 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1109 /* The multiple "Capture Source" controls confuse alsamixer
1110 * So call somewhat different..
1112 /* .name = "Capture Source", */
1113 .name = "Input Source",
1115 .info = alc_mux_enum_info,
1116 .get = alc_mux_enum_get,
1117 .put = alc_mux_enum_put,
1125 * ALC880 5-stack model
1127 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1129 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1130 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1133 /* additional mixers to alc880_three_stack_mixer */
1134 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1135 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1136 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1140 /* channel source setting (6/8 channel selection for 5-stack) */
1142 static struct hda_verb alc880_fivestack_ch6_init[] = {
1143 /* set line-in to input, mute it */
1144 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1145 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1150 static struct hda_verb alc880_fivestack_ch8_init[] = {
1151 /* set line-in to output, unmute it */
1152 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1153 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1157 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1158 { 6, alc880_fivestack_ch6_init },
1159 { 8, alc880_fivestack_ch8_init },
1164 * ALC880 6-stack model
1166 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1167 * Side = 0x05 (0x0f)
1168 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1169 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1172 static hda_nid_t alc880_6st_dac_nids[4] = {
1173 /* front, rear, clfe, rear_surr */
1174 0x02, 0x03, 0x04, 0x05
1177 static struct hda_input_mux alc880_6stack_capture_source = {
1181 { "Front Mic", 0x1 },
1187 /* fixed 8-channels */
1188 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1192 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1193 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1194 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1195 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1196 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1197 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1198 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1199 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1200 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1201 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1202 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1203 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1204 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1208 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1209 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1210 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1211 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1212 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1215 .name = "Channel Mode",
1216 .info = alc_ch_mode_info,
1217 .get = alc_ch_mode_get,
1218 .put = alc_ch_mode_put,
1227 * W810 has rear IO for:
1230 * Center/LFE (DAC 04)
1233 * The system also has a pair of internal speakers, and a headphone jack.
1234 * These are both connected to Line2 on the codec, hence to DAC 02.
1236 * There is a variable resistor to control the speaker or headphone
1237 * volume. This is a hardware-only device without a software API.
1239 * Plugging headphones in will disable the internal speakers. This is
1240 * implemented in hardware, not via the driver using jack sense. In
1241 * a similar fashion, plugging into the rear socket marked "front" will
1242 * disable both the speakers and headphones.
1244 * For input, there's a microphone jack, and an "audio in" jack.
1245 * These may not do anything useful with this driver yet, because I
1246 * haven't setup any initialization verbs for these yet...
1249 static hda_nid_t alc880_w810_dac_nids[3] = {
1250 /* front, rear/surround, clfe */
1254 /* fixed 6 channels */
1255 static struct hda_channel_mode alc880_w810_modes[1] = {
1259 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1260 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1261 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1262 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1263 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1264 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1265 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1266 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1267 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1268 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1269 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1277 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1278 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1282 static hda_nid_t alc880_z71v_dac_nids[1] = {
1285 #define ALC880_Z71V_HP_DAC 0x03
1287 /* fixed 2 channels */
1288 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1292 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1294 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1295 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1296 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1297 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1298 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1299 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1300 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1306 * ALC880 F1734 model
1308 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1309 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1312 static hda_nid_t alc880_f1734_dac_nids[1] = {
1315 #define ALC880_F1734_HP_DAC 0x02
1317 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1318 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1319 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1320 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1321 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1322 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1323 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1329 static struct hda_input_mux alc880_f1734_capture_source = {
1341 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1342 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1343 * Mic = 0x18, Line = 0x1a
1346 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1347 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1349 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1351 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1352 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1353 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1354 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1355 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1356 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1357 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1358 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1359 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1360 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1361 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1363 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1366 .name = "Channel Mode",
1367 .info = alc_ch_mode_info,
1368 .get = alc_ch_mode_get,
1369 .put = alc_ch_mode_put,
1375 * ALC880 ASUS W1V model
1377 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1378 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1379 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1382 /* additional mixers to alc880_asus_mixer */
1383 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1384 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1385 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1389 /* additional mixers to alc880_asus_mixer */
1390 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1391 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1392 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1397 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1399 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1401 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1402 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1405 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1406 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1409 /* The multiple "Capture Source" controls confuse alsamixer
1410 * So call somewhat different..
1412 /* .name = "Capture Source", */
1413 .name = "Input Source",
1415 .info = alc_mux_enum_info,
1416 .get = alc_mux_enum_get,
1417 .put = alc_mux_enum_put,
1423 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1424 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1425 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1426 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1427 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1428 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1429 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1430 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1431 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1432 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1433 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1434 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1435 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1438 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1439 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1440 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1441 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1444 .name = "Channel Mode",
1445 .info = alc_ch_mode_info,
1446 .get = alc_ch_mode_get,
1447 .put = alc_ch_mode_put,
1452 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1454 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1455 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1456 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1457 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1458 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1459 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1460 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1461 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1462 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1466 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1467 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1468 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1469 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1470 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1472 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1477 * virtual master controls
1481 * slave controls for virtual master
1483 static const char *alc_slave_vols[] = {
1484 "Front Playback Volume",
1485 "Surround Playback Volume",
1486 "Center Playback Volume",
1487 "LFE Playback Volume",
1488 "Side Playback Volume",
1489 "Headphone Playback Volume",
1490 "Speaker Playback Volume",
1491 "Mono Playback Volume",
1492 "Line-Out Playback Volume",
1496 static const char *alc_slave_sws[] = {
1497 "Front Playback Switch",
1498 "Surround Playback Switch",
1499 "Center Playback Switch",
1500 "LFE Playback Switch",
1501 "Side Playback Switch",
1502 "Headphone Playback Switch",
1503 "Speaker Playback Switch",
1504 "Mono Playback Switch",
1505 "IEC958 Playback Switch",
1510 * build control elements
1512 static int alc_build_controls(struct hda_codec *codec)
1514 struct alc_spec *spec = codec->spec;
1518 for (i = 0; i < spec->num_mixers; i++) {
1519 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1524 if (spec->multiout.dig_out_nid) {
1525 err = snd_hda_create_spdif_out_ctls(codec,
1526 spec->multiout.dig_out_nid);
1529 err = snd_hda_create_spdif_share_sw(codec,
1533 spec->multiout.share_spdif = 1;
1535 if (spec->dig_in_nid) {
1536 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1541 /* if we have no master control, let's create it */
1542 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1543 unsigned int vmaster_tlv[4];
1544 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1545 HDA_OUTPUT, vmaster_tlv);
1546 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1547 vmaster_tlv, alc_slave_vols);
1551 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1552 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1553 NULL, alc_slave_sws);
1563 * initialize the codec volumes, etc
1567 * generic initialization of ADC, input mixers and output mixers
1569 static struct hda_verb alc880_volume_init_verbs[] = {
1571 * Unmute ADC0-2 and set the default input to mic-in
1573 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1575 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1576 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1577 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1578 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1580 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1582 * Note: PASD motherboards uses the Line In 2 as the input for front
1585 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1590 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1591 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1592 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1595 * Set up output mixers (0x0c - 0x0f)
1597 /* set vol=0 to output mixers */
1598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1599 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1600 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1601 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1602 /* set up input amps for analog loopback */
1603 /* Amp Indices: DAC = 0, mixer = 1 */
1604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1608 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1617 * 3-stack pin configuration:
1618 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1620 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1622 * preset connection lists of input pins
1623 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1625 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1626 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1627 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1630 * Set pin mode and muting
1632 /* set front pin widgets 0x14 for output */
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1636 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1637 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1638 /* Mic2 (as headphone out) for HP output */
1639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1640 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1641 /* Line In pin widget for input */
1642 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1643 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1644 /* Line2 (as front mic) pin widget for input and vref at 80% */
1645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1646 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1647 /* CD pin widget for input */
1648 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1654 * 5-stack pin configuration:
1655 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1656 * line-in/side = 0x1a, f-mic = 0x1b
1658 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1660 * preset connection lists of input pins
1661 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1663 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1664 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1667 * Set pin mode and muting
1669 /* set pin widgets 0x14-0x17 for output */
1670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1672 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1673 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1674 /* unmute pins for output (no gain on this amp) */
1675 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1681 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1683 /* Mic2 (as headphone out) for HP output */
1684 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1685 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686 /* Line In pin widget for input */
1687 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1689 /* Line2 (as front mic) pin widget for input and vref at 80% */
1690 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1691 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1692 /* CD pin widget for input */
1693 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1699 * W810 pin configuration:
1700 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1702 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1703 /* hphone/speaker input selector: front DAC */
1704 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1706 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1707 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1710 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1711 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1714 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1720 * Z71V pin configuration:
1721 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1723 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1724 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1725 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1727 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1729 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1731 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738 * 6-stack pin configuration:
1739 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1740 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1742 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1743 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1746 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1751 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1752 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1754 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1755 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1762 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1768 * Uniwill pin configuration:
1769 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1772 static struct hda_verb alc880_uniwill_init_verbs[] = {
1773 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1775 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1777 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1779 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1781 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1782 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1784 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1785 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1787 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1788 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1791 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1792 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1793 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1794 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1795 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1796 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1797 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1798 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1800 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1801 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1808 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1810 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1811 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1813 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1821 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1822 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1823 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1824 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1826 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1827 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1828 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1829 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1830 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1831 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1833 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1834 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1839 static struct hda_verb alc880_beep_init_verbs[] = {
1840 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1844 /* toggle speaker-output according to the hp-jack state */
1845 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1847 unsigned int present;
1850 present = snd_hda_codec_read(codec, 0x14, 0,
1851 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1852 bits = present ? HDA_AMP_MUTE : 0;
1853 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1854 HDA_AMP_MUTE, bits);
1855 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1856 HDA_AMP_MUTE, bits);
1859 /* auto-toggle front mic */
1860 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1862 unsigned int present;
1865 present = snd_hda_codec_read(codec, 0x18, 0,
1866 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1867 bits = present ? HDA_AMP_MUTE : 0;
1868 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1871 static void alc880_uniwill_automute(struct hda_codec *codec)
1873 alc880_uniwill_hp_automute(codec);
1874 alc880_uniwill_mic_automute(codec);
1877 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1880 /* Looks like the unsol event is incompatible with the standard
1881 * definition. 4bit tag is placed at 28 bit!
1883 switch (res >> 28) {
1884 case ALC880_HP_EVENT:
1885 alc880_uniwill_hp_automute(codec);
1887 case ALC880_MIC_EVENT:
1888 alc880_uniwill_mic_automute(codec);
1893 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1895 unsigned int present;
1898 present = snd_hda_codec_read(codec, 0x14, 0,
1899 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1900 bits = present ? HDA_AMP_MUTE : 0;
1901 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
1904 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1906 unsigned int present;
1908 present = snd_hda_codec_read(codec, 0x21, 0,
1909 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1910 present &= HDA_AMP_VOLMASK;
1911 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1912 HDA_AMP_VOLMASK, present);
1913 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1914 HDA_AMP_VOLMASK, present);
1917 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1920 /* Looks like the unsol event is incompatible with the standard
1921 * definition. 4bit tag is placed at 28 bit!
1923 if ((res >> 28) == ALC880_HP_EVENT)
1924 alc880_uniwill_p53_hp_automute(codec);
1925 if ((res >> 28) == ALC880_DCVOL_EVENT)
1926 alc880_uniwill_p53_dcvol_automute(codec);
1930 * F1734 pin configuration:
1931 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1933 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1934 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
1935 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1936 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1937 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1938 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1940 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1941 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1943 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1945 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1946 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1947 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
1948 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1949 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1950 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1951 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1952 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1953 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1955 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
1956 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
1962 * ASUS pin configuration:
1963 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1965 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1966 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1967 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1968 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1969 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1971 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1973 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1974 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1975 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1976 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1977 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1980 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1982 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1983 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1984 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1985 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1988 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1993 /* Enable GPIO mask and set output */
1994 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1995 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1997 /* Clevo m520g init */
1998 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1999 /* headphone output */
2000 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2002 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2003 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2005 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2006 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2008 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2009 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2010 /* Mic1 (rear panel) */
2011 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2012 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2013 /* Mic2 (front panel) */
2014 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2015 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2018 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2019 /* change to EAPD mode */
2020 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2021 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2026 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2027 /* change to EAPD mode */
2028 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2029 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2031 /* Headphone output */
2032 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2034 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2035 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2037 /* Line In pin widget for input */
2038 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2039 /* CD pin widget for input */
2040 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2041 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2044 /* change to EAPD mode */
2045 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2046 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2052 * LG m1 express dual
2055 * Rear Line-In/Out (blue): 0x14
2056 * Build-in Mic-In: 0x15
2058 * HP-Out (green): 0x1b
2059 * Mic-In/Out (red): 0x19
2063 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2064 static hda_nid_t alc880_lg_dac_nids[3] = {
2068 /* seems analog CD is not working */
2069 static struct hda_input_mux alc880_lg_capture_source = {
2074 { "Internal Mic", 0x6 },
2078 /* 2,4,6 channel modes */
2079 static struct hda_verb alc880_lg_ch2_init[] = {
2080 /* set line-in and mic-in to input */
2081 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2082 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2086 static struct hda_verb alc880_lg_ch4_init[] = {
2087 /* set line-in to out and mic-in to input */
2088 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2093 static struct hda_verb alc880_lg_ch6_init[] = {
2094 /* set line-in and mic-in to output */
2095 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2096 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2100 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2101 { 2, alc880_lg_ch2_init },
2102 { 4, alc880_lg_ch4_init },
2103 { 6, alc880_lg_ch6_init },
2106 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2110 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2113 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2114 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2119 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2120 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2122 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2123 .name = "Channel Mode",
2124 .info = alc_ch_mode_info,
2125 .get = alc_ch_mode_get,
2126 .put = alc_ch_mode_put,
2131 static struct hda_verb alc880_lg_init_verbs[] = {
2132 /* set capture source to mic-in */
2133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2134 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2135 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2136 /* mute all amp mixer inputs */
2137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2139 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2140 /* line-in to input */
2141 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2142 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2147 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2148 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2149 /* mic-in to input */
2150 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2151 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2152 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2154 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2155 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2156 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2162 /* toggle speaker-output according to the hp-jack state */
2163 static void alc880_lg_automute(struct hda_codec *codec)
2165 unsigned int present;
2168 present = snd_hda_codec_read(codec, 0x1b, 0,
2169 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2170 bits = present ? HDA_AMP_MUTE : 0;
2171 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2172 HDA_AMP_MUTE, bits);
2175 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2177 /* Looks like the unsol event is incompatible with the standard
2178 * definition. 4bit tag is placed at 28 bit!
2180 if ((res >> 28) == 0x01)
2181 alc880_lg_automute(codec);
2190 * Built-in Mic-In: 0x19
2196 static struct hda_input_mux alc880_lg_lw_capture_source = {
2200 { "Internal Mic", 0x1 },
2205 #define alc880_lg_lw_modes alc880_threestack_modes
2207 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2208 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2209 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2210 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2211 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2212 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2213 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2214 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2215 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2217 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2219 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2220 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2221 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2223 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2224 .name = "Channel Mode",
2225 .info = alc_ch_mode_info,
2226 .get = alc_ch_mode_get,
2227 .put = alc_ch_mode_put,
2232 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2233 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2234 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2235 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2237 /* set capture source to mic-in */
2238 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2239 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2240 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2243 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2244 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2248 /* mic-in to input */
2249 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2250 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2252 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2253 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2255 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2259 /* toggle speaker-output according to the hp-jack state */
2260 static void alc880_lg_lw_automute(struct hda_codec *codec)
2262 unsigned int present;
2265 present = snd_hda_codec_read(codec, 0x1b, 0,
2266 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2267 bits = present ? HDA_AMP_MUTE : 0;
2268 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2269 HDA_AMP_MUTE, bits);
2272 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2274 /* Looks like the unsol event is incompatible with the standard
2275 * definition. 4bit tag is placed at 28 bit!
2277 if ((res >> 28) == 0x01)
2278 alc880_lg_lw_automute(codec);
2281 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2282 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2283 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2286 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2287 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2291 static struct hda_input_mux alc880_medion_rim_capture_source = {
2295 { "Internal Mic", 0x1 },
2299 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2300 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2303 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2305 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2306 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2308 /* Mic2 (as headphone out) for HP output */
2309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2310 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2311 /* Internal Speaker */
2312 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2313 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2315 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2316 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2318 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2322 /* toggle speaker-output according to the hp-jack state */
2323 static void alc880_medion_rim_automute(struct hda_codec *codec)
2325 unsigned int present;
2328 present = snd_hda_codec_read(codec, 0x14, 0,
2329 AC_VERB_GET_PIN_SENSE, 0)
2330 & AC_PINSENSE_PRESENCE;
2331 bits = present ? HDA_AMP_MUTE : 0;
2332 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2333 HDA_AMP_MUTE, bits);
2335 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2337 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2340 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2343 /* Looks like the unsol event is incompatible with the standard
2344 * definition. 4bit tag is placed at 28 bit!
2346 if ((res >> 28) == ALC880_HP_EVENT)
2347 alc880_medion_rim_automute(codec);
2350 #ifdef CONFIG_SND_HDA_POWER_SAVE
2351 static struct hda_amp_list alc880_loopbacks[] = {
2352 { 0x0b, HDA_INPUT, 0 },
2353 { 0x0b, HDA_INPUT, 1 },
2354 { 0x0b, HDA_INPUT, 2 },
2355 { 0x0b, HDA_INPUT, 3 },
2356 { 0x0b, HDA_INPUT, 4 },
2360 static struct hda_amp_list alc880_lg_loopbacks[] = {
2361 { 0x0b, HDA_INPUT, 1 },
2362 { 0x0b, HDA_INPUT, 6 },
2363 { 0x0b, HDA_INPUT, 7 },
2372 static int alc_init(struct hda_codec *codec)
2374 struct alc_spec *spec = codec->spec;
2377 for (i = 0; i < spec->num_init_verbs; i++)
2378 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2380 if (spec->init_hook)
2381 spec->init_hook(codec);
2386 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2388 struct alc_spec *spec = codec->spec;
2390 if (spec->unsol_event)
2391 spec->unsol_event(codec, res);
2394 #ifdef CONFIG_SND_HDA_POWER_SAVE
2395 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2397 struct alc_spec *spec = codec->spec;
2398 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2403 * Analog playback callbacks
2405 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2406 struct hda_codec *codec,
2407 struct snd_pcm_substream *substream)
2409 struct alc_spec *spec = codec->spec;
2410 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2414 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2415 struct hda_codec *codec,
2416 unsigned int stream_tag,
2417 unsigned int format,
2418 struct snd_pcm_substream *substream)
2420 struct alc_spec *spec = codec->spec;
2421 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2422 stream_tag, format, substream);
2425 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2426 struct hda_codec *codec,
2427 struct snd_pcm_substream *substream)
2429 struct alc_spec *spec = codec->spec;
2430 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2436 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2437 struct hda_codec *codec,
2438 struct snd_pcm_substream *substream)
2440 struct alc_spec *spec = codec->spec;
2441 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2444 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2445 struct hda_codec *codec,
2446 unsigned int stream_tag,
2447 unsigned int format,
2448 struct snd_pcm_substream *substream)
2450 struct alc_spec *spec = codec->spec;
2451 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2452 stream_tag, format, substream);
2455 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2456 struct hda_codec *codec,
2457 struct snd_pcm_substream *substream)
2459 struct alc_spec *spec = codec->spec;
2460 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2466 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2467 struct hda_codec *codec,
2468 unsigned int stream_tag,
2469 unsigned int format,
2470 struct snd_pcm_substream *substream)
2472 struct alc_spec *spec = codec->spec;
2474 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2475 stream_tag, 0, format);
2479 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2480 struct hda_codec *codec,
2481 struct snd_pcm_substream *substream)
2483 struct alc_spec *spec = codec->spec;
2485 snd_hda_codec_cleanup_stream(codec,
2486 spec->adc_nids[substream->number + 1]);
2493 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2497 /* NID is set in alc_build_pcms */
2499 .open = alc880_playback_pcm_open,
2500 .prepare = alc880_playback_pcm_prepare,
2501 .cleanup = alc880_playback_pcm_cleanup
2505 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2509 /* NID is set in alc_build_pcms */
2512 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2516 /* NID is set in alc_build_pcms */
2519 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2520 .substreams = 2, /* can be overridden */
2523 /* NID is set in alc_build_pcms */
2525 .prepare = alc880_alt_capture_pcm_prepare,
2526 .cleanup = alc880_alt_capture_pcm_cleanup
2530 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2534 /* NID is set in alc_build_pcms */
2536 .open = alc880_dig_playback_pcm_open,
2537 .close = alc880_dig_playback_pcm_close,
2538 .prepare = alc880_dig_playback_pcm_prepare
2542 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2546 /* NID is set in alc_build_pcms */
2549 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2550 static struct hda_pcm_stream alc_pcm_null_stream = {
2556 static int alc_build_pcms(struct hda_codec *codec)
2558 struct alc_spec *spec = codec->spec;
2559 struct hda_pcm *info = spec->pcm_rec;
2562 codec->num_pcms = 1;
2563 codec->pcm_info = info;
2565 info->name = spec->stream_name_analog;
2566 if (spec->stream_analog_playback) {
2567 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2568 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2569 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2571 if (spec->stream_analog_capture) {
2572 snd_assert(spec->adc_nids, return -EINVAL);
2573 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2574 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2577 if (spec->channel_mode) {
2578 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2579 for (i = 0; i < spec->num_channel_mode; i++) {
2580 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2581 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2586 /* SPDIF for stream index #1 */
2587 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2588 codec->num_pcms = 2;
2589 info = spec->pcm_rec + 1;
2590 info->name = spec->stream_name_digital;
2591 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2592 if (spec->multiout.dig_out_nid &&
2593 spec->stream_digital_playback) {
2594 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2595 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2597 if (spec->dig_in_nid &&
2598 spec->stream_digital_capture) {
2599 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2600 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2604 /* If the use of more than one ADC is requested for the current
2605 * model, configure a second analog capture-only PCM.
2607 /* Additional Analaog capture for index #2 */
2608 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2609 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2610 codec->num_pcms = 3;
2611 info = spec->pcm_rec + 2;
2612 info->name = spec->stream_name_analog;
2613 if (spec->alt_dac_nid) {
2614 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2615 *spec->stream_analog_alt_playback;
2616 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2619 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2620 alc_pcm_null_stream;
2621 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2623 if (spec->num_adc_nids > 1) {
2624 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2625 *spec->stream_analog_alt_capture;
2626 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2628 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2629 spec->num_adc_nids - 1;
2631 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2632 alc_pcm_null_stream;
2633 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2640 static void alc_free(struct hda_codec *codec)
2642 struct alc_spec *spec = codec->spec;
2648 if (spec->kctl_alloc) {
2649 for (i = 0; i < spec->num_kctl_used; i++)
2650 kfree(spec->kctl_alloc[i].name);
2651 kfree(spec->kctl_alloc);
2654 codec->spec = NULL; /* to be sure */
2659 static struct hda_codec_ops alc_patch_ops = {
2660 .build_controls = alc_build_controls,
2661 .build_pcms = alc_build_pcms,
2664 .unsol_event = alc_unsol_event,
2665 #ifdef CONFIG_SND_HDA_POWER_SAVE
2666 .check_power_status = alc_check_power_status,
2672 * Test configuration for debugging
2674 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2677 #ifdef CONFIG_SND_DEBUG
2678 static hda_nid_t alc880_test_dac_nids[4] = {
2679 0x02, 0x03, 0x04, 0x05
2682 static struct hda_input_mux alc880_test_capture_source = {
2691 { "Surround", 0x6 },
2695 static struct hda_channel_mode alc880_test_modes[4] = {
2702 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_info *uinfo)
2705 static char *texts[] = {
2706 "N/A", "Line Out", "HP Out",
2707 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2709 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2711 uinfo->value.enumerated.items = 8;
2712 if (uinfo->value.enumerated.item >= 8)
2713 uinfo->value.enumerated.item = 7;
2714 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2718 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2719 struct snd_ctl_elem_value *ucontrol)
2721 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2722 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2723 unsigned int pin_ctl, item = 0;
2725 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2726 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2727 if (pin_ctl & AC_PINCTL_OUT_EN) {
2728 if (pin_ctl & AC_PINCTL_HP_EN)
2732 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2733 switch (pin_ctl & AC_PINCTL_VREFEN) {
2734 case AC_PINCTL_VREF_HIZ: item = 3; break;
2735 case AC_PINCTL_VREF_50: item = 4; break;
2736 case AC_PINCTL_VREF_GRD: item = 5; break;
2737 case AC_PINCTL_VREF_80: item = 6; break;
2738 case AC_PINCTL_VREF_100: item = 7; break;
2741 ucontrol->value.enumerated.item[0] = item;
2745 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2746 struct snd_ctl_elem_value *ucontrol)
2748 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2749 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2750 static unsigned int ctls[] = {
2751 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2752 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2753 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2754 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2755 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2756 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2758 unsigned int old_ctl, new_ctl;
2760 old_ctl = snd_hda_codec_read(codec, nid, 0,
2761 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2762 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2763 if (old_ctl != new_ctl) {
2765 snd_hda_codec_write_cache(codec, nid, 0,
2766 AC_VERB_SET_PIN_WIDGET_CONTROL,
2768 val = ucontrol->value.enumerated.item[0] >= 3 ?
2770 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2777 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2778 struct snd_ctl_elem_info *uinfo)
2780 static char *texts[] = {
2781 "Front", "Surround", "CLFE", "Side"
2783 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2785 uinfo->value.enumerated.items = 4;
2786 if (uinfo->value.enumerated.item >= 4)
2787 uinfo->value.enumerated.item = 3;
2788 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2792 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2793 struct snd_ctl_elem_value *ucontrol)
2795 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2796 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2799 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2800 ucontrol->value.enumerated.item[0] = sel & 3;
2804 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2805 struct snd_ctl_elem_value *ucontrol)
2807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2808 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2811 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2812 if (ucontrol->value.enumerated.item[0] != sel) {
2813 sel = ucontrol->value.enumerated.item[0] & 3;
2814 snd_hda_codec_write_cache(codec, nid, 0,
2815 AC_VERB_SET_CONNECT_SEL, sel);
2821 #define PIN_CTL_TEST(xname,nid) { \
2822 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2824 .info = alc_test_pin_ctl_info, \
2825 .get = alc_test_pin_ctl_get, \
2826 .put = alc_test_pin_ctl_put, \
2827 .private_value = nid \
2830 #define PIN_SRC_TEST(xname,nid) { \
2831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2833 .info = alc_test_pin_src_info, \
2834 .get = alc_test_pin_src_get, \
2835 .put = alc_test_pin_src_put, \
2836 .private_value = nid \
2839 static struct snd_kcontrol_new alc880_test_mixer[] = {
2840 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2841 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2842 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2843 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2844 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2845 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2846 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2847 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2848 PIN_CTL_TEST("Front Pin Mode", 0x14),
2849 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2850 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2851 PIN_CTL_TEST("Side Pin Mode", 0x17),
2852 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2853 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2854 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2855 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2856 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2857 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2858 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2859 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2860 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2861 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2862 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2863 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2864 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2865 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2866 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2867 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2871 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2872 .name = "Channel Mode",
2873 .info = alc_ch_mode_info,
2874 .get = alc_ch_mode_get,
2875 .put = alc_ch_mode_put,
2880 static struct hda_verb alc880_test_init_verbs[] = {
2881 /* Unmute inputs of 0x0c - 0x0f */
2882 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2883 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2884 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2885 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2886 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2889 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2890 /* Vol output for 0x0c-0x0f */
2891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2892 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2893 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2895 /* Set output pins 0x14-0x17 */
2896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2898 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2899 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2900 /* Unmute output pins 0x14-0x17 */
2901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2902 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2904 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2905 /* Set input pins 0x18-0x1c */
2906 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2911 /* Mute input pins 0x18-0x1b */
2912 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2915 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2917 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2918 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2919 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2920 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2921 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2922 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2923 /* Analog input/passthru */
2924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2936 static const char *alc880_models[ALC880_MODEL_LAST] = {
2937 [ALC880_3ST] = "3stack",
2938 [ALC880_TCL_S700] = "tcl",
2939 [ALC880_3ST_DIG] = "3stack-digout",
2940 [ALC880_CLEVO] = "clevo",
2941 [ALC880_5ST] = "5stack",
2942 [ALC880_5ST_DIG] = "5stack-digout",
2943 [ALC880_W810] = "w810",
2944 [ALC880_Z71V] = "z71v",
2945 [ALC880_6ST] = "6stack",
2946 [ALC880_6ST_DIG] = "6stack-digout",
2947 [ALC880_ASUS] = "asus",
2948 [ALC880_ASUS_W1V] = "asus-w1v",
2949 [ALC880_ASUS_DIG] = "asus-dig",
2950 [ALC880_ASUS_DIG2] = "asus-dig2",
2951 [ALC880_UNIWILL_DIG] = "uniwill",
2952 [ALC880_UNIWILL_P53] = "uniwill-p53",
2953 [ALC880_FUJITSU] = "fujitsu",
2954 [ALC880_F1734] = "F1734",
2956 [ALC880_LG_LW] = "lg-lw",
2957 [ALC880_MEDION_RIM] = "medion",
2958 #ifdef CONFIG_SND_DEBUG
2959 [ALC880_TEST] = "test",
2961 [ALC880_AUTO] = "auto",
2964 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2965 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2966 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2967 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2968 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2969 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2970 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2971 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2972 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2973 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2974 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2975 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2976 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2977 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2978 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2979 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2980 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2981 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2982 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2983 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2984 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2985 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2986 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
2987 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2988 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2989 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2990 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
2991 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2992 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2993 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2994 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2995 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2996 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2997 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2998 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2999 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3000 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3001 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3002 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3003 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3004 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3005 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3006 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3007 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3008 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3009 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3010 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3011 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3012 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3013 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3014 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3015 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3016 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3017 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3018 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3019 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3020 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3021 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3022 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3023 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3024 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3025 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3026 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3027 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3028 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3029 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3030 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3031 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3032 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3033 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3034 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3039 * ALC880 codec presets
3041 static struct alc_config_preset alc880_presets[] = {
3043 .mixers = { alc880_three_stack_mixer },
3044 .init_verbs = { alc880_volume_init_verbs,
3045 alc880_pin_3stack_init_verbs },
3046 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3047 .dac_nids = alc880_dac_nids,
3048 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3049 .channel_mode = alc880_threestack_modes,
3051 .input_mux = &alc880_capture_source,
3053 [ALC880_3ST_DIG] = {
3054 .mixers = { alc880_three_stack_mixer },
3055 .init_verbs = { alc880_volume_init_verbs,
3056 alc880_pin_3stack_init_verbs },
3057 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3058 .dac_nids = alc880_dac_nids,
3059 .dig_out_nid = ALC880_DIGOUT_NID,
3060 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3061 .channel_mode = alc880_threestack_modes,
3063 .input_mux = &alc880_capture_source,
3065 [ALC880_TCL_S700] = {
3066 .mixers = { alc880_tcl_s700_mixer },
3067 .init_verbs = { alc880_volume_init_verbs,
3068 alc880_pin_tcl_S700_init_verbs,
3069 alc880_gpio2_init_verbs },
3070 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3071 .dac_nids = alc880_dac_nids,
3073 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3074 .channel_mode = alc880_2_jack_modes,
3075 .input_mux = &alc880_capture_source,
3078 .mixers = { alc880_three_stack_mixer,
3079 alc880_five_stack_mixer},
3080 .init_verbs = { alc880_volume_init_verbs,
3081 alc880_pin_5stack_init_verbs },
3082 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3083 .dac_nids = alc880_dac_nids,
3084 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3085 .channel_mode = alc880_fivestack_modes,
3086 .input_mux = &alc880_capture_source,
3088 [ALC880_5ST_DIG] = {
3089 .mixers = { alc880_three_stack_mixer,
3090 alc880_five_stack_mixer },
3091 .init_verbs = { alc880_volume_init_verbs,
3092 alc880_pin_5stack_init_verbs },
3093 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3094 .dac_nids = alc880_dac_nids,
3095 .dig_out_nid = ALC880_DIGOUT_NID,
3096 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3097 .channel_mode = alc880_fivestack_modes,
3098 .input_mux = &alc880_capture_source,
3101 .mixers = { alc880_six_stack_mixer },
3102 .init_verbs = { alc880_volume_init_verbs,
3103 alc880_pin_6stack_init_verbs },
3104 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3105 .dac_nids = alc880_6st_dac_nids,
3106 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3107 .channel_mode = alc880_sixstack_modes,
3108 .input_mux = &alc880_6stack_capture_source,
3110 [ALC880_6ST_DIG] = {
3111 .mixers = { alc880_six_stack_mixer },
3112 .init_verbs = { alc880_volume_init_verbs,
3113 alc880_pin_6stack_init_verbs },
3114 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3115 .dac_nids = alc880_6st_dac_nids,
3116 .dig_out_nid = ALC880_DIGOUT_NID,
3117 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3118 .channel_mode = alc880_sixstack_modes,
3119 .input_mux = &alc880_6stack_capture_source,
3122 .mixers = { alc880_w810_base_mixer },
3123 .init_verbs = { alc880_volume_init_verbs,
3124 alc880_pin_w810_init_verbs,
3125 alc880_gpio2_init_verbs },
3126 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3127 .dac_nids = alc880_w810_dac_nids,
3128 .dig_out_nid = ALC880_DIGOUT_NID,
3129 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3130 .channel_mode = alc880_w810_modes,
3131 .input_mux = &alc880_capture_source,
3134 .mixers = { alc880_z71v_mixer },
3135 .init_verbs = { alc880_volume_init_verbs,
3136 alc880_pin_z71v_init_verbs },
3137 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3138 .dac_nids = alc880_z71v_dac_nids,
3139 .dig_out_nid = ALC880_DIGOUT_NID,
3141 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3142 .channel_mode = alc880_2_jack_modes,
3143 .input_mux = &alc880_capture_source,
3146 .mixers = { alc880_f1734_mixer },
3147 .init_verbs = { alc880_volume_init_verbs,
3148 alc880_pin_f1734_init_verbs },
3149 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3150 .dac_nids = alc880_f1734_dac_nids,
3152 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3153 .channel_mode = alc880_2_jack_modes,
3154 .input_mux = &alc880_f1734_capture_source,
3155 .unsol_event = alc880_uniwill_p53_unsol_event,
3156 .init_hook = alc880_uniwill_p53_hp_automute,
3159 .mixers = { alc880_asus_mixer },
3160 .init_verbs = { alc880_volume_init_verbs,
3161 alc880_pin_asus_init_verbs,
3162 alc880_gpio1_init_verbs },
3163 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3164 .dac_nids = alc880_asus_dac_nids,
3165 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3166 .channel_mode = alc880_asus_modes,
3168 .input_mux = &alc880_capture_source,
3170 [ALC880_ASUS_DIG] = {
3171 .mixers = { alc880_asus_mixer },
3172 .init_verbs = { alc880_volume_init_verbs,
3173 alc880_pin_asus_init_verbs,
3174 alc880_gpio1_init_verbs },
3175 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3176 .dac_nids = alc880_asus_dac_nids,
3177 .dig_out_nid = ALC880_DIGOUT_NID,
3178 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3179 .channel_mode = alc880_asus_modes,
3181 .input_mux = &alc880_capture_source,
3183 [ALC880_ASUS_DIG2] = {
3184 .mixers = { alc880_asus_mixer },
3185 .init_verbs = { alc880_volume_init_verbs,
3186 alc880_pin_asus_init_verbs,
3187 alc880_gpio2_init_verbs }, /* use GPIO2 */
3188 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3189 .dac_nids = alc880_asus_dac_nids,
3190 .dig_out_nid = ALC880_DIGOUT_NID,
3191 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3192 .channel_mode = alc880_asus_modes,
3194 .input_mux = &alc880_capture_source,
3196 [ALC880_ASUS_W1V] = {
3197 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3198 .init_verbs = { alc880_volume_init_verbs,
3199 alc880_pin_asus_init_verbs,
3200 alc880_gpio1_init_verbs },
3201 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3202 .dac_nids = alc880_asus_dac_nids,
3203 .dig_out_nid = ALC880_DIGOUT_NID,
3204 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3205 .channel_mode = alc880_asus_modes,
3207 .input_mux = &alc880_capture_source,
3209 [ALC880_UNIWILL_DIG] = {
3210 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3211 .init_verbs = { alc880_volume_init_verbs,
3212 alc880_pin_asus_init_verbs },
3213 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3214 .dac_nids = alc880_asus_dac_nids,
3215 .dig_out_nid = ALC880_DIGOUT_NID,
3216 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3217 .channel_mode = alc880_asus_modes,
3219 .input_mux = &alc880_capture_source,
3221 [ALC880_UNIWILL] = {
3222 .mixers = { alc880_uniwill_mixer },
3223 .init_verbs = { alc880_volume_init_verbs,
3224 alc880_uniwill_init_verbs },
3225 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3226 .dac_nids = alc880_asus_dac_nids,
3227 .dig_out_nid = ALC880_DIGOUT_NID,
3228 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3229 .channel_mode = alc880_threestack_modes,
3231 .input_mux = &alc880_capture_source,
3232 .unsol_event = alc880_uniwill_unsol_event,
3233 .init_hook = alc880_uniwill_automute,
3235 [ALC880_UNIWILL_P53] = {
3236 .mixers = { alc880_uniwill_p53_mixer },
3237 .init_verbs = { alc880_volume_init_verbs,
3238 alc880_uniwill_p53_init_verbs },
3239 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3240 .dac_nids = alc880_asus_dac_nids,
3241 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3242 .channel_mode = alc880_threestack_modes,
3243 .input_mux = &alc880_capture_source,
3244 .unsol_event = alc880_uniwill_p53_unsol_event,
3245 .init_hook = alc880_uniwill_p53_hp_automute,
3247 [ALC880_FUJITSU] = {
3248 .mixers = { alc880_fujitsu_mixer,
3249 alc880_pcbeep_mixer, },
3250 .init_verbs = { alc880_volume_init_verbs,
3251 alc880_uniwill_p53_init_verbs,
3252 alc880_beep_init_verbs },
3253 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3254 .dac_nids = alc880_dac_nids,
3255 .dig_out_nid = ALC880_DIGOUT_NID,
3256 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3257 .channel_mode = alc880_2_jack_modes,
3258 .input_mux = &alc880_capture_source,
3259 .unsol_event = alc880_uniwill_p53_unsol_event,
3260 .init_hook = alc880_uniwill_p53_hp_automute,
3263 .mixers = { alc880_three_stack_mixer },
3264 .init_verbs = { alc880_volume_init_verbs,
3265 alc880_pin_clevo_init_verbs },
3266 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3267 .dac_nids = alc880_dac_nids,
3269 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3270 .channel_mode = alc880_threestack_modes,
3272 .input_mux = &alc880_capture_source,
3275 .mixers = { alc880_lg_mixer },
3276 .init_verbs = { alc880_volume_init_verbs,
3277 alc880_lg_init_verbs },
3278 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3279 .dac_nids = alc880_lg_dac_nids,
3280 .dig_out_nid = ALC880_DIGOUT_NID,
3281 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3282 .channel_mode = alc880_lg_ch_modes,
3284 .input_mux = &alc880_lg_capture_source,
3285 .unsol_event = alc880_lg_unsol_event,
3286 .init_hook = alc880_lg_automute,
3287 #ifdef CONFIG_SND_HDA_POWER_SAVE
3288 .loopbacks = alc880_lg_loopbacks,
3292 .mixers = { alc880_lg_lw_mixer },
3293 .init_verbs = { alc880_volume_init_verbs,
3294 alc880_lg_lw_init_verbs },
3295 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3296 .dac_nids = alc880_dac_nids,
3297 .dig_out_nid = ALC880_DIGOUT_NID,
3298 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3299 .channel_mode = alc880_lg_lw_modes,
3300 .input_mux = &alc880_lg_lw_capture_source,
3301 .unsol_event = alc880_lg_lw_unsol_event,
3302 .init_hook = alc880_lg_lw_automute,
3304 [ALC880_MEDION_RIM] = {
3305 .mixers = { alc880_medion_rim_mixer },
3306 .init_verbs = { alc880_volume_init_verbs,
3307 alc880_medion_rim_init_verbs,
3308 alc_gpio2_init_verbs },
3309 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3310 .dac_nids = alc880_dac_nids,
3311 .dig_out_nid = ALC880_DIGOUT_NID,
3312 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3313 .channel_mode = alc880_2_jack_modes,
3314 .input_mux = &alc880_medion_rim_capture_source,
3315 .unsol_event = alc880_medion_rim_unsol_event,
3316 .init_hook = alc880_medion_rim_automute,
3318 #ifdef CONFIG_SND_DEBUG
3320 .mixers = { alc880_test_mixer },
3321 .init_verbs = { alc880_test_init_verbs },
3322 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3323 .dac_nids = alc880_test_dac_nids,
3324 .dig_out_nid = ALC880_DIGOUT_NID,
3325 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3326 .channel_mode = alc880_test_modes,
3327 .input_mux = &alc880_test_capture_source,
3333 * Automatic parse of I/O pins from the BIOS configuration
3336 #define NUM_CONTROL_ALLOC 32
3337 #define NUM_VERB_ALLOC 32
3341 ALC_CTL_WIDGET_MUTE,
3344 static struct snd_kcontrol_new alc880_control_templates[] = {
3345 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3346 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3347 HDA_BIND_MUTE(NULL, 0, 0, 0),
3350 /* add dynamic controls */
3351 static int add_control(struct alc_spec *spec, int type, const char *name,
3354 struct snd_kcontrol_new *knew;
3356 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3357 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3359 /* array + terminator */
3360 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3363 if (spec->kctl_alloc) {
3364 memcpy(knew, spec->kctl_alloc,
3365 sizeof(*knew) * spec->num_kctl_alloc);
3366 kfree(spec->kctl_alloc);
3368 spec->kctl_alloc = knew;
3369 spec->num_kctl_alloc = num;
3372 knew = &spec->kctl_alloc[spec->num_kctl_used];
3373 *knew = alc880_control_templates[type];
3374 knew->name = kstrdup(name, GFP_KERNEL);
3377 knew->private_value = val;
3378 spec->num_kctl_used++;
3382 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3383 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3384 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3385 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3386 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3387 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3388 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3389 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3390 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3391 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3392 #define ALC880_PIN_CD_NID 0x1c
3394 /* fill in the dac_nids table from the parsed pin configuration */
3395 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3396 const struct auto_pin_cfg *cfg)
3402 memset(assigned, 0, sizeof(assigned));
3403 spec->multiout.dac_nids = spec->private_dac_nids;
3405 /* check the pins hardwired to audio widget */
3406 for (i = 0; i < cfg->line_outs; i++) {
3407 nid = cfg->line_out_pins[i];
3408 if (alc880_is_fixed_pin(nid)) {
3409 int idx = alc880_fixed_pin_idx(nid);
3410 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3414 /* left pins can be connect to any audio widget */
3415 for (i = 0; i < cfg->line_outs; i++) {
3416 nid = cfg->line_out_pins[i];
3417 if (alc880_is_fixed_pin(nid))
3419 /* search for an empty channel */
3420 for (j = 0; j < cfg->line_outs; j++) {
3422 spec->multiout.dac_nids[i] =
3423 alc880_idx_to_dac(j);
3429 spec->multiout.num_dacs = cfg->line_outs;
3433 /* add playback controls from the parsed DAC table */
3434 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3435 const struct auto_pin_cfg *cfg)
3438 static const char *chname[4] = {
3439 "Front", "Surround", NULL /*CLFE*/, "Side"
3444 for (i = 0; i < cfg->line_outs; i++) {
3445 if (!spec->multiout.dac_nids[i])
3447 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3450 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3451 "Center Playback Volume",
3452 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3456 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3457 "LFE Playback Volume",
3458 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3462 err = add_control(spec, ALC_CTL_BIND_MUTE,
3463 "Center Playback Switch",
3464 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3468 err = add_control(spec, ALC_CTL_BIND_MUTE,
3469 "LFE Playback Switch",
3470 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3475 sprintf(name, "%s Playback Volume", chname[i]);
3476 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3477 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3481 sprintf(name, "%s Playback Switch", chname[i]);
3482 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3483 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3492 /* add playback controls for speaker and HP outputs */
3493 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3503 if (alc880_is_fixed_pin(pin)) {
3504 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3505 /* specify the DAC as the extra output */
3506 if (!spec->multiout.hp_nid)
3507 spec->multiout.hp_nid = nid;
3509 spec->multiout.extra_out_nid[0] = nid;
3510 /* control HP volume/switch on the output mixer amp */
3511 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3512 sprintf(name, "%s Playback Volume", pfx);
3513 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3514 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3517 sprintf(name, "%s Playback Switch", pfx);
3518 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3519 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3522 } else if (alc880_is_multi_pin(pin)) {
3523 /* set manual connection */
3524 /* we have only a switch on HP-out PIN */
3525 sprintf(name, "%s Playback Switch", pfx);
3526 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3527 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3534 /* create input playback/capture controls for the given pin */
3535 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3536 const char *ctlname,
3537 int idx, hda_nid_t mix_nid)
3542 sprintf(name, "%s Playback Volume", ctlname);
3543 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3544 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3547 sprintf(name, "%s Playback Switch", ctlname);
3548 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3549 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3555 /* create playback/capture controls for input pins */
3556 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3557 const struct auto_pin_cfg *cfg)
3559 struct hda_input_mux *imux = &spec->private_imux;
3562 for (i = 0; i < AUTO_PIN_LAST; i++) {
3563 if (alc880_is_input_pin(cfg->input_pins[i])) {
3564 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3565 err = new_analog_input(spec, cfg->input_pins[i],
3566 auto_pin_cfg_labels[i],
3570 imux->items[imux->num_items].label =
3571 auto_pin_cfg_labels[i];
3572 imux->items[imux->num_items].index =
3573 alc880_input_pin_idx(cfg->input_pins[i]);
3580 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3581 unsigned int pin_type)
3583 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3586 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3590 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3591 hda_nid_t nid, int pin_type,
3594 alc_set_pin_output(codec, nid, pin_type);
3595 /* need the manual connection? */
3596 if (alc880_is_multi_pin(nid)) {
3597 struct alc_spec *spec = codec->spec;
3598 int idx = alc880_multi_pin_idx(nid);
3599 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3600 AC_VERB_SET_CONNECT_SEL,
3601 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3605 static int get_pin_type(int line_out_type)
3607 if (line_out_type == AUTO_PIN_HP_OUT)
3613 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3615 struct alc_spec *spec = codec->spec;
3618 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3619 for (i = 0; i < spec->autocfg.line_outs; i++) {
3620 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3621 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3622 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3626 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3628 struct alc_spec *spec = codec->spec;
3631 pin = spec->autocfg.speaker_pins[0];
3632 if (pin) /* connect to front */
3633 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3634 pin = spec->autocfg.hp_pins[0];
3635 if (pin) /* connect to front */
3636 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3639 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3641 struct alc_spec *spec = codec->spec;
3644 for (i = 0; i < AUTO_PIN_LAST; i++) {
3645 hda_nid_t nid = spec->autocfg.input_pins[i];
3646 if (alc880_is_input_pin(nid)) {
3647 snd_hda_codec_write(codec, nid, 0,
3648 AC_VERB_SET_PIN_WIDGET_CONTROL,
3649 i <= AUTO_PIN_FRONT_MIC ?
3650 PIN_VREF80 : PIN_IN);
3651 if (nid != ALC880_PIN_CD_NID)
3652 snd_hda_codec_write(codec, nid, 0,
3653 AC_VERB_SET_AMP_GAIN_MUTE,
3659 /* parse the BIOS configuration and set up the alc_spec */
3660 /* return 1 if successful, 0 if the proper config is not found,
3661 * or a negative error code
3663 static int alc880_parse_auto_config(struct hda_codec *codec)
3665 struct alc_spec *spec = codec->spec;
3667 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3669 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3673 if (!spec->autocfg.line_outs)
3674 return 0; /* can't find valid BIOS pin config */
3676 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3679 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3682 err = alc880_auto_create_extra_out(spec,
3683 spec->autocfg.speaker_pins[0],
3687 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3691 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3695 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3697 if (spec->autocfg.dig_out_pin)
3698 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3699 if (spec->autocfg.dig_in_pin)
3700 spec->dig_in_nid = ALC880_DIGIN_NID;
3702 if (spec->kctl_alloc)
3703 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3705 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3707 spec->num_mux_defs = 1;
3708 spec->input_mux = &spec->private_imux;
3713 /* additional initialization for auto-configuration model */
3714 static void alc880_auto_init(struct hda_codec *codec)
3716 struct alc_spec *spec = codec->spec;
3717 alc880_auto_init_multi_out(codec);
3718 alc880_auto_init_extra_out(codec);
3719 alc880_auto_init_analog_input(codec);
3720 if (spec->unsol_event)
3721 alc_sku_automute(codec);
3725 * OK, here we have finally the patch for ALC880
3728 static int patch_alc880(struct hda_codec *codec)
3730 struct alc_spec *spec;
3734 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3740 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3743 if (board_config < 0) {
3744 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3745 "trying auto-probe from BIOS...\n");
3746 board_config = ALC880_AUTO;
3749 if (board_config == ALC880_AUTO) {
3750 /* automatic parse from the BIOS config */
3751 err = alc880_parse_auto_config(codec);
3757 "hda_codec: Cannot set up configuration "
3758 "from BIOS. Using 3-stack mode...\n");
3759 board_config = ALC880_3ST;
3763 if (board_config != ALC880_AUTO)
3764 setup_preset(spec, &alc880_presets[board_config]);
3766 spec->stream_name_analog = "ALC880 Analog";
3767 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3768 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3769 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3771 spec->stream_name_digital = "ALC880 Digital";
3772 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3773 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3775 if (!spec->adc_nids && spec->input_mux) {
3776 /* check whether NID 0x07 is valid */
3777 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3779 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3780 if (wcap != AC_WID_AUD_IN) {
3781 spec->adc_nids = alc880_adc_nids_alt;
3782 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3783 spec->mixers[spec->num_mixers] =
3784 alc880_capture_alt_mixer;
3787 spec->adc_nids = alc880_adc_nids;
3788 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3789 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3794 spec->vmaster_nid = 0x0c;
3796 codec->patch_ops = alc_patch_ops;
3797 if (board_config == ALC880_AUTO)
3798 spec->init_hook = alc880_auto_init;
3799 #ifdef CONFIG_SND_HDA_POWER_SAVE
3800 if (!spec->loopback.amplist)
3801 spec->loopback.amplist = alc880_loopbacks;
3812 static hda_nid_t alc260_dac_nids[1] = {
3817 static hda_nid_t alc260_adc_nids[1] = {
3822 static hda_nid_t alc260_adc_nids_alt[1] = {
3827 static hda_nid_t alc260_hp_adc_nids[2] = {
3832 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3833 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3835 static hda_nid_t alc260_dual_adc_nids[2] = {
3840 #define ALC260_DIGOUT_NID 0x03
3841 #define ALC260_DIGIN_NID 0x06
3843 static struct hda_input_mux alc260_capture_source = {
3847 { "Front Mic", 0x1 },
3853 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3854 * headphone jack and the internal CD lines since these are the only pins at
3855 * which audio can appear. For flexibility, also allow the option of
3856 * recording the mixer output on the second ADC (ADC0 doesn't have a
3857 * connection to the mixer output).
3859 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3863 { "Mic/Line", 0x0 },
3865 { "Headphone", 0x2 },
3871 { "Mic/Line", 0x0 },
3873 { "Headphone", 0x2 },
3880 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3881 * the Fujitsu S702x, but jacks are marked differently.
3883 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3890 { "Headphone", 0x5 },
3899 { "Headphone", 0x6 },
3905 * This is just place-holder, so there's something for alc_build_pcms to look
3906 * at when it calculates the maximum number of channels. ALC260 has no mixer
3907 * element which allows changing the channel mode, so the verb list is
3910 static struct hda_channel_mode alc260_modes[1] = {
3915 /* Mixer combinations
3917 * basic: base_output + input + pc_beep + capture
3918 * HP: base_output + input + capture_alt
3919 * HP_3013: hp_3013 + input + capture
3920 * fujitsu: fujitsu + capture
3921 * acer: acer + capture
3924 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3925 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3926 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3928 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3929 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3930 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3934 static struct snd_kcontrol_new alc260_input_mixer[] = {
3935 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3936 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3937 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3938 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3939 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3940 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3941 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3946 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3947 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3948 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3952 /* update HP, line and mono out pins according to the master switch */
3953 static void alc260_hp_master_update(struct hda_codec *codec,
3954 hda_nid_t hp, hda_nid_t line,
3957 struct alc_spec *spec = codec->spec;
3958 unsigned int val = spec->master_sw ? PIN_HP : 0;
3959 /* change HP and line-out pins */
3960 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3962 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3964 /* mono (speaker) depending on the HP jack sense */
3965 val = (val && !spec->jack_present) ? PIN_OUT : 0;
3966 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3970 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
3971 struct snd_ctl_elem_value *ucontrol)
3973 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3974 struct alc_spec *spec = codec->spec;
3975 *ucontrol->value.integer.value = spec->master_sw;
3979 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
3980 struct snd_ctl_elem_value *ucontrol)
3982 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3983 struct alc_spec *spec = codec->spec;
3984 int val = !!*ucontrol->value.integer.value;
3985 hda_nid_t hp, line, mono;
3987 if (val == spec->master_sw)
3989 spec->master_sw = val;
3990 hp = (kcontrol->private_value >> 16) & 0xff;
3991 line = (kcontrol->private_value >> 8) & 0xff;
3992 mono = kcontrol->private_value & 0xff;
3993 alc260_hp_master_update(codec, hp, line, mono);
3997 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
3999 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4000 .name = "Master Playback Switch",
4001 .info = snd_ctl_boolean_mono_info,
4002 .get = alc260_hp_master_sw_get,
4003 .put = alc260_hp_master_sw_put,
4004 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4006 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4007 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4008 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4009 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4010 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4012 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4016 static struct hda_verb alc260_hp_unsol_verbs[] = {
4017 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4021 static void alc260_hp_automute(struct hda_codec *codec)
4023 struct alc_spec *spec = codec->spec;
4024 unsigned int present;
4026 present = snd_hda_codec_read(codec, 0x10, 0,
4027 AC_VERB_GET_PIN_SENSE, 0);
4028 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4029 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4032 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4034 if ((res >> 26) == ALC880_HP_EVENT)
4035 alc260_hp_automute(codec);
4038 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4041 .name = "Master Playback Switch",
4042 .info = snd_ctl_boolean_mono_info,
4043 .get = alc260_hp_master_sw_get,
4044 .put = alc260_hp_master_sw_put,
4045 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4047 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4048 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4049 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4050 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4051 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4053 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4054 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4058 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4059 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4063 static void alc260_hp_3013_automute(struct hda_codec *codec)
4065 struct alc_spec *spec = codec->spec;
4066 unsigned int present;
4068 present = snd_hda_codec_read(codec, 0x15, 0,
4069 AC_VERB_GET_PIN_SENSE, 0);
4070 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4071 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4074 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4077 if ((res >> 26) == ALC880_HP_EVENT)
4078 alc260_hp_3013_automute(codec);
4081 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4082 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4084 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4085 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4086 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4087 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4088 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4089 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4090 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4091 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4092 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4093 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4094 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4095 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4096 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4100 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4101 * versions of the ALC260 don't act on requests to enable mic bias from NID
4102 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4103 * datasheet doesn't mention this restriction. At this stage it's not clear
4104 * whether this behaviour is intentional or is a hardware bug in chip
4105 * revisions available in early 2006. Therefore for now allow the
4106 * "Headphone Jack Mode" control to span all choices, but if it turns out
4107 * that the lack of mic bias for this NID is intentional we could change the
4108 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4110 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4111 * don't appear to make the mic bias available from the "line" jack, even
4112 * though the NID used for this jack (0x14) can supply it. The theory is
4113 * that perhaps Acer have included blocking capacitors between the ALC260
4114 * and the output jack. If this turns out to be the case for all such
4115 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4116 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4118 * The C20x Tablet series have a mono internal speaker which is controlled
4119 * via the chip's Mono sum widget and pin complex, so include the necessary
4120 * controls for such models. On models without a "mono speaker" the control
4121 * won't do anything.
4123 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4124 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4125 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4126 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4127 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4129 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4131 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4132 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4134 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4135 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4136 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4137 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4138 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4139 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4140 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4144 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4145 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4147 static struct snd_kcontrol_new alc260_will_mixer[] = {
4148 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4149 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4151 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4152 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4153 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4154 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4155 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4156 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4157 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4158 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4159 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4163 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4164 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4166 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4167 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4168 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4170 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4171 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4172 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4173 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4174 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4175 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4176 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4180 /* capture mixer elements */
4181 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4182 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4183 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4184 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4185 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4188 /* The multiple "Capture Source" controls confuse alsamixer
4189 * So call somewhat different..
4191 /* .name = "Capture Source", */
4192 .name = "Input Source",
4194 .info = alc_mux_enum_info,
4195 .get = alc_mux_enum_get,
4196 .put = alc_mux_enum_put,
4201 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4202 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4203 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4206 /* The multiple "Capture Source" controls confuse alsamixer
4207 * So call somewhat different..
4209 /* .name = "Capture Source", */
4210 .name = "Input Source",
4212 .info = alc_mux_enum_info,
4213 .get = alc_mux_enum_get,
4214 .put = alc_mux_enum_put,
4220 * initialization verbs
4222 static struct hda_verb alc260_init_verbs[] = {
4223 /* Line In pin widget for input */
4224 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4225 /* CD pin widget for input */
4226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4227 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4228 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4229 /* Mic2 (front panel) pin widget for input and vref at 80% */
4230 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4231 /* LINE-2 is used for line-out in rear */
4232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4233 /* select line-out */
4234 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4236 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4238 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4240 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4241 /* mute capture amp left and right */
4242 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4243 /* set connection select to line in (default select for this ADC) */
4244 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4245 /* mute capture amp left and right */
4246 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4247 /* set connection select to line in (default select for this ADC) */
4248 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4249 /* set vol=0 Line-Out mixer amp left and right */
4250 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4251 /* unmute pin widget amp left and right (no gain on this amp) */
4252 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4253 /* set vol=0 HP mixer amp left and right */
4254 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4255 /* unmute pin widget amp left and right (no gain on this amp) */
4256 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4257 /* set vol=0 Mono mixer amp left and right */
4258 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4259 /* unmute pin widget amp left and right (no gain on this amp) */
4260 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4261 /* unmute LINE-2 out pin */
4262 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4263 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4266 /* mute analog inputs */
4267 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4268 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4272 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4273 /* mute Front out path */
4274 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4276 /* mute Headphone out path */
4277 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4278 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4279 /* mute Mono out path */
4280 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4281 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4285 #if 0 /* should be identical with alc260_init_verbs? */
4286 static struct hda_verb alc260_hp_init_verbs[] = {
4287 /* Headphone and output */
4288 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4290 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4291 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4293 /* Mic2 (front panel) pin widget for input and vref at 80% */
4294 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4295 /* Line In pin widget for input */
4296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4297 /* Line-2 pin widget for output */
4298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4299 /* CD pin widget for input */
4300 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4301 /* unmute amp left and right */
4302 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4303 /* set connection select to line in (default select for this ADC) */
4304 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4305 /* unmute Line-Out mixer amp left and right (volume = 0) */
4306 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4307 /* mute pin widget amp left and right (no gain on this amp) */
4308 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4309 /* unmute HP mixer amp left and right (volume = 0) */
4310 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4311 /* mute pin widget amp left and right (no gain on this amp) */
4312 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4313 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4316 /* mute analog inputs */
4317 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4318 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4320 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4321 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4322 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4323 /* Unmute Front out path */
4324 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4326 /* Unmute Headphone out path */
4327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4329 /* Unmute Mono out path */
4330 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4331 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4336 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4337 /* Line out and output */
4338 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4340 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4341 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4342 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4343 /* Mic2 (front panel) pin widget for input and vref at 80% */
4344 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4345 /* Line In pin widget for input */
4346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4347 /* Headphone pin widget for output */
4348 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4349 /* CD pin widget for input */
4350 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4351 /* unmute amp left and right */
4352 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4353 /* set connection select to line in (default select for this ADC) */
4354 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4355 /* unmute Line-Out mixer amp left and right (volume = 0) */
4356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4357 /* mute pin widget amp left and right (no gain on this amp) */
4358 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4359 /* unmute HP mixer amp left and right (volume = 0) */
4360 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4361 /* mute pin widget amp left and right (no gain on this amp) */
4362 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4363 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4366 /* mute analog inputs */
4367 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4368 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4370 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4371 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4372 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4373 /* Unmute Front out path */
4374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4376 /* Unmute Headphone out path */
4377 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4378 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4379 /* Unmute Mono out path */
4380 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4381 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4385 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4386 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4387 * audio = 0x16, internal speaker = 0x10.
4389 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4390 /* Disable all GPIOs */
4391 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4392 /* Internal speaker is connected to headphone pin */
4393 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4394 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4396 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4397 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4398 /* Ensure all other unused pins are disabled and muted. */
4399 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4400 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4401 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4402 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4403 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4404 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4408 /* Disable digital (SPDIF) pins */
4409 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4410 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4412 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4413 * when acting as an output.
4415 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4417 /* Start with output sum widgets muted and their output gains at min */
4418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4421 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4422 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4424 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4425 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4426 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4428 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4429 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4430 /* Unmute Line1 pin widget output buffer since it starts as an output.
4431 * If the pin mode is changed by the user the pin mode control will
4432 * take care of enabling the pin's input/output buffers as needed.
4433 * Therefore there's no need to enable the input buffer at this
4436 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4437 /* Unmute input buffer of pin widget used for Line-in (no equiv
4440 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4442 /* Mute capture amp left and right */
4443 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4444 /* Set ADC connection select to match default mixer setting - line
4447 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4449 /* Do the same for the second ADC: mute capture input amp and
4450 * set ADC connection to line in (on mic1 pin)
4452 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4453 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4455 /* Mute all inputs to mixer widget (even unconnected ones) */
4456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4461 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4463 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4468 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4469 * similar laptops (adapted from Fujitsu init verbs).
4471 static struct hda_verb alc260_acer_init_verbs[] = {
4472 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4473 * the headphone jack. Turn this on and rely on the standard mute
4474 * methods whenever the user wants to turn these outputs off.
4476 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4477 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4478 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4479 /* Internal speaker/Headphone jack is connected to Line-out pin */
4480 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4481 /* Internal microphone/Mic jack is connected to Mic1 pin */
4482 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4483 /* Line In jack is connected to Line1 pin */
4484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4485 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4486 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4487 /* Ensure all other unused pins are disabled and muted. */
4488 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4489 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4490 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4491 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4494 /* Disable digital (SPDIF) pins */
4495 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4496 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4498 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4499 * bus when acting as outputs.
4501 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4502 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4504 /* Start with output sum widgets muted and their output gains at min */
4505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4511 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4515 /* Unmute Line-out pin widget amp left and right
4516 * (no equiv mixer ctrl)
4518 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4519 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4520 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4521 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4522 * inputs. If the pin mode is changed by the user the pin mode control
4523 * will take care of enabling the pin's input/output buffers as needed.
4524 * Therefore there's no need to enable the input buffer at this
4527 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4528 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4530 /* Mute capture amp left and right */
4531 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4532 /* Set ADC connection select to match default mixer setting - mic
4535 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4537 /* Do similar with the second ADC: mute capture input amp and
4538 * set ADC connection to mic to match ALSA's default state.
4540 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4541 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4543 /* Mute all inputs to mixer widget (even unconnected ones) */
4544 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4545 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4547 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4556 static struct hda_verb alc260_will_verbs[] = {
4557 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4558 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4559 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4560 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4561 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4562 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4566 static struct hda_verb alc260_replacer_672v_verbs[] = {
4567 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4568 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4569 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4571 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4572 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4573 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4575 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4579 /* toggle speaker-output according to the hp-jack state */
4580 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4582 unsigned int present;
4584 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4585 present = snd_hda_codec_read(codec, 0x0f, 0,
4586 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4588 snd_hda_codec_write_cache(codec, 0x01, 0,
4589 AC_VERB_SET_GPIO_DATA, 1);
4590 snd_hda_codec_write_cache(codec, 0x0f, 0,
4591 AC_VERB_SET_PIN_WIDGET_CONTROL,
4594 snd_hda_codec_write_cache(codec, 0x01, 0,
4595 AC_VERB_SET_GPIO_DATA, 0);
4596 snd_hda_codec_write_cache(codec, 0x0f, 0,
4597 AC_VERB_SET_PIN_WIDGET_CONTROL,
4602 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4605 if ((res >> 26) == ALC880_HP_EVENT)
4606 alc260_replacer_672v_automute(codec);
4609 /* Test configuration for debugging, modelled after the ALC880 test
4612 #ifdef CONFIG_SND_DEBUG
4613 static hda_nid_t alc260_test_dac_nids[1] = {
4616 static hda_nid_t alc260_test_adc_nids[2] = {
4619 /* For testing the ALC260, each input MUX needs its own definition since
4620 * the signal assignments are different. This assumes that the first ADC
4623 static struct hda_input_mux alc260_test_capture_sources[2] = {
4627 { "MIC1 pin", 0x0 },
4628 { "MIC2 pin", 0x1 },
4629 { "LINE1 pin", 0x2 },
4630 { "LINE2 pin", 0x3 },
4632 { "LINE-OUT pin", 0x5 },
4633 { "HP-OUT pin", 0x6 },
4639 { "MIC1 pin", 0x0 },
4640 { "MIC2 pin", 0x1 },
4641 { "LINE1 pin", 0x2 },
4642 { "LINE2 pin", 0x3 },
4645 { "LINE-OUT pin", 0x6 },
4646 { "HP-OUT pin", 0x7 },
4650 static struct snd_kcontrol_new alc260_test_mixer[] = {
4651 /* Output driver widgets */
4652 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4653 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4654 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4655 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4656 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4657 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4659 /* Modes for retasking pin widgets
4660 * Note: the ALC260 doesn't seem to act on requests to enable mic
4661 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4662 * mention this restriction. At this stage it's not clear whether
4663 * this behaviour is intentional or is a hardware bug in chip
4664 * revisions available at least up until early 2006. Therefore for
4665 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4666 * choices, but if it turns out that the lack of mic bias for these
4667 * NIDs is intentional we could change their modes from
4668 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4670 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4671 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4672 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4673 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4674 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4675 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4677 /* Loopback mixer controls */
4678 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4679 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4680 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4681 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4682 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4683 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4684 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4685 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4686 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4687 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4688 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4689 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4690 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4691 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4692 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4693 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4695 /* Controls for GPIO pins, assuming they are configured as outputs */
4696 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4697 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4698 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4699 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4701 /* Switches to allow the digital IO pins to be enabled. The datasheet
4702 * is ambigious as to which NID is which; testing on laptops which
4703 * make this output available should provide clarification.
4705 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4706 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4708 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4709 * this output to turn on an external amplifier.
4711 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4712 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4716 static struct hda_verb alc260_test_init_verbs[] = {
4717 /* Enable all GPIOs as outputs with an initial value of 0 */
4718 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4719 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4720 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4722 /* Enable retasking pins as output, initially without power amp */
4723 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4724 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4725 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4726 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4727 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4728 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4730 /* Disable digital (SPDIF) pins initially, but users can enable
4731 * them via a mixer switch. In the case of SPDIF-out, this initverb
4732 * payload also sets the generation to 0, output to be in "consumer"
4733 * PCM format, copyright asserted, no pre-emphasis and no validity
4736 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4737 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4739 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4740 * OUT1 sum bus when acting as an output.
4742 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4743 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4744 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4745 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4747 /* Start with output sum widgets muted and their output gains at min */
4748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4749 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4751 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4752 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4754 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4755 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4756 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4758 /* Unmute retasking pin widget output buffers since the default
4759 * state appears to be output. As the pin mode is changed by the
4760 * user the pin mode control will take care of enabling the pin's
4761 * input/output buffers as needed.
4763 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4767 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4768 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4769 /* Also unmute the mono-out pin widget */
4770 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4772 /* Mute capture amp left and right */
4773 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4774 /* Set ADC connection select to match default mixer setting (mic1
4777 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4779 /* Do the same for the second ADC: mute capture input amp and
4780 * set ADC connection to mic1 pin
4782 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4783 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4785 /* Mute all inputs to mixer widget (even unconnected ones) */
4786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4799 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
4800 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
4802 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4803 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4806 * for BIOS auto-configuration
4809 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4813 unsigned long vol_val, sw_val;
4817 if (nid >= 0x0f && nid < 0x11) {
4818 nid_vol = nid - 0x7;
4819 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4820 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4821 } else if (nid == 0x11) {
4822 nid_vol = nid - 0x7;
4823 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4824 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4825 } else if (nid >= 0x12 && nid <= 0x15) {
4827 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4828 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4832 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4833 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4836 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4837 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4843 /* add playback controls from the parsed DAC table */
4844 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4845 const struct auto_pin_cfg *cfg)
4850 spec->multiout.num_dacs = 1;
4851 spec->multiout.dac_nids = spec->private_dac_nids;
4852 spec->multiout.dac_nids[0] = 0x02;
4854 nid = cfg->line_out_pins[0];
4856 err = alc260_add_playback_controls(spec, nid, "Front");
4861 nid = cfg->speaker_pins[0];
4863 err = alc260_add_playback_controls(spec, nid, "Speaker");
4868 nid = cfg->hp_pins[0];
4870 err = alc260_add_playback_controls(spec, nid, "Headphone");
4877 /* create playback/capture controls for input pins */
4878 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4879 const struct auto_pin_cfg *cfg)
4881 struct hda_input_mux *imux = &spec->private_imux;
4884 for (i = 0; i < AUTO_PIN_LAST; i++) {
4885 if (cfg->input_pins[i] >= 0x12) {
4886 idx = cfg->input_pins[i] - 0x12;
4887 err = new_analog_input(spec, cfg->input_pins[i],
4888 auto_pin_cfg_labels[i], idx,
4892 imux->items[imux->num_items].label =
4893 auto_pin_cfg_labels[i];
4894 imux->items[imux->num_items].index = idx;
4897 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4898 idx = cfg->input_pins[i] - 0x09;
4899 err = new_analog_input(spec, cfg->input_pins[i],
4900 auto_pin_cfg_labels[i], idx,
4904 imux->items[imux->num_items].label =
4905 auto_pin_cfg_labels[i];
4906 imux->items[imux->num_items].index = idx;
4913 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4914 hda_nid_t nid, int pin_type,
4917 alc_set_pin_output(codec, nid, pin_type);
4918 /* need the manual connection? */
4920 int idx = nid - 0x12;
4921 snd_hda_codec_write(codec, idx + 0x0b, 0,
4922 AC_VERB_SET_CONNECT_SEL, sel_idx);
4926 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4928 struct alc_spec *spec = codec->spec;
4931 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4932 nid = spec->autocfg.line_out_pins[0];
4934 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4935 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4938 nid = spec->autocfg.speaker_pins[0];
4940 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4942 nid = spec->autocfg.hp_pins[0];
4944 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4947 #define ALC260_PIN_CD_NID 0x16
4948 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4950 struct alc_spec *spec = codec->spec;
4953 for (i = 0; i < AUTO_PIN_LAST; i++) {
4954 hda_nid_t nid = spec->autocfg.input_pins[i];
4956 snd_hda_codec_write(codec, nid, 0,
4957 AC_VERB_SET_PIN_WIDGET_CONTROL,
4958 i <= AUTO_PIN_FRONT_MIC ?
4959 PIN_VREF80 : PIN_IN);
4960 if (nid != ALC260_PIN_CD_NID)
4961 snd_hda_codec_write(codec, nid, 0,
4962 AC_VERB_SET_AMP_GAIN_MUTE,
4969 * generic initialization of ADC, input mixers and output mixers
4971 static struct hda_verb alc260_volume_init_verbs[] = {
4973 * Unmute ADC0-1 and set the default input to mic-in
4975 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4976 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4977 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4978 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4980 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4982 * Note: PASD motherboards uses the Line In 2 as the input for
4983 * front panel mic (mic 2)
4985 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4986 /* mute analog inputs */
4987 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4988 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4994 * Set up output mixers (0x08 - 0x0a)
4996 /* set vol=0 to output mixers */
4997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4998 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4999 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5000 /* set up input amps for analog loopback */
5001 /* Amp Indices: DAC = 0, mixer = 1 */
5002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5003 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5004 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5006 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5007 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5012 static int alc260_parse_auto_config(struct hda_codec *codec)
5014 struct alc_spec *spec = codec->spec;
5017 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5019 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5023 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5026 if (!spec->kctl_alloc)
5027 return 0; /* can't find valid BIOS pin config */
5028 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5032 spec->multiout.max_channels = 2;
5034 if (spec->autocfg.dig_out_pin)
5035 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5036 if (spec->kctl_alloc)
5037 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
5039 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
5041 spec->num_mux_defs = 1;
5042 spec->input_mux = &spec->private_imux;
5044 /* check whether NID 0x04 is valid */
5045 wcap = get_wcaps(codec, 0x04);
5046 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5047 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5048 spec->adc_nids = alc260_adc_nids_alt;
5049 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5050 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5052 spec->adc_nids = alc260_adc_nids;
5053 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5054 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5061 /* additional initialization for auto-configuration model */
5062 static void alc260_auto_init(struct hda_codec *codec)
5064 struct alc_spec *spec = codec->spec;
5065 alc260_auto_init_multi_out(codec);
5066 alc260_auto_init_analog_input(codec);
5067 if (spec->unsol_event)
5068 alc_sku_automute(codec);
5071 #ifdef CONFIG_SND_HDA_POWER_SAVE
5072 static struct hda_amp_list alc260_loopbacks[] = {
5073 { 0x07, HDA_INPUT, 0 },
5074 { 0x07, HDA_INPUT, 1 },
5075 { 0x07, HDA_INPUT, 2 },
5076 { 0x07, HDA_INPUT, 3 },
5077 { 0x07, HDA_INPUT, 4 },
5083 * ALC260 configurations
5085 static const char *alc260_models[ALC260_MODEL_LAST] = {
5086 [ALC260_BASIC] = "basic",
5088 [ALC260_HP_3013] = "hp-3013",
5089 [ALC260_FUJITSU_S702X] = "fujitsu",
5090 [ALC260_ACER] = "acer",
5091 [ALC260_WILL] = "will",
5092 [ALC260_REPLACER_672V] = "replacer",
5093 #ifdef CONFIG_SND_DEBUG
5094 [ALC260_TEST] = "test",
5096 [ALC260_AUTO] = "auto",
5099 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5100 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5101 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5102 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5103 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5104 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5105 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
5106 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
5107 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5108 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5109 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5110 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5111 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5112 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5113 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5114 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5115 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5116 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5117 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5121 static struct alc_config_preset alc260_presets[] = {
5123 .mixers = { alc260_base_output_mixer,
5125 alc260_pc_beep_mixer,
5126 alc260_capture_mixer },
5127 .init_verbs = { alc260_init_verbs },
5128 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5129 .dac_nids = alc260_dac_nids,
5130 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5131 .adc_nids = alc260_adc_nids,
5132 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5133 .channel_mode = alc260_modes,
5134 .input_mux = &alc260_capture_source,
5137 .mixers = { alc260_hp_output_mixer,
5139 alc260_capture_alt_mixer },
5140 .init_verbs = { alc260_init_verbs,
5141 alc260_hp_unsol_verbs },
5142 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5143 .dac_nids = alc260_dac_nids,
5144 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5145 .adc_nids = alc260_hp_adc_nids,
5146 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5147 .channel_mode = alc260_modes,
5148 .input_mux = &alc260_capture_source,
5149 .unsol_event = alc260_hp_unsol_event,
5150 .init_hook = alc260_hp_automute,
5152 [ALC260_HP_3013] = {
5153 .mixers = { alc260_hp_3013_mixer,
5155 alc260_capture_alt_mixer },
5156 .init_verbs = { alc260_hp_3013_init_verbs,
5157 alc260_hp_3013_unsol_verbs },
5158 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5159 .dac_nids = alc260_dac_nids,
5160 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5161 .adc_nids = alc260_hp_adc_nids,
5162 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5163 .channel_mode = alc260_modes,
5164 .input_mux = &alc260_capture_source,
5165 .unsol_event = alc260_hp_3013_unsol_event,
5166 .init_hook = alc260_hp_3013_automute,
5168 [ALC260_FUJITSU_S702X] = {
5169 .mixers = { alc260_fujitsu_mixer,
5170 alc260_capture_mixer },
5171 .init_verbs = { alc260_fujitsu_init_verbs },
5172 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5173 .dac_nids = alc260_dac_nids,
5174 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5175 .adc_nids = alc260_dual_adc_nids,
5176 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5177 .channel_mode = alc260_modes,
5178 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5179 .input_mux = alc260_fujitsu_capture_sources,
5182 .mixers = { alc260_acer_mixer,
5183 alc260_capture_mixer },
5184 .init_verbs = { alc260_acer_init_verbs },
5185 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5186 .dac_nids = alc260_dac_nids,
5187 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5188 .adc_nids = alc260_dual_adc_nids,
5189 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5190 .channel_mode = alc260_modes,
5191 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5192 .input_mux = alc260_acer_capture_sources,
5195 .mixers = { alc260_will_mixer,
5196 alc260_capture_mixer },
5197 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5198 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5199 .dac_nids = alc260_dac_nids,
5200 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5201 .adc_nids = alc260_adc_nids,
5202 .dig_out_nid = ALC260_DIGOUT_NID,
5203 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5204 .channel_mode = alc260_modes,
5205 .input_mux = &alc260_capture_source,
5207 [ALC260_REPLACER_672V] = {
5208 .mixers = { alc260_replacer_672v_mixer,
5209 alc260_capture_mixer },
5210 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5211 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5212 .dac_nids = alc260_dac_nids,
5213 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5214 .adc_nids = alc260_adc_nids,
5215 .dig_out_nid = ALC260_DIGOUT_NID,
5216 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5217 .channel_mode = alc260_modes,
5218 .input_mux = &alc260_capture_source,
5219 .unsol_event = alc260_replacer_672v_unsol_event,
5220 .init_hook = alc260_replacer_672v_automute,
5222 #ifdef CONFIG_SND_DEBUG
5224 .mixers = { alc260_test_mixer,
5225 alc260_capture_mixer },
5226 .init_verbs = { alc260_test_init_verbs },
5227 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5228 .dac_nids = alc260_test_dac_nids,
5229 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5230 .adc_nids = alc260_test_adc_nids,
5231 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5232 .channel_mode = alc260_modes,
5233 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5234 .input_mux = alc260_test_capture_sources,
5239 static int patch_alc260(struct hda_codec *codec)
5241 struct alc_spec *spec;
5242 int err, board_config;
5244 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5250 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5253 if (board_config < 0) {
5254 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5255 "trying auto-probe from BIOS...\n");
5256 board_config = ALC260_AUTO;
5259 if (board_config == ALC260_AUTO) {
5260 /* automatic parse from the BIOS config */
5261 err = alc260_parse_auto_config(codec);
5267 "hda_codec: Cannot set up configuration "
5268 "from BIOS. Using base mode...\n");
5269 board_config = ALC260_BASIC;
5273 if (board_config != ALC260_AUTO)
5274 setup_preset(spec, &alc260_presets[board_config]);
5276 spec->stream_name_analog = "ALC260 Analog";
5277 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5278 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5280 spec->stream_name_digital = "ALC260 Digital";
5281 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5282 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5284 spec->vmaster_nid = 0x08;
5286 codec->patch_ops = alc_patch_ops;
5287 if (board_config == ALC260_AUTO)
5288 spec->init_hook = alc260_auto_init;
5289 #ifdef CONFIG_SND_HDA_POWER_SAVE
5290 if (!spec->loopback.amplist)
5291 spec->loopback.amplist = alc260_loopbacks;
5301 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5302 * configuration. Each pin widget can choose any input DACs and a mixer.
5303 * Each ADC is connected from a mixer of all inputs. This makes possible
5304 * 6-channel independent captures.
5306 * In addition, an independent DAC for the multi-playback (not used in this
5309 #define ALC882_DIGOUT_NID 0x06
5310 #define ALC882_DIGIN_NID 0x0a
5312 static struct hda_channel_mode alc882_ch_modes[1] = {
5316 static hda_nid_t alc882_dac_nids[4] = {
5317 /* front, rear, clfe, rear_surr */
5318 0x02, 0x03, 0x04, 0x05
5321 /* identical with ALC880 */
5322 #define alc882_adc_nids alc880_adc_nids
5323 #define alc882_adc_nids_alt alc880_adc_nids_alt
5325 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5326 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5329 /* FIXME: should be a matrix-type input source selection */
5331 static struct hda_input_mux alc882_capture_source = {
5335 { "Front Mic", 0x1 },
5340 #define alc882_mux_enum_info alc_mux_enum_info
5341 #define alc882_mux_enum_get alc_mux_enum_get
5343 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5344 struct snd_ctl_elem_value *ucontrol)
5346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5347 struct alc_spec *spec = codec->spec;
5348 const struct hda_input_mux *imux = spec->input_mux;
5349 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5350 hda_nid_t nid = spec->capsrc_nids ?
5351 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5352 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5353 unsigned int i, idx;
5355 idx = ucontrol->value.enumerated.item[0];
5356 if (idx >= imux->num_items)
5357 idx = imux->num_items - 1;
5358 if (*cur_val == idx)
5360 for (i = 0; i < imux->num_items; i++) {
5361 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5362 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5363 imux->items[i].index,
5373 static struct hda_verb alc882_3ST_ch2_init[] = {
5374 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5375 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5376 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5377 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5384 static struct hda_verb alc882_3ST_ch6_init[] = {
5385 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5386 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5387 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5388 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5389 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5390 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5394 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5395 { 2, alc882_3ST_ch2_init },
5396 { 6, alc882_3ST_ch6_init },
5402 static struct hda_verb alc882_sixstack_ch6_init[] = {
5403 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5404 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5405 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5406 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5413 static struct hda_verb alc882_sixstack_ch8_init[] = {
5414 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5415 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5416 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5417 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5421 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5422 { 6, alc882_sixstack_ch6_init },
5423 { 8, alc882_sixstack_ch8_init },
5427 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5433 static struct hda_verb alc885_mbp_ch2_init[] = {
5434 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5435 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5436 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5443 static struct hda_verb alc885_mbp_ch6_init[] = {
5444 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5445 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5446 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5447 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5448 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5452 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5453 { 2, alc885_mbp_ch2_init },
5454 { 6, alc885_mbp_ch6_init },
5458 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5459 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5461 static struct snd_kcontrol_new alc882_base_mixer[] = {
5462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5464 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5465 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5466 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5467 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5468 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5469 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5470 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5471 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5473 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5474 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5475 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5476 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5478 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5480 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5481 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5483 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5484 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5488 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5489 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5490 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5491 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5492 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5493 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5494 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5496 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5497 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5498 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5501 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5502 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5503 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5509 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5511 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5512 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5516 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5518 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5520 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5521 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5525 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5526 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5527 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5528 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5529 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5533 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5534 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5536 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5537 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5538 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5539 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5540 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5541 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5542 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5545 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5546 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5549 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5553 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5554 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5555 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5556 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5557 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5558 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5559 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5560 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5561 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5562 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5563 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5564 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5565 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5569 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5572 .name = "Channel Mode",
5573 .info = alc_ch_mode_info,
5574 .get = alc_ch_mode_get,
5575 .put = alc_ch_mode_put,
5580 static struct hda_verb alc882_init_verbs[] = {
5581 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5583 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5586 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5587 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5588 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5590 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5598 /* Front Pin: output 0 (0x0c) */
5599 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5601 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5602 /* Rear Pin: output 1 (0x0d) */
5603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5606 /* CLFE Pin: output 2 (0x0e) */
5607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5609 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5610 /* Side Pin: output 3 (0x0f) */
5611 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5612 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5613 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5614 /* Mic (rear) pin: input vref at 80% */
5615 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5616 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5617 /* Front Mic pin: input vref at 80% */
5618 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5620 /* Line In pin: input */
5621 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5622 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5623 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5624 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5625 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5626 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5627 /* CD pin widget for input */
5628 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5630 /* FIXME: use matrix-type input source selection */
5631 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5632 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5633 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5634 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5635 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5636 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5638 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5639 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5640 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5641 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5643 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5644 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5645 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5646 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5647 /* ADC1: mute amp left and right */
5648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5649 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5650 /* ADC2: mute amp left and right */
5651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5652 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5653 /* ADC3: mute amp left and right */
5654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5655 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5660 static struct hda_verb alc882_eapd_verbs[] = {
5661 /* change to EAPD mode */
5662 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5663 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5668 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5672 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5673 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5674 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5675 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5679 static struct hda_verb alc882_macpro_init_verbs[] = {
5680 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5682 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5683 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5684 /* Front Pin: output 0 (0x0c) */
5685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5687 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5688 /* Front Mic pin: input vref at 80% */
5689 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5690 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5691 /* Speaker: output */
5692 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5693 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5694 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5695 /* Headphone output (output 0 - 0x0c) */
5696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5700 /* FIXME: use matrix-type input source selection */
5701 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5702 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5703 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5704 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5708 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5709 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5710 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5714 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5715 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5717 /* ADC1: mute amp left and right */
5718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5719 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5720 /* ADC2: mute amp left and right */
5721 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5722 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5723 /* ADC3: mute amp left and right */
5724 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5725 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5730 /* Macbook Pro rev3 */
5731 static struct hda_verb alc885_mbp3_init_verbs[] = {
5732 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5739 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5740 /* Front Pin: output 0 (0x0c) */
5741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5743 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5744 /* HP Pin: output 0 (0x0d) */
5745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5747 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5748 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5749 /* Mic (rear) pin: input vref at 80% */
5750 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5751 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5752 /* Front Mic pin: input vref at 80% */
5753 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5754 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5755 /* Line In pin: use output 1 when in LineOut mode */
5756 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5757 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5758 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5760 /* FIXME: use matrix-type input source selection */
5761 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5762 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5771 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5777 /* ADC1: mute amp left and right */
5778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5779 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5780 /* ADC2: mute amp left and right */
5781 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5782 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5783 /* ADC3: mute amp left and right */
5784 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5785 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5790 /* iMac 24 mixer. */
5791 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5792 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5793 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5797 /* iMac 24 init verbs. */
5798 static struct hda_verb alc885_imac24_init_verbs[] = {
5799 /* Internal speakers: output 0 (0x0c) */
5800 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5801 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5802 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5803 /* Internal speakers: output 0 (0x0c) */
5804 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5805 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5806 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5807 /* Headphone: output 0 (0x0c) */
5808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5810 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5811 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5812 /* Front Mic: input vref at 80% */
5813 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5814 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5818 /* Toggle speaker-output according to the hp-jack state */
5819 static void alc885_imac24_automute(struct hda_codec *codec)
5821 unsigned int present;
5823 present = snd_hda_codec_read(codec, 0x14, 0,
5824 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5825 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5826 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5827 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5828 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5831 /* Processes unsolicited events. */
5832 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5835 /* Headphone insertion or removal. */
5836 if ((res >> 26) == ALC880_HP_EVENT)
5837 alc885_imac24_automute(codec);
5840 static void alc885_mbp3_automute(struct hda_codec *codec)
5842 unsigned int present;
5844 present = snd_hda_codec_read(codec, 0x15, 0,
5845 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5846 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
5847 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5848 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5849 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5852 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5855 /* Headphone insertion or removal. */
5856 if ((res >> 26) == ALC880_HP_EVENT)
5857 alc885_mbp3_automute(codec);
5861 static struct hda_verb alc882_targa_verbs[] = {
5862 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5863 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5865 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5866 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5868 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5869 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5870 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5872 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5873 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5874 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5875 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5879 /* toggle speaker-output according to the hp-jack state */
5880 static void alc882_targa_automute(struct hda_codec *codec)
5882 unsigned int present;
5884 present = snd_hda_codec_read(codec, 0x14, 0,
5885 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5886 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5887 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5888 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5892 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5894 /* Looks like the unsol event is incompatible with the standard
5895 * definition. 4bit tag is placed at 26 bit!
5897 if (((res >> 26) == ALC880_HP_EVENT)) {
5898 alc882_targa_automute(codec);
5902 static struct hda_verb alc882_asus_a7j_verbs[] = {
5903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5907 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5908 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5910 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5911 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5912 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5914 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5915 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5916 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5920 static struct hda_verb alc882_asus_a7m_verbs[] = {
5921 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5924 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5925 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5926 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5928 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5929 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5930 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5932 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5934 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5938 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5940 unsigned int gpiostate, gpiomask, gpiodir;
5942 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5943 AC_VERB_GET_GPIO_DATA, 0);
5946 gpiostate |= (1 << pin);
5948 gpiostate &= ~(1 << pin);
5950 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5951 AC_VERB_GET_GPIO_MASK, 0);
5952 gpiomask |= (1 << pin);
5954 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5955 AC_VERB_GET_GPIO_DIRECTION, 0);
5956 gpiodir |= (1 << pin);
5959 snd_hda_codec_write(codec, codec->afg, 0,
5960 AC_VERB_SET_GPIO_MASK, gpiomask);
5961 snd_hda_codec_write(codec, codec->afg, 0,
5962 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5966 snd_hda_codec_write(codec, codec->afg, 0,
5967 AC_VERB_SET_GPIO_DATA, gpiostate);
5970 /* set up GPIO at initialization */
5971 static void alc885_macpro_init_hook(struct hda_codec *codec)
5973 alc882_gpio_mute(codec, 0, 0);
5974 alc882_gpio_mute(codec, 1, 0);
5977 /* set up GPIO and update auto-muting at initialization */
5978 static void alc885_imac24_init_hook(struct hda_codec *codec)
5980 alc885_macpro_init_hook(codec);
5981 alc885_imac24_automute(codec);
5985 * generic initialization of ADC, input mixers and output mixers
5987 static struct hda_verb alc882_auto_init_verbs[] = {
5989 * Unmute ADC0-2 and set the default input to mic-in
5991 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5993 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5995 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5996 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5998 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6000 * Note: PASD motherboards uses the Line In 2 as the input for
6001 * front panel mic (mic 2)
6003 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6004 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6005 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6006 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6011 * Set up output mixers (0x0c - 0x0f)
6013 /* set vol=0 to output mixers */
6014 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6015 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6016 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6017 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6018 /* set up input amps for analog loopback */
6019 /* Amp Indices: DAC = 0, mixer = 1 */
6020 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6021 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6022 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6023 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6024 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6025 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6026 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6027 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6028 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6029 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6031 /* FIXME: use matrix-type input source selection */
6032 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6033 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6034 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6039 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6041 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6042 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6044 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6052 /* capture mixer elements */
6053 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6054 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6055 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6056 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6057 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6060 /* The multiple "Capture Source" controls confuse alsamixer
6061 * So call somewhat different..
6063 /* .name = "Capture Source", */
6064 .name = "Input Source",
6066 .info = alc882_mux_enum_info,
6067 .get = alc882_mux_enum_get,
6068 .put = alc882_mux_enum_put,
6073 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6074 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6075 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6076 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6077 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6078 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6079 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6082 /* The multiple "Capture Source" controls confuse alsamixer
6083 * So call somewhat different..
6085 /* .name = "Capture Source", */
6086 .name = "Input Source",
6088 .info = alc882_mux_enum_info,
6089 .get = alc882_mux_enum_get,
6090 .put = alc882_mux_enum_put,
6095 #ifdef CONFIG_SND_HDA_POWER_SAVE
6096 #define alc882_loopbacks alc880_loopbacks
6099 /* pcm configuration: identiacal with ALC880 */
6100 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6101 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6102 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6103 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6106 * configuration and preset
6108 static const char *alc882_models[ALC882_MODEL_LAST] = {
6109 [ALC882_3ST_DIG] = "3stack-dig",
6110 [ALC882_6ST_DIG] = "6stack-dig",
6111 [ALC882_ARIMA] = "arima",
6112 [ALC882_W2JC] = "w2jc",
6113 [ALC882_TARGA] = "targa",
6114 [ALC882_ASUS_A7J] = "asus-a7j",
6115 [ALC882_ASUS_A7M] = "asus-a7m",
6116 [ALC885_MACPRO] = "macpro",
6117 [ALC885_MBP3] = "mbp3",
6118 [ALC885_IMAC24] = "imac24",
6119 [ALC882_AUTO] = "auto",
6122 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6123 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6124 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6125 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6126 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6127 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6128 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6129 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6130 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6131 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6132 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6133 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6134 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6138 static struct alc_config_preset alc882_presets[] = {
6139 [ALC882_3ST_DIG] = {
6140 .mixers = { alc882_base_mixer },
6141 .init_verbs = { alc882_init_verbs },
6142 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6143 .dac_nids = alc882_dac_nids,
6144 .dig_out_nid = ALC882_DIGOUT_NID,
6145 .dig_in_nid = ALC882_DIGIN_NID,
6146 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6147 .channel_mode = alc882_ch_modes,
6149 .input_mux = &alc882_capture_source,
6151 [ALC882_6ST_DIG] = {
6152 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6153 .init_verbs = { alc882_init_verbs },
6154 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6155 .dac_nids = alc882_dac_nids,
6156 .dig_out_nid = ALC882_DIGOUT_NID,
6157 .dig_in_nid = ALC882_DIGIN_NID,
6158 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6159 .channel_mode = alc882_sixstack_modes,
6160 .input_mux = &alc882_capture_source,
6163 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6164 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6165 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6166 .dac_nids = alc882_dac_nids,
6167 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6168 .channel_mode = alc882_sixstack_modes,
6169 .input_mux = &alc882_capture_source,
6172 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6173 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6174 alc880_gpio1_init_verbs },
6175 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6176 .dac_nids = alc882_dac_nids,
6177 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6178 .channel_mode = alc880_threestack_modes,
6180 .input_mux = &alc882_capture_source,
6181 .dig_out_nid = ALC882_DIGOUT_NID,
6184 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6185 .init_verbs = { alc885_mbp3_init_verbs,
6186 alc880_gpio1_init_verbs },
6187 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6188 .dac_nids = alc882_dac_nids,
6189 .channel_mode = alc885_mbp_6ch_modes,
6190 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6191 .input_mux = &alc882_capture_source,
6192 .dig_out_nid = ALC882_DIGOUT_NID,
6193 .dig_in_nid = ALC882_DIGIN_NID,
6194 .unsol_event = alc885_mbp3_unsol_event,
6195 .init_hook = alc885_mbp3_automute,
6198 .mixers = { alc882_macpro_mixer },
6199 .init_verbs = { alc882_macpro_init_verbs },
6200 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6201 .dac_nids = alc882_dac_nids,
6202 .dig_out_nid = ALC882_DIGOUT_NID,
6203 .dig_in_nid = ALC882_DIGIN_NID,
6204 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6205 .channel_mode = alc882_ch_modes,
6206 .input_mux = &alc882_capture_source,
6207 .init_hook = alc885_macpro_init_hook,
6210 .mixers = { alc885_imac24_mixer },
6211 .init_verbs = { alc885_imac24_init_verbs },
6212 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6213 .dac_nids = alc882_dac_nids,
6214 .dig_out_nid = ALC882_DIGOUT_NID,
6215 .dig_in_nid = ALC882_DIGIN_NID,
6216 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6217 .channel_mode = alc882_ch_modes,
6218 .input_mux = &alc882_capture_source,
6219 .unsol_event = alc885_imac24_unsol_event,
6220 .init_hook = alc885_imac24_init_hook,
6223 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6224 alc882_capture_mixer },
6225 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6226 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6227 .dac_nids = alc882_dac_nids,
6228 .dig_out_nid = ALC882_DIGOUT_NID,
6229 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6230 .adc_nids = alc882_adc_nids,
6231 .capsrc_nids = alc882_capsrc_nids,
6232 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6233 .channel_mode = alc882_3ST_6ch_modes,
6235 .input_mux = &alc882_capture_source,
6236 .unsol_event = alc882_targa_unsol_event,
6237 .init_hook = alc882_targa_automute,
6239 [ALC882_ASUS_A7J] = {
6240 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6241 alc882_capture_mixer },
6242 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6243 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6244 .dac_nids = alc882_dac_nids,
6245 .dig_out_nid = ALC882_DIGOUT_NID,
6246 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6247 .adc_nids = alc882_adc_nids,
6248 .capsrc_nids = alc882_capsrc_nids,
6249 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6250 .channel_mode = alc882_3ST_6ch_modes,
6252 .input_mux = &alc882_capture_source,
6254 [ALC882_ASUS_A7M] = {
6255 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6256 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6257 alc880_gpio1_init_verbs,
6258 alc882_asus_a7m_verbs },
6259 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6260 .dac_nids = alc882_dac_nids,
6261 .dig_out_nid = ALC882_DIGOUT_NID,
6262 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6263 .channel_mode = alc880_threestack_modes,
6265 .input_mux = &alc882_capture_source,
6274 PINFIX_ABIT_AW9D_MAX
6277 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6278 { 0x15, 0x01080104 }, /* side */
6279 { 0x16, 0x01011012 }, /* rear */
6280 { 0x17, 0x01016011 }, /* clfe */
6284 static const struct alc_pincfg *alc882_pin_fixes[] = {
6285 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6288 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6289 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6294 * BIOS auto configuration
6296 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6297 hda_nid_t nid, int pin_type,
6301 struct alc_spec *spec = codec->spec;
6304 alc_set_pin_output(codec, nid, pin_type);
6305 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6308 idx = spec->multiout.dac_nids[dac_idx] - 2;
6309 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6313 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6315 struct alc_spec *spec = codec->spec;
6318 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6319 for (i = 0; i <= HDA_SIDE; i++) {
6320 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6321 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6323 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6328 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6330 struct alc_spec *spec = codec->spec;
6333 pin = spec->autocfg.hp_pins[0];
6334 if (pin) /* connect to front */
6336 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6337 pin = spec->autocfg.speaker_pins[0];
6339 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6342 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6343 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6345 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6347 struct alc_spec *spec = codec->spec;
6350 for (i = 0; i < AUTO_PIN_LAST; i++) {
6351 hda_nid_t nid = spec->autocfg.input_pins[i];
6356 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6357 if (snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP) &
6361 snd_hda_codec_write(codec, nid, 0,
6362 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6363 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6364 snd_hda_codec_write(codec, nid, 0,
6365 AC_VERB_SET_AMP_GAIN_MUTE,
6370 /* add mic boosts if needed */
6371 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6373 struct alc_spec *spec = codec->spec;
6377 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6378 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6379 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6381 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6385 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6386 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6387 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6389 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6396 /* almost identical with ALC880 parser... */
6397 static int alc882_parse_auto_config(struct hda_codec *codec)
6399 struct alc_spec *spec = codec->spec;
6400 int err = alc880_parse_auto_config(codec);
6405 return 0; /* no config found */
6407 err = alc_auto_add_mic_boost(codec);
6411 /* hack - override the init verbs */
6412 spec->init_verbs[0] = alc882_auto_init_verbs;
6414 return 1; /* config found */
6417 /* additional initialization for auto-configuration model */
6418 static void alc882_auto_init(struct hda_codec *codec)
6420 struct alc_spec *spec = codec->spec;
6421 alc882_auto_init_multi_out(codec);
6422 alc882_auto_init_hp_out(codec);
6423 alc882_auto_init_analog_input(codec);
6424 if (spec->unsol_event)
6425 alc_sku_automute(codec);
6428 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6430 static int patch_alc882(struct hda_codec *codec)
6432 struct alc_spec *spec;
6433 int err, board_config;
6435 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6441 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6445 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6446 /* Pick up systems that don't supply PCI SSID */
6447 switch (codec->subsystem_id) {
6448 case 0x106b0c00: /* Mac Pro */
6449 board_config = ALC885_MACPRO;
6451 case 0x106b1000: /* iMac 24 */
6452 board_config = ALC885_IMAC24;
6454 case 0x106b00a1: /* Macbook */
6455 case 0x106b2c00: /* Macbook Pro rev3 */
6456 board_config = ALC885_MBP3;
6459 /* ALC889A is handled better as ALC888-compatible */
6460 if (codec->revision_id == 0x100103) {
6462 return patch_alc883(codec);
6464 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6465 "trying auto-probe from BIOS...\n");
6466 board_config = ALC882_AUTO;
6470 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6472 if (board_config == ALC882_AUTO) {
6473 /* automatic parse from the BIOS config */
6474 err = alc882_parse_auto_config(codec);
6480 "hda_codec: Cannot set up configuration "
6481 "from BIOS. Using base mode...\n");
6482 board_config = ALC882_3ST_DIG;
6486 if (board_config != ALC882_AUTO)
6487 setup_preset(spec, &alc882_presets[board_config]);
6489 spec->stream_name_analog = "ALC882 Analog";
6490 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6491 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6492 /* FIXME: setup DAC5 */
6493 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6494 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6496 spec->stream_name_digital = "ALC882 Digital";
6497 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6498 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6500 if (!spec->adc_nids && spec->input_mux) {
6501 /* check whether NID 0x07 is valid */
6502 unsigned int wcap = get_wcaps(codec, 0x07);
6504 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6505 if (wcap != AC_WID_AUD_IN) {
6506 spec->adc_nids = alc882_adc_nids_alt;
6507 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6508 spec->capsrc_nids = alc882_capsrc_nids_alt;
6509 spec->mixers[spec->num_mixers] =
6510 alc882_capture_alt_mixer;
6513 spec->adc_nids = alc882_adc_nids;
6514 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6515 spec->capsrc_nids = alc882_capsrc_nids;
6516 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6521 spec->vmaster_nid = 0x0c;
6523 codec->patch_ops = alc_patch_ops;
6524 if (board_config == ALC882_AUTO)
6525 spec->init_hook = alc882_auto_init;
6526 #ifdef CONFIG_SND_HDA_POWER_SAVE
6527 if (!spec->loopback.amplist)
6528 spec->loopback.amplist = alc882_loopbacks;
6537 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6538 * configuration. Each pin widget can choose any input DACs and a mixer.
6539 * Each ADC is connected from a mixer of all inputs. This makes possible
6540 * 6-channel independent captures.
6542 * In addition, an independent DAC for the multi-playback (not used in this
6545 #define ALC883_DIGOUT_NID 0x06
6546 #define ALC883_DIGIN_NID 0x0a
6548 static hda_nid_t alc883_dac_nids[4] = {
6549 /* front, rear, clfe, rear_surr */
6550 0x02, 0x03, 0x04, 0x05
6553 static hda_nid_t alc883_adc_nids[2] = {
6558 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6561 /* FIXME: should be a matrix-type input source selection */
6563 static struct hda_input_mux alc883_capture_source = {
6567 { "Front Mic", 0x1 },
6573 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6581 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6591 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6599 #define alc883_mux_enum_info alc_mux_enum_info
6600 #define alc883_mux_enum_get alc_mux_enum_get
6601 /* ALC883 has the ALC882-type input selection */
6602 #define alc883_mux_enum_put alc882_mux_enum_put
6607 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6614 static struct hda_verb alc883_3ST_ch2_init[] = {
6615 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6616 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6625 static struct hda_verb alc883_3ST_ch4_init[] = {
6626 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6627 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6628 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6629 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6630 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6637 static struct hda_verb alc883_3ST_ch6_init[] = {
6638 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6639 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6640 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6643 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6647 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6648 { 2, alc883_3ST_ch2_init },
6649 { 4, alc883_3ST_ch4_init },
6650 { 6, alc883_3ST_ch6_init },
6656 static struct hda_verb alc883_sixstack_ch6_init[] = {
6657 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6658 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6659 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6660 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6667 static struct hda_verb alc883_sixstack_ch8_init[] = {
6668 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6669 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6670 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6671 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6675 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6676 { 6, alc883_sixstack_ch6_init },
6677 { 8, alc883_sixstack_ch8_init },
6680 static struct hda_verb alc883_medion_eapd_verbs[] = {
6681 /* eanable EAPD on medion laptop */
6682 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6683 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6687 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6688 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6691 static struct snd_kcontrol_new alc883_base_mixer[] = {
6692 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6693 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6694 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6695 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6696 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6697 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6698 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6699 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6700 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6701 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6702 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6703 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6704 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6711 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6712 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6713 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6714 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6715 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6716 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6717 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6718 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6720 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6721 /* .name = "Capture Source", */
6722 .name = "Input Source",
6724 .info = alc883_mux_enum_info,
6725 .get = alc883_mux_enum_get,
6726 .put = alc883_mux_enum_put,
6731 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
6732 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6733 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6734 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6735 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6736 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6737 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6738 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6740 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6741 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6742 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6743 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6744 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6747 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6748 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6751 /* .name = "Capture Source", */
6752 .name = "Input Source",
6754 .info = alc883_mux_enum_info,
6755 .get = alc883_mux_enum_get,
6756 .put = alc883_mux_enum_put,
6761 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
6762 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6763 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6764 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6765 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6766 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6767 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6769 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6770 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6771 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6772 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6773 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6774 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6775 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6778 /* .name = "Capture Source", */
6779 .name = "Input Source",
6781 .info = alc883_mux_enum_info,
6782 .get = alc883_mux_enum_get,
6783 .put = alc883_mux_enum_put,
6788 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
6789 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6790 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
6791 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6792 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6796 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6797 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6798 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6799 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6800 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6801 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6802 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6804 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6805 /* .name = "Capture Source", */
6806 .name = "Input Source",
6808 .info = alc883_mux_enum_info,
6809 .get = alc883_mux_enum_get,
6810 .put = alc883_mux_enum_put,
6815 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6816 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6817 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6824 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6825 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6827 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6828 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6829 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6830 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6831 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6832 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6833 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6834 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6837 /* .name = "Capture Source", */
6838 .name = "Input Source",
6840 .info = alc883_mux_enum_info,
6841 .get = alc883_mux_enum_get,
6842 .put = alc883_mux_enum_put,
6847 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6848 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6849 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6850 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6851 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6852 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6853 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6854 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6855 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6856 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6857 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6858 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6859 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6860 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6862 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6864 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6865 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6866 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6867 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6868 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6869 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6870 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6871 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6872 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6874 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6875 /* .name = "Capture Source", */
6876 .name = "Input Source",
6878 .info = alc883_mux_enum_info,
6879 .get = alc883_mux_enum_get,
6880 .put = alc883_mux_enum_put,
6885 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6886 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6887 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6888 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6889 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6890 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6891 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6892 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6893 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6894 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6897 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6898 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6900 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6902 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6903 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6904 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6905 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6906 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6907 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6908 HDA_CODEC_MUTE("Capture Switch", 0x08, 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 alc883_tagra_mixer[] = {
6923 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6924 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6925 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6926 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6927 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6928 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
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("Capture Volume", 0x08, 0x0, HDA_INPUT),
6940 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6941 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6942 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6945 /* .name = "Capture Source", */
6946 .name = "Input Source",
6948 .info = alc883_mux_enum_info,
6949 .get = alc883_mux_enum_get,
6950 .put = alc883_mux_enum_put,
6955 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6957 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6958 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6959 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6960 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6962 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6963 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6964 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6965 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
6966 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6967 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6968 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6969 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6970 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6972 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6973 /* .name = "Capture Source", */
6974 .name = "Input Source",
6976 .info = alc883_mux_enum_info,
6977 .get = alc883_mux_enum_get,
6978 .put = alc883_mux_enum_put,
6983 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6984 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6985 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6986 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6987 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
6988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6992 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6993 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6996 /* .name = "Capture Source", */
6997 .name = "Input Source",
6999 .info = alc883_mux_enum_info,
7000 .get = alc883_mux_enum_get,
7001 .put = alc883_mux_enum_put,
7006 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7007 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7008 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7009 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7010 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7011 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7014 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7015 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7016 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7017 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7018 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7019 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7022 /* .name = "Capture Source", */
7023 .name = "Input Source",
7025 .info = alc883_mux_enum_info,
7026 .get = alc883_mux_enum_get,
7027 .put = alc883_mux_enum_put,
7032 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7033 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7035 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7040 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7041 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7042 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7043 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7044 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7045 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7047 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7048 /* .name = "Capture Source", */
7049 .name = "Input Source",
7051 .info = alc883_mux_enum_info,
7052 .get = alc883_mux_enum_get,
7053 .put = alc883_mux_enum_put,
7058 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7059 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7060 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7065 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7067 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7068 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7069 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7070 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7073 /* .name = "Capture Source", */
7074 .name = "Input Source",
7076 .info = alc883_mux_enum_info,
7077 .get = alc883_mux_enum_get,
7078 .put = alc883_mux_enum_put,
7083 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7086 .name = "Channel Mode",
7087 .info = alc_ch_mode_info,
7088 .get = alc_ch_mode_get,
7089 .put = alc_ch_mode_put,
7094 static struct hda_verb alc883_init_verbs[] = {
7095 /* ADC1: mute amp left and right */
7096 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7097 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7098 /* ADC2: mute amp left and right */
7099 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7100 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7101 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7104 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7115 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7116 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7118 /* mute analog input loopbacks */
7119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7122 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7123 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7125 /* Front Pin: output 0 (0x0c) */
7126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7128 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7129 /* Rear Pin: output 1 (0x0d) */
7130 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7131 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7132 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7133 /* CLFE Pin: output 2 (0x0e) */
7134 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7135 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7136 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7137 /* Side Pin: output 3 (0x0f) */
7138 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7139 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7140 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7141 /* Mic (rear) pin: input vref at 80% */
7142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7143 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7144 /* Front Mic pin: input vref at 80% */
7145 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7146 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7147 /* Line In pin: input */
7148 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7149 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7150 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7151 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7152 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7153 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7154 /* CD pin widget for input */
7155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7157 /* FIXME: use matrix-type input source selection */
7158 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7162 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7172 /* toggle speaker-output according to the hp-jack state */
7173 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7175 unsigned int present;
7177 present = snd_hda_codec_read(codec, 0x15, 0,
7178 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7179 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7180 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7181 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7182 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7185 /* auto-toggle front mic */
7187 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7189 unsigned int present;
7192 present = snd_hda_codec_read(codec, 0x18, 0,
7193 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7194 bits = present ? HDA_AMP_MUTE : 0;
7195 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7199 static void alc883_mitac_automute(struct hda_codec *codec)
7201 alc883_mitac_hp_automute(codec);
7202 /* alc883_mitac_mic_automute(codec); */
7205 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7208 switch (res >> 26) {
7209 case ALC880_HP_EVENT:
7210 alc883_mitac_hp_automute(codec);
7212 case ALC880_MIC_EVENT:
7213 /* alc883_mitac_mic_automute(codec); */
7218 static struct hda_verb alc883_mitac_verbs[] = {
7220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7223 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7224 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7226 /* enable unsolicited event */
7227 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7228 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7233 static struct hda_verb alc883_clevo_m720_verbs[] = {
7235 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7238 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7239 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7241 /* enable unsolicited event */
7242 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7243 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7248 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7250 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7251 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7253 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7254 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7256 /* enable unsolicited event */
7257 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7262 static struct hda_verb alc883_tagra_verbs[] = {
7263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7266 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7267 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7269 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7270 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7271 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7273 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7274 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7275 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7276 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7281 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7282 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7283 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7284 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7288 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7289 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7291 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7296 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7300 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7301 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7305 static struct hda_verb alc883_haier_w66_verbs[] = {
7306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7309 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7311 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7312 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7313 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7318 static struct hda_verb alc888_3st_hp_verbs[] = {
7319 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7320 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7321 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7325 static struct hda_verb alc888_6st_dell_verbs[] = {
7326 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7330 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7331 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7332 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7333 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7334 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7338 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7339 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7340 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7341 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7342 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7346 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7347 { 2, alc888_3st_hp_2ch_init },
7348 { 6, alc888_3st_hp_6ch_init },
7351 /* toggle front-jack and RCA according to the hp-jack state */
7352 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7354 unsigned int present;
7356 present = snd_hda_codec_read(codec, 0x1b, 0,
7357 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7358 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7359 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7360 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7361 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7364 /* toggle RCA according to the front-jack state */
7365 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7367 unsigned int present;
7369 present = snd_hda_codec_read(codec, 0x14, 0,
7370 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7371 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7372 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7375 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7378 if ((res >> 26) == ALC880_HP_EVENT)
7379 alc888_lenovo_ms7195_front_automute(codec);
7380 if ((res >> 26) == ALC880_FRONT_EVENT)
7381 alc888_lenovo_ms7195_rca_automute(codec);
7384 static struct hda_verb alc883_medion_md2_verbs[] = {
7385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7390 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7394 /* toggle speaker-output according to the hp-jack state */
7395 static void alc883_medion_md2_automute(struct hda_codec *codec)
7397 unsigned int present;
7399 present = snd_hda_codec_read(codec, 0x14, 0,
7400 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7401 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7402 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7405 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7408 if ((res >> 26) == ALC880_HP_EVENT)
7409 alc883_medion_md2_automute(codec);
7412 /* toggle speaker-output according to the hp-jack state */
7413 static void alc883_tagra_automute(struct hda_codec *codec)
7415 unsigned int present;
7418 present = snd_hda_codec_read(codec, 0x14, 0,
7419 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7420 bits = present ? HDA_AMP_MUTE : 0;
7421 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7422 HDA_AMP_MUTE, bits);
7423 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7427 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7429 if ((res >> 26) == ALC880_HP_EVENT)
7430 alc883_tagra_automute(codec);
7433 /* toggle speaker-output according to the hp-jack state */
7434 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7436 unsigned int present;
7439 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7440 & AC_PINSENSE_PRESENCE;
7441 bits = present ? HDA_AMP_MUTE : 0;
7442 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7443 HDA_AMP_MUTE, bits);
7446 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7448 unsigned int present;
7450 present = snd_hda_codec_read(codec, 0x18, 0,
7451 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7452 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7453 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7456 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7458 alc883_clevo_m720_hp_automute(codec);
7459 alc883_clevo_m720_mic_automute(codec);
7462 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7465 switch (res >> 26) {
7466 case ALC880_HP_EVENT:
7467 alc883_clevo_m720_hp_automute(codec);
7469 case ALC880_MIC_EVENT:
7470 alc883_clevo_m720_mic_automute(codec);
7475 /* toggle speaker-output according to the hp-jack state */
7476 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
7478 unsigned int present;
7481 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
7482 & AC_PINSENSE_PRESENCE;
7483 bits = present ? HDA_AMP_MUTE : 0;
7484 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7485 HDA_AMP_MUTE, bits);
7488 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
7491 if ((res >> 26) == ALC880_HP_EVENT)
7492 alc883_2ch_fujitsu_pi2515_automute(codec);
7495 static void alc883_haier_w66_automute(struct hda_codec *codec)
7497 unsigned int present;
7500 present = snd_hda_codec_read(codec, 0x1b, 0,
7501 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7502 bits = present ? 0x80 : 0;
7503 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7507 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
7510 if ((res >> 26) == ALC880_HP_EVENT)
7511 alc883_haier_w66_automute(codec);
7514 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
7516 unsigned int present;
7519 present = snd_hda_codec_read(codec, 0x14, 0,
7520 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7521 bits = present ? HDA_AMP_MUTE : 0;
7522 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7523 HDA_AMP_MUTE, bits);
7526 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
7528 unsigned int present;
7531 present = snd_hda_codec_read(codec, 0x1b, 0,
7532 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7533 bits = present ? HDA_AMP_MUTE : 0;
7534 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7535 HDA_AMP_MUTE, bits);
7536 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7537 HDA_AMP_MUTE, bits);
7540 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
7543 if ((res >> 26) == ALC880_HP_EVENT)
7544 alc883_lenovo_101e_all_automute(codec);
7545 if ((res >> 26) == ALC880_FRONT_EVENT)
7546 alc883_lenovo_101e_ispeaker_automute(codec);
7549 /* toggle speaker-output according to the hp-jack state */
7550 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7552 unsigned int present;
7554 present = snd_hda_codec_read(codec, 0x14, 0,
7555 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7556 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7557 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7558 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7559 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7562 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7565 if ((res >> 26) == ALC880_HP_EVENT)
7566 alc883_acer_aspire_automute(codec);
7569 static struct hda_verb alc883_acer_eapd_verbs[] = {
7570 /* HP Pin: output 0 (0x0c) */
7571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7573 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7574 /* Front Pin: output 0 (0x0c) */
7575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7576 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7577 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7578 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7579 /* eanable EAPD on medion laptop */
7580 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7581 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7582 /* enable unsolicited event */
7583 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7587 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
7589 unsigned int present;
7591 present = snd_hda_codec_read(codec, 0x1b, 0,
7592 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7593 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7594 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7595 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7596 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7597 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7598 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7599 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7600 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7603 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
7606 switch (res >> 26) {
7607 case ALC880_HP_EVENT:
7608 printk("hp_event\n");
7609 alc888_6st_dell_front_automute(codec);
7615 * generic initialization of ADC, input mixers and output mixers
7617 static struct hda_verb alc883_auto_init_verbs[] = {
7619 * Unmute ADC0-2 and set the default input to mic-in
7621 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7622 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7623 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7624 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7626 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7628 * Note: PASD motherboards uses the Line In 2 as the input for
7629 * front panel mic (mic 2)
7631 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7639 * Set up output mixers (0x0c - 0x0f)
7641 /* set vol=0 to output mixers */
7642 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7644 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7645 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7646 /* set up input amps for analog loopback */
7647 /* Amp Indices: DAC = 0, mixer = 1 */
7648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7654 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7656 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7657 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7659 /* FIXME: use matrix-type input source selection */
7660 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7665 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7671 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7677 /* capture mixer elements */
7678 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7679 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7680 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7681 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7682 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7684 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7685 /* The multiple "Capture Source" controls confuse alsamixer
7686 * So call somewhat different..
7688 /* .name = "Capture Source", */
7689 .name = "Input Source",
7691 .info = alc882_mux_enum_info,
7692 .get = alc882_mux_enum_get,
7693 .put = alc882_mux_enum_put,
7698 #ifdef CONFIG_SND_HDA_POWER_SAVE
7699 #define alc883_loopbacks alc880_loopbacks
7702 /* pcm configuration: identiacal with ALC880 */
7703 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
7704 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
7705 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
7706 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
7707 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
7710 * configuration and preset
7712 static const char *alc883_models[ALC883_MODEL_LAST] = {
7713 [ALC883_3ST_2ch_DIG] = "3stack-dig",
7714 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
7715 [ALC883_3ST_6ch] = "3stack-6ch",
7716 [ALC883_6ST_DIG] = "6stack-dig",
7717 [ALC883_TARGA_DIG] = "targa-dig",
7718 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
7719 [ALC883_ACER] = "acer",
7720 [ALC883_ACER_ASPIRE] = "acer-aspire",
7721 [ALC883_MEDION] = "medion",
7722 [ALC883_MEDION_MD2] = "medion-md2",
7723 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
7724 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7725 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
7726 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7727 [ALC883_HAIER_W66] = "haier-w66",
7728 [ALC888_3ST_HP] = "3stack-hp",
7729 [ALC888_6ST_DELL] = "6stack-dell",
7730 [ALC883_MITAC] = "mitac",
7731 [ALC883_CLEVO_M720] = "clevo-m720",
7732 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
7733 [ALC883_AUTO] = "auto",
7736 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7737 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7738 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7739 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7740 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7741 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
7742 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
7743 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7744 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7745 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7746 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
7747 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7748 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
7749 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7750 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
7751 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7752 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7753 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7754 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7755 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
7756 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7757 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
7758 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7759 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
7760 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7761 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7762 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7763 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7764 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7765 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7766 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7767 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7768 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7769 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7770 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7771 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7772 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
7773 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7774 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7775 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7776 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7777 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
7778 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
7779 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7780 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7781 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7782 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
7783 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7784 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7785 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7786 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7787 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7788 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
7789 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7790 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7794 static struct alc_config_preset alc883_presets[] = {
7795 [ALC883_3ST_2ch_DIG] = {
7796 .mixers = { alc883_3ST_2ch_mixer },
7797 .init_verbs = { alc883_init_verbs },
7798 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7799 .dac_nids = alc883_dac_nids,
7800 .dig_out_nid = ALC883_DIGOUT_NID,
7801 .dig_in_nid = ALC883_DIGIN_NID,
7802 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7803 .channel_mode = alc883_3ST_2ch_modes,
7804 .input_mux = &alc883_capture_source,
7806 [ALC883_3ST_6ch_DIG] = {
7807 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7808 .init_verbs = { alc883_init_verbs },
7809 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7810 .dac_nids = alc883_dac_nids,
7811 .dig_out_nid = ALC883_DIGOUT_NID,
7812 .dig_in_nid = ALC883_DIGIN_NID,
7813 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7814 .channel_mode = alc883_3ST_6ch_modes,
7816 .input_mux = &alc883_capture_source,
7818 [ALC883_3ST_6ch] = {
7819 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7820 .init_verbs = { alc883_init_verbs },
7821 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7822 .dac_nids = alc883_dac_nids,
7823 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7824 .channel_mode = alc883_3ST_6ch_modes,
7826 .input_mux = &alc883_capture_source,
7828 [ALC883_6ST_DIG] = {
7829 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7830 .init_verbs = { alc883_init_verbs },
7831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7832 .dac_nids = alc883_dac_nids,
7833 .dig_out_nid = ALC883_DIGOUT_NID,
7834 .dig_in_nid = ALC883_DIGIN_NID,
7835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7836 .channel_mode = alc883_sixstack_modes,
7837 .input_mux = &alc883_capture_source,
7839 [ALC883_TARGA_DIG] = {
7840 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7841 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7843 .dac_nids = alc883_dac_nids,
7844 .dig_out_nid = ALC883_DIGOUT_NID,
7845 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7846 .channel_mode = alc883_3ST_6ch_modes,
7848 .input_mux = &alc883_capture_source,
7849 .unsol_event = alc883_tagra_unsol_event,
7850 .init_hook = alc883_tagra_automute,
7852 [ALC883_TARGA_2ch_DIG] = {
7853 .mixers = { alc883_tagra_2ch_mixer},
7854 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7855 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7856 .dac_nids = alc883_dac_nids,
7857 .dig_out_nid = ALC883_DIGOUT_NID,
7858 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7859 .channel_mode = alc883_3ST_2ch_modes,
7860 .input_mux = &alc883_capture_source,
7861 .unsol_event = alc883_tagra_unsol_event,
7862 .init_hook = alc883_tagra_automute,
7865 .mixers = { alc883_base_mixer },
7866 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7867 * and the headphone jack. Turn this on and rely on the
7868 * standard mute methods whenever the user wants to turn
7869 * these outputs off.
7871 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7873 .dac_nids = alc883_dac_nids,
7874 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7875 .channel_mode = alc883_3ST_2ch_modes,
7876 .input_mux = &alc883_capture_source,
7878 [ALC883_ACER_ASPIRE] = {
7879 .mixers = { alc883_acer_aspire_mixer },
7880 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7881 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7882 .dac_nids = alc883_dac_nids,
7883 .dig_out_nid = ALC883_DIGOUT_NID,
7884 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7885 .channel_mode = alc883_3ST_2ch_modes,
7886 .input_mux = &alc883_capture_source,
7887 .unsol_event = alc883_acer_aspire_unsol_event,
7888 .init_hook = alc883_acer_aspire_automute,
7891 .mixers = { alc883_fivestack_mixer,
7892 alc883_chmode_mixer },
7893 .init_verbs = { alc883_init_verbs,
7894 alc883_medion_eapd_verbs },
7895 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7896 .dac_nids = alc883_dac_nids,
7897 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7898 .channel_mode = alc883_sixstack_modes,
7899 .input_mux = &alc883_capture_source,
7901 [ALC883_MEDION_MD2] = {
7902 .mixers = { alc883_medion_md2_mixer},
7903 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7904 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7905 .dac_nids = alc883_dac_nids,
7906 .dig_out_nid = ALC883_DIGOUT_NID,
7907 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7908 .channel_mode = alc883_3ST_2ch_modes,
7909 .input_mux = &alc883_capture_source,
7910 .unsol_event = alc883_medion_md2_unsol_event,
7911 .init_hook = alc883_medion_md2_automute,
7913 [ALC883_LAPTOP_EAPD] = {
7914 .mixers = { alc883_base_mixer },
7915 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7916 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7917 .dac_nids = alc883_dac_nids,
7918 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7919 .channel_mode = alc883_3ST_2ch_modes,
7920 .input_mux = &alc883_capture_source,
7922 [ALC883_CLEVO_M720] = {
7923 .mixers = { alc883_clevo_m720_mixer },
7924 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
7925 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7926 .dac_nids = alc883_dac_nids,
7927 .dig_out_nid = ALC883_DIGOUT_NID,
7928 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7929 .channel_mode = alc883_3ST_2ch_modes,
7930 .input_mux = &alc883_capture_source,
7931 .unsol_event = alc883_clevo_m720_unsol_event,
7932 .init_hook = alc883_clevo_m720_automute,
7934 [ALC883_LENOVO_101E_2ch] = {
7935 .mixers = { alc883_lenovo_101e_2ch_mixer},
7936 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7937 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7938 .dac_nids = alc883_dac_nids,
7939 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7940 .channel_mode = alc883_3ST_2ch_modes,
7941 .input_mux = &alc883_lenovo_101e_capture_source,
7942 .unsol_event = alc883_lenovo_101e_unsol_event,
7943 .init_hook = alc883_lenovo_101e_all_automute,
7945 [ALC883_LENOVO_NB0763] = {
7946 .mixers = { alc883_lenovo_nb0763_mixer },
7947 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7948 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7949 .dac_nids = alc883_dac_nids,
7950 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7951 .channel_mode = alc883_3ST_2ch_modes,
7953 .input_mux = &alc883_lenovo_nb0763_capture_source,
7954 .unsol_event = alc883_medion_md2_unsol_event,
7955 .init_hook = alc883_medion_md2_automute,
7957 [ALC888_LENOVO_MS7195_DIG] = {
7958 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7959 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7960 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7961 .dac_nids = alc883_dac_nids,
7962 .dig_out_nid = ALC883_DIGOUT_NID,
7963 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7964 .channel_mode = alc883_3ST_6ch_modes,
7966 .input_mux = &alc883_capture_source,
7967 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7968 .init_hook = alc888_lenovo_ms7195_front_automute,
7970 [ALC883_HAIER_W66] = {
7971 .mixers = { alc883_tagra_2ch_mixer},
7972 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7973 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7974 .dac_nids = alc883_dac_nids,
7975 .dig_out_nid = ALC883_DIGOUT_NID,
7976 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7977 .channel_mode = alc883_3ST_2ch_modes,
7978 .input_mux = &alc883_capture_source,
7979 .unsol_event = alc883_haier_w66_unsol_event,
7980 .init_hook = alc883_haier_w66_automute,
7983 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7984 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7985 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7986 .dac_nids = alc883_dac_nids,
7987 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7988 .channel_mode = alc888_3st_hp_modes,
7990 .input_mux = &alc883_capture_source,
7992 [ALC888_6ST_DELL] = {
7993 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7994 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
7995 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7996 .dac_nids = alc883_dac_nids,
7997 .dig_out_nid = ALC883_DIGOUT_NID,
7998 .dig_in_nid = ALC883_DIGIN_NID,
7999 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8000 .channel_mode = alc883_sixstack_modes,
8001 .input_mux = &alc883_capture_source,
8002 .unsol_event = alc888_6st_dell_unsol_event,
8003 .init_hook = alc888_6st_dell_front_automute,
8006 .mixers = { alc883_mitac_mixer },
8007 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8008 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8009 .dac_nids = alc883_dac_nids,
8010 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8011 .channel_mode = alc883_3ST_2ch_modes,
8012 .input_mux = &alc883_capture_source,
8013 .unsol_event = alc883_mitac_unsol_event,
8014 .init_hook = alc883_mitac_automute,
8016 [ALC883_FUJITSU_PI2515] = {
8017 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8018 .init_verbs = { alc883_init_verbs,
8019 alc883_2ch_fujitsu_pi2515_verbs},
8020 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8021 .dac_nids = alc883_dac_nids,
8022 .dig_out_nid = ALC883_DIGOUT_NID,
8023 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8024 .channel_mode = alc883_3ST_2ch_modes,
8025 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8026 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8027 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8033 * BIOS auto configuration
8035 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8036 hda_nid_t nid, int pin_type,
8040 struct alc_spec *spec = codec->spec;
8043 alc_set_pin_output(codec, nid, pin_type);
8044 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8047 idx = spec->multiout.dac_nids[dac_idx] - 2;
8048 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8052 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8054 struct alc_spec *spec = codec->spec;
8057 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8058 for (i = 0; i <= HDA_SIDE; i++) {
8059 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8060 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8062 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8067 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8069 struct alc_spec *spec = codec->spec;
8072 pin = spec->autocfg.hp_pins[0];
8073 if (pin) /* connect to front */
8075 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8076 pin = spec->autocfg.speaker_pins[0];
8078 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8081 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8082 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8084 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8086 struct alc_spec *spec = codec->spec;
8089 for (i = 0; i < AUTO_PIN_LAST; i++) {
8090 hda_nid_t nid = spec->autocfg.input_pins[i];
8091 if (alc883_is_input_pin(nid)) {
8092 snd_hda_codec_write(codec, nid, 0,
8093 AC_VERB_SET_PIN_WIDGET_CONTROL,
8094 (i <= AUTO_PIN_FRONT_MIC ?
8095 PIN_VREF80 : PIN_IN));
8096 if (nid != ALC883_PIN_CD_NID)
8097 snd_hda_codec_write(codec, nid, 0,
8098 AC_VERB_SET_AMP_GAIN_MUTE,
8104 /* almost identical with ALC880 parser... */
8105 static int alc883_parse_auto_config(struct hda_codec *codec)
8107 struct alc_spec *spec = codec->spec;
8108 int err = alc880_parse_auto_config(codec);
8113 return 0; /* no config found */
8115 err = alc_auto_add_mic_boost(codec);
8119 /* hack - override the init verbs */
8120 spec->init_verbs[0] = alc883_auto_init_verbs;
8121 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8124 return 1; /* config found */
8127 /* additional initialization for auto-configuration model */
8128 static void alc883_auto_init(struct hda_codec *codec)
8130 struct alc_spec *spec = codec->spec;
8131 alc883_auto_init_multi_out(codec);
8132 alc883_auto_init_hp_out(codec);
8133 alc883_auto_init_analog_input(codec);
8134 if (spec->unsol_event)
8135 alc_sku_automute(codec);
8138 static int patch_alc883(struct hda_codec *codec)
8140 struct alc_spec *spec;
8141 int err, board_config;
8143 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8149 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8152 if (board_config < 0) {
8153 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8154 "trying auto-probe from BIOS...\n");
8155 board_config = ALC883_AUTO;
8158 if (board_config == ALC883_AUTO) {
8159 /* automatic parse from the BIOS config */
8160 err = alc883_parse_auto_config(codec);
8166 "hda_codec: Cannot set up configuration "
8167 "from BIOS. Using base mode...\n");
8168 board_config = ALC883_3ST_2ch_DIG;
8172 if (board_config != ALC883_AUTO)
8173 setup_preset(spec, &alc883_presets[board_config]);
8175 spec->stream_name_analog = "ALC883 Analog";
8176 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8177 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8178 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8180 spec->stream_name_digital = "ALC883 Digital";
8181 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8182 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8184 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8185 spec->adc_nids = alc883_adc_nids;
8186 spec->capsrc_nids = alc883_capsrc_nids;
8188 spec->vmaster_nid = 0x0c;
8190 codec->patch_ops = alc_patch_ops;
8191 if (board_config == ALC883_AUTO)
8192 spec->init_hook = alc883_auto_init;
8193 #ifdef CONFIG_SND_HDA_POWER_SAVE
8194 if (!spec->loopback.amplist)
8195 spec->loopback.amplist = alc883_loopbacks;
8205 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8206 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8208 #define alc262_dac_nids alc260_dac_nids
8209 #define alc262_adc_nids alc882_adc_nids
8210 #define alc262_adc_nids_alt alc882_adc_nids_alt
8211 #define alc262_capsrc_nids alc882_capsrc_nids
8212 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8214 #define alc262_modes alc260_modes
8215 #define alc262_capture_source alc882_capture_source
8217 static struct snd_kcontrol_new alc262_base_mixer[] = {
8218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8219 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8220 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8221 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8222 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8223 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8226 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8227 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8229 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8230 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8231 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8232 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
8233 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8234 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8235 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
8239 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
8240 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8241 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8242 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8243 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8247 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8250 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8251 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8252 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8253 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
8254 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
8255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8259 /* update HP, line and mono-out pins according to the master switch */
8260 static void alc262_hp_master_update(struct hda_codec *codec)
8262 struct alc_spec *spec = codec->spec;
8263 int val = spec->master_sw;
8266 snd_hda_codec_write_cache(codec, 0x1b, 0,
8267 AC_VERB_SET_PIN_WIDGET_CONTROL,
8269 snd_hda_codec_write_cache(codec, 0x15, 0,
8270 AC_VERB_SET_PIN_WIDGET_CONTROL,
8272 /* mono (speaker) depending on the HP jack sense */
8273 val = val && !spec->jack_present;
8274 snd_hda_codec_write_cache(codec, 0x16, 0,
8275 AC_VERB_SET_PIN_WIDGET_CONTROL,
8279 static void alc262_hp_bpc_automute(struct hda_codec *codec)
8281 struct alc_spec *spec = codec->spec;
8282 unsigned int presence;
8283 presence = snd_hda_codec_read(codec, 0x1b, 0,
8284 AC_VERB_GET_PIN_SENSE, 0);
8285 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8286 alc262_hp_master_update(codec);
8289 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
8291 if ((res >> 26) != ALC880_HP_EVENT)
8293 alc262_hp_bpc_automute(codec);
8296 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
8298 struct alc_spec *spec = codec->spec;
8299 unsigned int presence;
8300 presence = snd_hda_codec_read(codec, 0x15, 0,
8301 AC_VERB_GET_PIN_SENSE, 0);
8302 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
8303 alc262_hp_master_update(codec);
8306 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
8309 if ((res >> 26) != ALC880_HP_EVENT)
8311 alc262_hp_wildwest_automute(codec);
8314 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
8315 struct snd_ctl_elem_value *ucontrol)
8317 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8318 struct alc_spec *spec = codec->spec;
8319 *ucontrol->value.integer.value = spec->master_sw;
8323 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
8324 struct snd_ctl_elem_value *ucontrol)
8326 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8327 struct alc_spec *spec = codec->spec;
8328 int val = !!*ucontrol->value.integer.value;
8330 if (val == spec->master_sw)
8332 spec->master_sw = val;
8333 alc262_hp_master_update(codec);
8337 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
8339 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8340 .name = "Master Playback Switch",
8341 .info = snd_ctl_boolean_mono_info,
8342 .get = alc262_hp_master_sw_get,
8343 .put = alc262_hp_master_sw_put,
8345 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8346 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8348 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8350 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8352 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8354 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8355 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8356 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8357 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8362 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8363 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8364 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
8365 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
8369 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
8371 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8372 .name = "Master Playback Switch",
8373 .info = snd_ctl_boolean_mono_info,
8374 .get = alc262_hp_master_sw_get,
8375 .put = alc262_hp_master_sw_put,
8377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8378 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8379 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8380 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8381 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
8383 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
8385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
8386 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
8387 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
8388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8390 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8391 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8392 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
8393 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
8397 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
8398 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8399 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8400 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
8404 /* mute/unmute internal speaker according to the hp jack and mute state */
8405 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
8407 struct alc_spec *spec = codec->spec;
8409 if (force || !spec->sense_updated) {
8410 unsigned int present;
8411 present = snd_hda_codec_read(codec, 0x15, 0,
8412 AC_VERB_GET_PIN_SENSE, 0);
8413 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
8414 spec->sense_updated = 1;
8416 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
8417 spec->jack_present ? HDA_AMP_MUTE : 0);
8420 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
8423 if ((res >> 26) != ALC880_HP_EVENT)
8425 alc262_hp_t5735_automute(codec, 1);
8428 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
8430 alc262_hp_t5735_automute(codec, 1);
8433 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
8434 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8435 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8440 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8444 static struct hda_verb alc262_hp_t5735_verbs[] = {
8445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8448 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8452 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
8453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8454 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8455 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8456 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8457 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8458 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8462 static struct hda_verb alc262_hp_rp5700_verbs[] = {
8463 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8464 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8465 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8467 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8468 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8471 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
8476 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8483 /* bind hp and internal speaker mute (with plug check) */
8484 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
8485 struct snd_ctl_elem_value *ucontrol)
8487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8488 long *valp = ucontrol->value.integer.value;
8491 /* change hp mute */
8492 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
8494 valp[0] ? 0 : HDA_AMP_MUTE);
8495 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
8497 valp[1] ? 0 : HDA_AMP_MUTE);
8499 /* change speaker according to HP jack state */
8500 struct alc_spec *spec = codec->spec;
8502 if (spec->jack_present)
8503 mute = HDA_AMP_MUTE;
8505 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
8507 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8508 HDA_AMP_MUTE, mute);
8513 static struct snd_kcontrol_new alc262_sony_mixer[] = {
8514 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8516 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8517 .name = "Master Playback Switch",
8518 .info = snd_hda_mixer_amp_switch_info,
8519 .get = snd_hda_mixer_amp_switch_get,
8520 .put = alc262_sony_master_sw_put,
8521 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
8523 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8525 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8526 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8530 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
8531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8532 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8533 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8536 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8537 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8541 #define alc262_capture_mixer alc882_capture_mixer
8542 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
8545 * generic initialization of ADC, input mixers and output mixers
8547 static struct hda_verb alc262_init_verbs[] = {
8549 * Unmute ADC0-2 and set the default input to mic-in
8551 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8553 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8555 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8556 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8558 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8560 * Note: PASD motherboards uses the Line In 2 as the input for
8561 * front panel mic (mic 2)
8563 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8564 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8565 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8566 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8567 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8568 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8571 * Set up output mixers (0x0c - 0x0e)
8573 /* set vol=0 to output mixers */
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8575 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8577 /* set up input amps for analog loopback */
8578 /* Amp Indices: DAC = 0, mixer = 1 */
8579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8584 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8588 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8589 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8590 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8591 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8594 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8596 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8597 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8599 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8600 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8602 /* FIXME: use matrix-type input source selection */
8603 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8604 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8605 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8610 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8615 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8623 static struct hda_verb alc262_hippo_unsol_verbs[] = {
8624 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8629 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
8630 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8631 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8632 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
8634 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8635 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8639 static struct hda_verb alc262_sony_unsol_verbs[] = {
8640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8641 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8642 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
8644 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8645 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8648 /* mute/unmute internal speaker according to the hp jack and mute state */
8649 static void alc262_hippo_automute(struct hda_codec *codec)
8651 struct alc_spec *spec = codec->spec;
8653 unsigned int present;
8655 /* need to execute and sync at first */
8656 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
8657 present = snd_hda_codec_read(codec, 0x15, 0,
8658 AC_VERB_GET_PIN_SENSE, 0);
8659 spec->jack_present = (present & 0x80000000) != 0;
8660 if (spec->jack_present) {
8661 /* mute internal speaker */
8662 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8663 HDA_AMP_MUTE, HDA_AMP_MUTE);
8665 /* unmute internal speaker if necessary */
8666 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
8667 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8668 HDA_AMP_MUTE, mute);
8672 /* unsolicited event for HP jack sensing */
8673 static void alc262_hippo_unsol_event(struct hda_codec *codec,
8676 if ((res >> 26) != ALC880_HP_EVENT)
8678 alc262_hippo_automute(codec);
8681 static void alc262_hippo1_automute(struct hda_codec *codec)
8684 unsigned int present;
8686 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8687 present = snd_hda_codec_read(codec, 0x1b, 0,
8688 AC_VERB_GET_PIN_SENSE, 0);
8689 present = (present & 0x80000000) != 0;
8691 /* mute internal speaker */
8692 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8693 HDA_AMP_MUTE, HDA_AMP_MUTE);
8695 /* unmute internal speaker if necessary */
8696 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8697 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8698 HDA_AMP_MUTE, mute);
8702 /* unsolicited event for HP jack sensing */
8703 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
8706 if ((res >> 26) != ALC880_HP_EVENT)
8708 alc262_hippo1_automute(codec);
8713 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
8714 * 0x1b = port replicator headphone out
8717 #define ALC_HP_EVENT 0x37
8719 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
8720 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8721 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8722 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8723 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8727 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
8728 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
8729 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8733 static struct hda_input_mux alc262_fujitsu_capture_source = {
8742 static struct hda_input_mux alc262_HP_capture_source = {
8746 { "Front Mic", 0x1 },
8753 static struct hda_input_mux alc262_HP_D7000_capture_source = {
8757 { "Front Mic", 0x2 },
8763 /* mute/unmute internal speaker according to the hp jacks and mute state */
8764 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
8766 struct alc_spec *spec = codec->spec;
8769 if (force || !spec->sense_updated) {
8770 unsigned int present;
8771 /* need to execute and sync at first */
8772 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
8773 /* check laptop HP jack */
8774 present = snd_hda_codec_read(codec, 0x14, 0,
8775 AC_VERB_GET_PIN_SENSE, 0);
8776 /* need to execute and sync at first */
8777 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8778 /* check docking HP jack */
8779 present |= snd_hda_codec_read(codec, 0x1b, 0,
8780 AC_VERB_GET_PIN_SENSE, 0);
8781 if (present & AC_PINSENSE_PRESENCE)
8782 spec->jack_present = 1;
8784 spec->jack_present = 0;
8785 spec->sense_updated = 1;
8787 /* unmute internal speaker only if both HPs are unplugged and
8788 * master switch is on
8790 if (spec->jack_present)
8791 mute = HDA_AMP_MUTE;
8793 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8794 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8795 HDA_AMP_MUTE, mute);
8798 /* unsolicited event for HP jack sensing */
8799 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8802 if ((res >> 26) != ALC_HP_EVENT)
8804 alc262_fujitsu_automute(codec, 1);
8807 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
8809 alc262_fujitsu_automute(codec, 1);
8812 /* bind volumes of both NID 0x0c and 0x0d */
8813 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8814 .ops = &snd_hda_bind_vol,
8816 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8817 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8822 /* mute/unmute internal speaker according to the hp jack and mute state */
8823 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
8825 struct alc_spec *spec = codec->spec;
8828 if (force || !spec->sense_updated) {
8829 unsigned int present_int_hp;
8830 /* need to execute and sync at first */
8831 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8832 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
8833 AC_VERB_GET_PIN_SENSE, 0);
8834 spec->jack_present = (present_int_hp & 0x80000000) != 0;
8835 spec->sense_updated = 1;
8837 if (spec->jack_present) {
8838 /* mute internal speaker */
8839 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8840 HDA_AMP_MUTE, HDA_AMP_MUTE);
8841 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8842 HDA_AMP_MUTE, HDA_AMP_MUTE);
8844 /* unmute internal speaker if necessary */
8845 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8846 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8847 HDA_AMP_MUTE, mute);
8848 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8849 HDA_AMP_MUTE, mute);
8853 /* unsolicited event for HP jack sensing */
8854 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
8857 if ((res >> 26) != ALC_HP_EVENT)
8859 alc262_lenovo_3000_automute(codec, 1);
8862 /* bind hp and internal speaker mute (with plug check) */
8863 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8864 struct snd_ctl_elem_value *ucontrol)
8866 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8867 long *valp = ucontrol->value.integer.value;
8870 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8872 valp ? 0 : HDA_AMP_MUTE);
8873 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8875 valp ? 0 : HDA_AMP_MUTE);
8878 alc262_fujitsu_automute(codec, 0);
8882 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8883 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8886 .name = "Master Playback Switch",
8887 .info = snd_hda_mixer_amp_switch_info,
8888 .get = snd_hda_mixer_amp_switch_get,
8889 .put = alc262_fujitsu_master_sw_put,
8890 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8894 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
8895 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
8896 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8899 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8901 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8905 /* bind hp and internal speaker mute (with plug check) */
8906 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
8907 struct snd_ctl_elem_value *ucontrol)
8909 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8910 long *valp = ucontrol->value.integer.value;
8913 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
8915 valp ? 0 : HDA_AMP_MUTE);
8918 alc262_lenovo_3000_automute(codec, 0);
8922 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
8923 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8926 .name = "Master Playback Switch",
8927 .info = snd_hda_mixer_amp_switch_info,
8928 .get = snd_hda_mixer_amp_switch_get,
8929 .put = alc262_lenovo_3000_master_sw_put,
8930 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
8932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8938 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8939 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8943 /* additional init verbs for Benq laptops */
8944 static struct hda_verb alc262_EAPD_verbs[] = {
8945 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8946 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8950 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8951 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8954 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8955 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8959 /* Samsung Q1 Ultra Vista model setup */
8960 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
8961 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8962 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
8963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8965 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
8970 static struct hda_verb alc262_ultra_verbs[] = {
8972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8978 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8984 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8985 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8987 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8989 /* ADC, choose mic */
8990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9003 /* mute/unmute internal speaker according to the hp jack and mute state */
9004 static void alc262_ultra_automute(struct hda_codec *codec)
9006 struct alc_spec *spec = codec->spec;
9010 /* auto-mute only when HP is used as HP */
9011 if (!spec->cur_mux[0]) {
9012 unsigned int present;
9013 /* need to execute and sync at first */
9014 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9015 present = snd_hda_codec_read(codec, 0x15, 0,
9016 AC_VERB_GET_PIN_SENSE, 0);
9017 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9018 if (spec->jack_present)
9019 mute = HDA_AMP_MUTE;
9021 /* mute/unmute internal speaker */
9022 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9023 HDA_AMP_MUTE, mute);
9024 /* mute/unmute HP */
9025 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9026 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9029 /* unsolicited event for HP jack sensing */
9030 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9033 if ((res >> 26) != ALC880_HP_EVENT)
9035 alc262_ultra_automute(codec);
9038 static struct hda_input_mux alc262_ultra_capture_source = {
9042 { "Headphone", 0x7 },
9046 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9047 struct snd_ctl_elem_value *ucontrol)
9049 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9050 struct alc_spec *spec = codec->spec;
9053 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9056 /* reprogram the HP pin as mic or HP according to the input source */
9057 snd_hda_codec_write_cache(codec, 0x15, 0,
9058 AC_VERB_SET_PIN_WIDGET_CONTROL,
9059 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9060 alc262_ultra_automute(codec); /* mute/unmute HP */
9064 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9065 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9066 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9069 .name = "Capture Source",
9070 .info = alc882_mux_enum_info,
9071 .get = alc882_mux_enum_get,
9072 .put = alc262_ultra_mux_enum_put,
9077 /* add playback controls from the parsed DAC table */
9078 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9079 const struct auto_pin_cfg *cfg)
9084 spec->multiout.num_dacs = 1; /* only use one dac */
9085 spec->multiout.dac_nids = spec->private_dac_nids;
9086 spec->multiout.dac_nids[0] = 2;
9088 nid = cfg->line_out_pins[0];
9090 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9091 "Front Playback Volume",
9092 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
9095 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9096 "Front Playback Switch",
9097 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
9102 nid = cfg->speaker_pins[0];
9105 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9106 "Speaker Playback Volume",
9107 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9111 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9112 "Speaker Playback Switch",
9113 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9118 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9119 "Speaker Playback Switch",
9120 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9126 nid = cfg->hp_pins[0];
9128 /* spec->multiout.hp_nid = 2; */
9130 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9131 "Headphone Playback Volume",
9132 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
9136 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9137 "Headphone Playback Switch",
9138 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
9143 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9144 "Headphone Playback Switch",
9145 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
9154 /* identical with ALC880 */
9155 #define alc262_auto_create_analog_input_ctls \
9156 alc880_auto_create_analog_input_ctls
9159 * generic initialization of ADC, input mixers and output mixers
9161 static struct hda_verb alc262_volume_init_verbs[] = {
9163 * Unmute ADC0-2 and set the default input to mic-in
9165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9167 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9168 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9169 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9170 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9172 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9174 * Note: PASD motherboards uses the Line In 2 as the input for
9175 * front panel mic (mic 2)
9177 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9178 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9179 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9180 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9181 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9182 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9185 * Set up output mixers (0x0c - 0x0f)
9187 /* set vol=0 to output mixers */
9188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9189 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9192 /* set up input amps for analog loopback */
9193 /* Amp Indices: DAC = 0, mixer = 1 */
9194 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9196 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9201 /* FIXME: use matrix-type input source selection */
9202 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9203 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9204 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9205 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9206 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9207 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9209 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9214 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9222 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
9224 * Unmute ADC0-2 and set the default input to mic-in
9226 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9228 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9233 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9235 * Note: PASD motherboards uses the Line In 2 as the input for
9236 * front panel mic (mic 2)
9238 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9248 * Set up output mixers (0x0c - 0x0e)
9250 /* set vol=0 to output mixers */
9251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9253 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9255 /* set up input amps for analog loopback */
9256 /* Amp Indices: DAC = 0, mixer = 1 */
9257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9258 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9261 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9262 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9264 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9265 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9266 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9268 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9271 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9272 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9276 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9277 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9278 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9280 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9281 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9282 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9284 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9285 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9288 /* FIXME: use matrix-type input source selection */
9289 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9290 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9291 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9292 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9293 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9294 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9296 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9297 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9298 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9299 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9301 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9302 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9303 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9304 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9306 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9311 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
9313 * Unmute ADC0-2 and set the default input to mic-in
9315 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9316 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9317 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9318 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9319 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9322 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9324 * Note: PASD motherboards uses the Line In 2 as the input for front
9327 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9328 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9329 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9330 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9331 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9332 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9333 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9334 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9337 * Set up output mixers (0x0c - 0x0e)
9339 /* set vol=0 to output mixers */
9340 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9341 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9342 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9344 /* set up input amps for analog loopback */
9345 /* Amp Indices: DAC = 0, mixer = 1 */
9346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9347 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9348 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9349 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9350 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
9355 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
9356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
9357 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
9358 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
9359 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
9360 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
9362 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9363 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9365 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9366 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9368 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
9369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9370 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9371 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
9372 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9373 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9375 /* FIXME: use matrix-type input source selection */
9376 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9377 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
9379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
9380 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
9381 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
9382 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
9383 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
9386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9389 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9391 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9392 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9395 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
9397 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
9398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
9399 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
9400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
9402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9407 #ifdef CONFIG_SND_HDA_POWER_SAVE
9408 #define alc262_loopbacks alc880_loopbacks
9411 /* pcm configuration: identiacal with ALC880 */
9412 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
9413 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
9414 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
9415 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
9418 * BIOS auto configuration
9420 static int alc262_parse_auto_config(struct hda_codec *codec)
9422 struct alc_spec *spec = codec->spec;
9424 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
9426 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9430 if (!spec->autocfg.line_outs)
9431 return 0; /* can't find valid BIOS pin config */
9432 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
9435 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
9439 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9441 if (spec->autocfg.dig_out_pin)
9442 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
9443 if (spec->autocfg.dig_in_pin)
9444 spec->dig_in_nid = ALC262_DIGIN_NID;
9446 if (spec->kctl_alloc)
9447 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9449 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
9450 spec->num_mux_defs = 1;
9451 spec->input_mux = &spec->private_imux;
9453 err = alc_auto_add_mic_boost(codec);
9460 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
9461 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
9462 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
9465 /* init callback for auto-configuration model -- overriding the default init */
9466 static void alc262_auto_init(struct hda_codec *codec)
9468 struct alc_spec *spec = codec->spec;
9469 alc262_auto_init_multi_out(codec);
9470 alc262_auto_init_hp_out(codec);
9471 alc262_auto_init_analog_input(codec);
9472 if (spec->unsol_event)
9473 alc_sku_automute(codec);
9477 * configuration and preset
9479 static const char *alc262_models[ALC262_MODEL_LAST] = {
9480 [ALC262_BASIC] = "basic",
9481 [ALC262_HIPPO] = "hippo",
9482 [ALC262_HIPPO_1] = "hippo_1",
9483 [ALC262_FUJITSU] = "fujitsu",
9484 [ALC262_HP_BPC] = "hp-bpc",
9485 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
9486 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
9487 [ALC262_HP_RP5700] = "hp-rp5700",
9488 [ALC262_BENQ_ED8] = "benq",
9489 [ALC262_BENQ_T31] = "benq-t31",
9490 [ALC262_SONY_ASSAMD] = "sony-assamd",
9491 [ALC262_ULTRA] = "ultra",
9492 [ALC262_LENOVO_3000] = "lenovo-3000",
9493 [ALC262_AUTO] = "auto",
9496 static struct snd_pci_quirk alc262_cfg_tbl[] = {
9497 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
9498 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
9499 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
9500 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
9501 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
9502 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
9503 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
9504 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
9505 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
9506 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
9507 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
9508 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
9509 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
9510 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
9511 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
9512 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
9513 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
9514 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
9515 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
9516 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
9517 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
9518 ALC262_HP_TC_T5735),
9519 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
9520 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9521 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
9522 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9523 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
9524 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
9525 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
9526 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
9527 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
9528 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
9529 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
9530 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
9531 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
9532 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
9536 static struct alc_config_preset alc262_presets[] = {
9538 .mixers = { alc262_base_mixer },
9539 .init_verbs = { alc262_init_verbs },
9540 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9541 .dac_nids = alc262_dac_nids,
9543 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9544 .channel_mode = alc262_modes,
9545 .input_mux = &alc262_capture_source,
9548 .mixers = { alc262_base_mixer },
9549 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
9550 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9551 .dac_nids = alc262_dac_nids,
9553 .dig_out_nid = ALC262_DIGOUT_NID,
9554 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9555 .channel_mode = alc262_modes,
9556 .input_mux = &alc262_capture_source,
9557 .unsol_event = alc262_hippo_unsol_event,
9558 .init_hook = alc262_hippo_automute,
9560 [ALC262_HIPPO_1] = {
9561 .mixers = { alc262_hippo1_mixer },
9562 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
9563 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9564 .dac_nids = alc262_dac_nids,
9566 .dig_out_nid = ALC262_DIGOUT_NID,
9567 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9568 .channel_mode = alc262_modes,
9569 .input_mux = &alc262_capture_source,
9570 .unsol_event = alc262_hippo1_unsol_event,
9571 .init_hook = alc262_hippo1_automute,
9573 [ALC262_FUJITSU] = {
9574 .mixers = { alc262_fujitsu_mixer },
9575 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9576 alc262_fujitsu_unsol_verbs },
9577 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9578 .dac_nids = alc262_dac_nids,
9580 .dig_out_nid = ALC262_DIGOUT_NID,
9581 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9582 .channel_mode = alc262_modes,
9583 .input_mux = &alc262_fujitsu_capture_source,
9584 .unsol_event = alc262_fujitsu_unsol_event,
9585 .init_hook = alc262_fujitsu_init_hook,
9588 .mixers = { alc262_HP_BPC_mixer },
9589 .init_verbs = { alc262_HP_BPC_init_verbs },
9590 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9591 .dac_nids = alc262_dac_nids,
9593 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9594 .channel_mode = alc262_modes,
9595 .input_mux = &alc262_HP_capture_source,
9596 .unsol_event = alc262_hp_bpc_unsol_event,
9597 .init_hook = alc262_hp_bpc_automute,
9599 [ALC262_HP_BPC_D7000_WF] = {
9600 .mixers = { alc262_HP_BPC_WildWest_mixer },
9601 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9602 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9603 .dac_nids = alc262_dac_nids,
9605 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9606 .channel_mode = alc262_modes,
9607 .input_mux = &alc262_HP_D7000_capture_source,
9608 .unsol_event = alc262_hp_wildwest_unsol_event,
9609 .init_hook = alc262_hp_wildwest_automute,
9611 [ALC262_HP_BPC_D7000_WL] = {
9612 .mixers = { alc262_HP_BPC_WildWest_mixer,
9613 alc262_HP_BPC_WildWest_option_mixer },
9614 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
9615 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9616 .dac_nids = alc262_dac_nids,
9618 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9619 .channel_mode = alc262_modes,
9620 .input_mux = &alc262_HP_D7000_capture_source,
9621 .unsol_event = alc262_hp_wildwest_unsol_event,
9622 .init_hook = alc262_hp_wildwest_automute,
9624 [ALC262_HP_TC_T5735] = {
9625 .mixers = { alc262_hp_t5735_mixer },
9626 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
9627 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9628 .dac_nids = alc262_dac_nids,
9630 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9631 .channel_mode = alc262_modes,
9632 .input_mux = &alc262_capture_source,
9633 .unsol_event = alc262_hp_t5735_unsol_event,
9634 .init_hook = alc262_hp_t5735_init_hook,
9636 [ALC262_HP_RP5700] = {
9637 .mixers = { alc262_hp_rp5700_mixer },
9638 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
9639 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9640 .dac_nids = alc262_dac_nids,
9641 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9642 .channel_mode = alc262_modes,
9643 .input_mux = &alc262_hp_rp5700_capture_source,
9645 [ALC262_BENQ_ED8] = {
9646 .mixers = { alc262_base_mixer },
9647 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
9648 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9649 .dac_nids = alc262_dac_nids,
9651 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9652 .channel_mode = alc262_modes,
9653 .input_mux = &alc262_capture_source,
9655 [ALC262_SONY_ASSAMD] = {
9656 .mixers = { alc262_sony_mixer },
9657 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
9658 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9659 .dac_nids = alc262_dac_nids,
9661 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9662 .channel_mode = alc262_modes,
9663 .input_mux = &alc262_capture_source,
9664 .unsol_event = alc262_hippo_unsol_event,
9665 .init_hook = alc262_hippo_automute,
9667 [ALC262_BENQ_T31] = {
9668 .mixers = { alc262_benq_t31_mixer },
9669 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
9670 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9671 .dac_nids = alc262_dac_nids,
9673 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9674 .channel_mode = alc262_modes,
9675 .input_mux = &alc262_capture_source,
9676 .unsol_event = alc262_hippo_unsol_event,
9677 .init_hook = alc262_hippo_automute,
9680 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
9681 .init_verbs = { alc262_ultra_verbs },
9682 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9683 .dac_nids = alc262_dac_nids,
9684 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9685 .channel_mode = alc262_modes,
9686 .input_mux = &alc262_ultra_capture_source,
9687 .adc_nids = alc262_adc_nids, /* ADC0 */
9688 .capsrc_nids = alc262_capsrc_nids,
9689 .num_adc_nids = 1, /* single ADC */
9690 .unsol_event = alc262_ultra_unsol_event,
9691 .init_hook = alc262_ultra_automute,
9693 [ALC262_LENOVO_3000] = {
9694 .mixers = { alc262_lenovo_3000_mixer },
9695 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
9696 alc262_lenovo_3000_unsol_verbs },
9697 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
9698 .dac_nids = alc262_dac_nids,
9700 .dig_out_nid = ALC262_DIGOUT_NID,
9701 .num_channel_mode = ARRAY_SIZE(alc262_modes),
9702 .channel_mode = alc262_modes,
9703 .input_mux = &alc262_fujitsu_capture_source,
9704 .unsol_event = alc262_lenovo_3000_unsol_event,
9708 static int patch_alc262(struct hda_codec *codec)
9710 struct alc_spec *spec;
9714 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9720 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
9725 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9726 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
9727 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
9728 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
9732 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
9736 if (board_config < 0) {
9737 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
9738 "trying auto-probe from BIOS...\n");
9739 board_config = ALC262_AUTO;
9742 if (board_config == ALC262_AUTO) {
9743 /* automatic parse from the BIOS config */
9744 err = alc262_parse_auto_config(codec);
9750 "hda_codec: Cannot set up configuration "
9751 "from BIOS. Using base mode...\n");
9752 board_config = ALC262_BASIC;
9756 if (board_config != ALC262_AUTO)
9757 setup_preset(spec, &alc262_presets[board_config]);
9759 spec->stream_name_analog = "ALC262 Analog";
9760 spec->stream_analog_playback = &alc262_pcm_analog_playback;
9761 spec->stream_analog_capture = &alc262_pcm_analog_capture;
9763 spec->stream_name_digital = "ALC262 Digital";
9764 spec->stream_digital_playback = &alc262_pcm_digital_playback;
9765 spec->stream_digital_capture = &alc262_pcm_digital_capture;
9767 if (!spec->adc_nids && spec->input_mux) {
9768 /* check whether NID 0x07 is valid */
9769 unsigned int wcap = get_wcaps(codec, 0x07);
9772 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9773 if (wcap != AC_WID_AUD_IN) {
9774 spec->adc_nids = alc262_adc_nids_alt;
9775 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
9776 spec->capsrc_nids = alc262_capsrc_nids_alt;
9777 spec->mixers[spec->num_mixers] =
9778 alc262_capture_alt_mixer;
9781 spec->adc_nids = alc262_adc_nids;
9782 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
9783 spec->capsrc_nids = alc262_capsrc_nids;
9784 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
9789 spec->vmaster_nid = 0x0c;
9791 codec->patch_ops = alc_patch_ops;
9792 if (board_config == ALC262_AUTO)
9793 spec->init_hook = alc262_auto_init;
9794 #ifdef CONFIG_SND_HDA_POWER_SAVE
9795 if (!spec->loopback.amplist)
9796 spec->loopback.amplist = alc262_loopbacks;
9803 * ALC268 channel source setting (2 channel)
9805 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
9806 #define alc268_modes alc260_modes
9808 static hda_nid_t alc268_dac_nids[2] = {
9813 static hda_nid_t alc268_adc_nids[2] = {
9818 static hda_nid_t alc268_adc_nids_alt[1] = {
9823 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
9825 static struct snd_kcontrol_new alc268_base_mixer[] = {
9826 /* output mixer control */
9827 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
9828 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
9830 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9831 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9832 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9833 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9837 /* bind Beep switches of both NID 0x0f and 0x10 */
9838 static struct hda_bind_ctls alc268_bind_beep_sw = {
9839 .ops = &snd_hda_bind_sw,
9841 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
9842 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
9847 static struct snd_kcontrol_new alc268_beep_mixer[] = {
9848 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
9849 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
9853 static struct hda_verb alc268_eapd_verbs[] = {
9854 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9855 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9859 /* Toshiba specific */
9860 #define alc268_toshiba_automute alc262_hippo_automute
9862 static struct hda_verb alc268_toshiba_verbs[] = {
9863 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9868 /* bind volumes of both NID 0x02 and 0x03 */
9869 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
9870 .ops = &snd_hda_bind_vol,
9872 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
9873 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
9878 /* mute/unmute internal speaker according to the hp jack and mute state */
9879 static void alc268_acer_automute(struct hda_codec *codec, int force)
9881 struct alc_spec *spec = codec->spec;
9884 if (force || !spec->sense_updated) {
9885 unsigned int present;
9886 present = snd_hda_codec_read(codec, 0x14, 0,
9887 AC_VERB_GET_PIN_SENSE, 0);
9888 spec->jack_present = (present & 0x80000000) != 0;
9889 spec->sense_updated = 1;
9891 if (spec->jack_present)
9892 mute = HDA_AMP_MUTE; /* mute internal speaker */
9893 else /* unmute internal speaker if necessary */
9894 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9895 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9896 HDA_AMP_MUTE, mute);
9900 /* bind hp and internal speaker mute (with plug check) */
9901 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
9902 struct snd_ctl_elem_value *ucontrol)
9904 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9905 long *valp = ucontrol->value.integer.value;
9908 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
9910 valp[0] ? 0 : HDA_AMP_MUTE);
9911 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
9913 valp[1] ? 0 : HDA_AMP_MUTE);
9915 alc268_acer_automute(codec, 0);
9919 static struct snd_kcontrol_new alc268_acer_mixer[] = {
9920 /* output mixer control */
9921 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
9923 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9924 .name = "Master Playback Switch",
9925 .info = snd_hda_mixer_amp_switch_info,
9926 .get = snd_hda_mixer_amp_switch_get,
9927 .put = alc268_acer_master_sw_put,
9928 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9930 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9931 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9932 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
9936 static struct hda_verb alc268_acer_verbs[] = {
9937 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
9938 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9941 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9942 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9944 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9948 /* unsolicited event for HP jack sensing */
9949 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
9952 if ((res >> 26) != ALC880_HP_EVENT)
9954 alc268_toshiba_automute(codec);
9957 static void alc268_acer_unsol_event(struct hda_codec *codec,
9960 if ((res >> 26) != ALC880_HP_EVENT)
9962 alc268_acer_automute(codec, 1);
9965 static void alc268_acer_init_hook(struct hda_codec *codec)
9967 alc268_acer_automute(codec, 1);
9970 static struct snd_kcontrol_new alc268_dell_mixer[] = {
9971 /* output mixer control */
9972 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
9973 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9974 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
9975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9977 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
9981 static struct hda_verb alc268_dell_verbs[] = {
9982 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9983 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9984 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9988 /* mute/unmute internal speaker according to the hp jack and mute state */
9989 static void alc268_dell_automute(struct hda_codec *codec)
9991 unsigned int present;
9994 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
9995 if (present & 0x80000000)
9996 mute = HDA_AMP_MUTE;
9998 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9999 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10000 HDA_AMP_MUTE, mute);
10003 static void alc268_dell_unsol_event(struct hda_codec *codec,
10006 if ((res >> 26) != ALC880_HP_EVENT)
10008 alc268_dell_automute(codec);
10011 #define alc268_dell_init_hook alc268_dell_automute
10013 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
10014 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10015 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10017 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10018 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10019 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
10020 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
10021 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10025 static struct hda_verb alc267_quanta_il1_verbs[] = {
10026 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10027 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
10031 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
10033 unsigned int present;
10035 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
10036 & AC_PINSENSE_PRESENCE;
10037 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10038 present ? 0 : PIN_OUT);
10041 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
10043 unsigned int present;
10045 present = snd_hda_codec_read(codec, 0x18, 0,
10046 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10047 snd_hda_codec_write(codec, 0x23, 0,
10048 AC_VERB_SET_CONNECT_SEL,
10049 present ? 0x00 : 0x01);
10052 static void alc267_quanta_il1_automute(struct hda_codec *codec)
10054 alc267_quanta_il1_hp_automute(codec);
10055 alc267_quanta_il1_mic_automute(codec);
10058 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
10061 switch (res >> 26) {
10062 case ALC880_HP_EVENT:
10063 alc267_quanta_il1_hp_automute(codec);
10065 case ALC880_MIC_EVENT:
10066 alc267_quanta_il1_mic_automute(codec);
10072 * generic initialization of ADC, input mixers and output mixers
10074 static struct hda_verb alc268_base_init_verbs[] = {
10075 /* Unmute DAC0-1 and set vol = 0 */
10076 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10077 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10080 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10081 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10084 * Set up output mixers (0x0c - 0x0e)
10086 /* set vol=0 to output mixers */
10087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10089 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10090 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
10092 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10093 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10095 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10097 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10098 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10099 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10100 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10101 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10102 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10104 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10105 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10106 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10107 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10108 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10109 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10110 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10112 /* set PCBEEP vol = 0, mute connections */
10113 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10115 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10117 /* Unmute Selector 23h,24h and set the default input to mic-in */
10119 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
10120 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10121 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10128 * generic initialization of ADC, input mixers and output mixers
10130 static struct hda_verb alc268_volume_init_verbs[] = {
10131 /* set output DAC */
10132 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10133 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10134 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10137 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10138 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10139 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10140 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10141 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10145 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10146 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10150 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10151 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10152 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10154 /* set PCBEEP vol = 0, mute connections */
10155 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10156 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10157 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10162 #define alc268_mux_enum_info alc_mux_enum_info
10163 #define alc268_mux_enum_get alc_mux_enum_get
10164 #define alc268_mux_enum_put alc_mux_enum_put
10166 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
10167 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10168 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10171 /* The multiple "Capture Source" controls confuse alsamixer
10172 * So call somewhat different..
10174 /* .name = "Capture Source", */
10175 .name = "Input Source",
10177 .info = alc268_mux_enum_info,
10178 .get = alc268_mux_enum_get,
10179 .put = alc268_mux_enum_put,
10184 static struct snd_kcontrol_new alc268_capture_mixer[] = {
10185 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10186 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
10187 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
10188 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
10190 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10191 /* The multiple "Capture Source" controls confuse alsamixer
10192 * So call somewhat different..
10194 /* .name = "Capture Source", */
10195 .name = "Input Source",
10197 .info = alc268_mux_enum_info,
10198 .get = alc268_mux_enum_get,
10199 .put = alc268_mux_enum_put,
10204 static struct hda_input_mux alc268_capture_source = {
10208 { "Front Mic", 0x1 },
10214 static struct hda_input_mux alc268_acer_capture_source = {
10218 { "Internal Mic", 0x6 },
10223 #ifdef CONFIG_SND_DEBUG
10224 static struct snd_kcontrol_new alc268_test_mixer[] = {
10225 /* Volume widgets */
10226 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10227 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10228 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10229 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
10230 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
10231 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
10232 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
10233 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
10234 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
10235 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
10236 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
10237 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
10238 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
10239 /* The below appears problematic on some hardwares */
10240 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
10241 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
10242 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
10243 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
10244 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
10246 /* Modes for retasking pin widgets */
10247 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
10248 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
10249 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
10250 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
10252 /* Controls for GPIO pins, assuming they are configured as outputs */
10253 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
10254 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
10255 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
10256 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
10258 /* Switches to allow the digital SPDIF output pin to be enabled.
10259 * The ALC268 does not have an SPDIF input.
10261 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
10263 /* A switch allowing EAPD to be enabled. Some laptops seem to use
10264 * this output to turn on an external amplifier.
10266 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
10267 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
10273 /* create input playback/capture controls for the given pin */
10274 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
10275 const char *ctlname, int idx)
10280 sprintf(name, "%s Playback Volume", ctlname);
10282 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10283 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
10287 } else if (nid == 0x15) {
10288 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
10289 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
10295 sprintf(name, "%s Playback Switch", ctlname);
10296 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
10297 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
10303 /* add playback controls from the parsed DAC table */
10304 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
10305 const struct auto_pin_cfg *cfg)
10310 spec->multiout.num_dacs = 2; /* only use one dac */
10311 spec->multiout.dac_nids = spec->private_dac_nids;
10312 spec->multiout.dac_nids[0] = 2;
10313 spec->multiout.dac_nids[1] = 3;
10315 nid = cfg->line_out_pins[0];
10317 alc268_new_analog_output(spec, nid, "Front", 0);
10319 nid = cfg->speaker_pins[0];
10321 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10322 "Speaker Playback Volume",
10323 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10327 nid = cfg->hp_pins[0];
10329 alc268_new_analog_output(spec, nid, "Headphone", 0);
10331 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
10333 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10334 "Mono Playback Switch",
10335 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
10342 /* create playback/capture controls for input pins */
10343 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
10344 const struct auto_pin_cfg *cfg)
10346 struct hda_input_mux *imux = &spec->private_imux;
10349 for (i = 0; i < AUTO_PIN_LAST; i++) {
10350 switch(cfg->input_pins[i]) {
10352 idx1 = 0; /* Mic 1 */
10355 idx1 = 1; /* Mic 2 */
10358 idx1 = 2; /* Line In */
10365 idx1 = 6; /* digital mics */
10370 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10371 imux->items[imux->num_items].index = idx1;
10377 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
10379 struct alc_spec *spec = codec->spec;
10380 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10381 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10382 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10383 unsigned int dac_vol1, dac_vol2;
10386 snd_hda_codec_write(codec, speaker_nid, 0,
10387 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
10388 snd_hda_codec_write(codec, 0x0f, 0,
10389 AC_VERB_SET_AMP_GAIN_MUTE,
10391 snd_hda_codec_write(codec, 0x10, 0,
10392 AC_VERB_SET_AMP_GAIN_MUTE,
10395 snd_hda_codec_write(codec, 0x0f, 0,
10396 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10397 snd_hda_codec_write(codec, 0x10, 0,
10398 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
10401 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
10402 if (line_nid == 0x14)
10403 dac_vol2 = AMP_OUT_ZERO;
10404 else if (line_nid == 0x15)
10405 dac_vol1 = AMP_OUT_ZERO;
10406 if (hp_nid == 0x14)
10407 dac_vol2 = AMP_OUT_ZERO;
10408 else if (hp_nid == 0x15)
10409 dac_vol1 = AMP_OUT_ZERO;
10410 if (line_nid != 0x16 || hp_nid != 0x16 ||
10411 spec->autocfg.line_out_pins[1] != 0x16 ||
10412 spec->autocfg.line_out_pins[2] != 0x16)
10413 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
10415 snd_hda_codec_write(codec, 0x02, 0,
10416 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
10417 snd_hda_codec_write(codec, 0x03, 0,
10418 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
10421 /* pcm configuration: identiacal with ALC880 */
10422 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
10423 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
10424 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
10425 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
10428 * BIOS auto configuration
10430 static int alc268_parse_auto_config(struct hda_codec *codec)
10432 struct alc_spec *spec = codec->spec;
10434 static hda_nid_t alc268_ignore[] = { 0 };
10436 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10440 if (!spec->autocfg.line_outs)
10441 return 0; /* can't find valid BIOS pin config */
10443 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
10446 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
10450 spec->multiout.max_channels = 2;
10452 /* digital only support output */
10453 if (spec->autocfg.dig_out_pin)
10454 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
10456 if (spec->kctl_alloc)
10457 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10459 if (spec->autocfg.speaker_pins[0] != 0x1d)
10460 spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
10462 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
10463 spec->num_mux_defs = 1;
10464 spec->input_mux = &spec->private_imux;
10466 err = alc_auto_add_mic_boost(codec);
10473 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
10474 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
10475 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
10477 /* init callback for auto-configuration model -- overriding the default init */
10478 static void alc268_auto_init(struct hda_codec *codec)
10480 struct alc_spec *spec = codec->spec;
10481 alc268_auto_init_multi_out(codec);
10482 alc268_auto_init_hp_out(codec);
10483 alc268_auto_init_mono_speaker_out(codec);
10484 alc268_auto_init_analog_input(codec);
10485 if (spec->unsol_event)
10486 alc_sku_automute(codec);
10490 * configuration and preset
10492 static const char *alc268_models[ALC268_MODEL_LAST] = {
10493 [ALC267_QUANTA_IL1] = "quanta-il1",
10494 [ALC268_3ST] = "3stack",
10495 [ALC268_TOSHIBA] = "toshiba",
10496 [ALC268_ACER] = "acer",
10497 [ALC268_DELL] = "dell",
10498 [ALC268_ZEPTO] = "zepto",
10499 #ifdef CONFIG_SND_DEBUG
10500 [ALC268_TEST] = "test",
10502 [ALC268_AUTO] = "auto",
10505 static struct snd_pci_quirk alc268_cfg_tbl[] = {
10506 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
10507 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
10508 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
10509 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
10510 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
10511 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
10512 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
10513 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
10514 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
10515 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
10516 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
10517 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
10518 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
10522 static struct alc_config_preset alc268_presets[] = {
10523 [ALC267_QUANTA_IL1] = {
10524 .mixers = { alc267_quanta_il1_mixer },
10525 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10526 alc267_quanta_il1_verbs },
10527 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10528 .dac_nids = alc268_dac_nids,
10529 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10530 .adc_nids = alc268_adc_nids_alt,
10532 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10533 .channel_mode = alc268_modes,
10534 .input_mux = &alc268_capture_source,
10535 .unsol_event = alc267_quanta_il1_unsol_event,
10536 .init_hook = alc267_quanta_il1_automute,
10539 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10540 alc268_beep_mixer },
10541 .init_verbs = { alc268_base_init_verbs },
10542 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10543 .dac_nids = alc268_dac_nids,
10544 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10545 .adc_nids = alc268_adc_nids_alt,
10546 .capsrc_nids = alc268_capsrc_nids,
10548 .dig_out_nid = ALC268_DIGOUT_NID,
10549 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10550 .channel_mode = alc268_modes,
10551 .input_mux = &alc268_capture_source,
10553 [ALC268_TOSHIBA] = {
10554 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10555 alc268_beep_mixer },
10556 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10557 alc268_toshiba_verbs },
10558 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10559 .dac_nids = alc268_dac_nids,
10560 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10561 .adc_nids = alc268_adc_nids_alt,
10562 .capsrc_nids = alc268_capsrc_nids,
10564 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10565 .channel_mode = alc268_modes,
10566 .input_mux = &alc268_capture_source,
10567 .unsol_event = alc268_toshiba_unsol_event,
10568 .init_hook = alc268_toshiba_automute,
10571 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
10572 alc268_beep_mixer },
10573 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10574 alc268_acer_verbs },
10575 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10576 .dac_nids = alc268_dac_nids,
10577 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10578 .adc_nids = alc268_adc_nids_alt,
10579 .capsrc_nids = alc268_capsrc_nids,
10581 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10582 .channel_mode = alc268_modes,
10583 .input_mux = &alc268_acer_capture_source,
10584 .unsol_event = alc268_acer_unsol_event,
10585 .init_hook = alc268_acer_init_hook,
10588 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
10589 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10590 alc268_dell_verbs },
10591 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10592 .dac_nids = alc268_dac_nids,
10594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10595 .channel_mode = alc268_modes,
10596 .unsol_event = alc268_dell_unsol_event,
10597 .init_hook = alc268_dell_init_hook,
10598 .input_mux = &alc268_capture_source,
10601 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
10602 alc268_beep_mixer },
10603 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10604 alc268_toshiba_verbs },
10605 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10606 .dac_nids = alc268_dac_nids,
10607 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10608 .adc_nids = alc268_adc_nids_alt,
10609 .capsrc_nids = alc268_capsrc_nids,
10611 .dig_out_nid = ALC268_DIGOUT_NID,
10612 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10613 .channel_mode = alc268_modes,
10614 .input_mux = &alc268_capture_source,
10615 .unsol_event = alc268_toshiba_unsol_event,
10616 .init_hook = alc268_toshiba_automute
10618 #ifdef CONFIG_SND_DEBUG
10620 .mixers = { alc268_test_mixer, alc268_capture_mixer },
10621 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
10622 alc268_volume_init_verbs },
10623 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
10624 .dac_nids = alc268_dac_nids,
10625 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
10626 .adc_nids = alc268_adc_nids_alt,
10627 .capsrc_nids = alc268_capsrc_nids,
10629 .dig_out_nid = ALC268_DIGOUT_NID,
10630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
10631 .channel_mode = alc268_modes,
10632 .input_mux = &alc268_capture_source,
10637 static int patch_alc268(struct hda_codec *codec)
10639 struct alc_spec *spec;
10643 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
10647 codec->spec = spec;
10649 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
10653 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
10654 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
10655 "trying auto-probe from BIOS...\n");
10656 board_config = ALC268_AUTO;
10659 if (board_config == ALC268_AUTO) {
10660 /* automatic parse from the BIOS config */
10661 err = alc268_parse_auto_config(codec);
10667 "hda_codec: Cannot set up configuration "
10668 "from BIOS. Using base mode...\n");
10669 board_config = ALC268_3ST;
10673 if (board_config != ALC268_AUTO)
10674 setup_preset(spec, &alc268_presets[board_config]);
10676 spec->stream_name_analog = "ALC268 Analog";
10677 spec->stream_analog_playback = &alc268_pcm_analog_playback;
10678 spec->stream_analog_capture = &alc268_pcm_analog_capture;
10679 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
10681 spec->stream_name_digital = "ALC268 Digital";
10682 spec->stream_digital_playback = &alc268_pcm_digital_playback;
10684 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
10685 /* override the amp caps for beep generator */
10686 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
10687 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
10688 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
10689 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
10690 (0 << AC_AMPCAP_MUTE_SHIFT));
10692 if (!spec->adc_nids && spec->input_mux) {
10693 /* check whether NID 0x07 is valid */
10694 unsigned int wcap = get_wcaps(codec, 0x07);
10698 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10699 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
10700 spec->adc_nids = alc268_adc_nids_alt;
10701 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
10702 spec->mixers[spec->num_mixers] =
10703 alc268_capture_alt_mixer;
10704 spec->num_mixers++;
10706 spec->adc_nids = alc268_adc_nids;
10707 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
10708 spec->mixers[spec->num_mixers] =
10709 alc268_capture_mixer;
10710 spec->num_mixers++;
10712 spec->capsrc_nids = alc268_capsrc_nids;
10713 /* set default input source */
10714 for (i = 0; i < spec->num_adc_nids; i++)
10715 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
10716 0, AC_VERB_SET_CONNECT_SEL,
10717 spec->input_mux->items[0].index);
10720 spec->vmaster_nid = 0x02;
10722 codec->patch_ops = alc_patch_ops;
10723 if (board_config == ALC268_AUTO)
10724 spec->init_hook = alc268_auto_init;
10730 * ALC269 channel source setting (2 channel)
10732 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
10734 #define alc269_dac_nids alc260_dac_nids
10736 static hda_nid_t alc269_adc_nids[1] = {
10741 #define alc269_modes alc260_modes
10742 #define alc269_capture_source alc880_lg_lw_capture_source
10744 static struct snd_kcontrol_new alc269_base_mixer[] = {
10745 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10746 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10747 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10748 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10749 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10750 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10751 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10752 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10753 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10754 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10756 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10760 /* capture mixer elements */
10761 static struct snd_kcontrol_new alc269_capture_mixer[] = {
10762 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10763 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10765 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10766 /* The multiple "Capture Source" controls confuse alsamixer
10767 * So call somewhat different..
10769 /* .name = "Capture Source", */
10770 .name = "Input Source",
10772 .info = alc_mux_enum_info,
10773 .get = alc_mux_enum_get,
10774 .put = alc_mux_enum_put,
10780 * generic initialization of ADC, input mixers and output mixers
10782 static struct hda_verb alc269_init_verbs[] = {
10784 * Unmute ADC0 and set the default input to mic-in
10786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10788 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
10789 * analog-loopback mixer widget
10790 * Note: PASD motherboards uses the Line In 2 as the input for
10791 * front panel mic (mic 2)
10793 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10798 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10801 * Set up output mixers (0x0c - 0x0e)
10803 /* set vol=0 to output mixers */
10804 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10805 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10807 /* set up input amps for analog loopback */
10808 /* Amp Indices: DAC = 0, mixer = 1 */
10809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10811 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10812 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10813 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10814 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10819 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10820 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10822 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10824 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10827 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10828 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10829 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10830 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10835 /* FIXME: use matrix-type input source selection */
10836 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
10837 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10838 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10839 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10840 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10841 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10844 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10845 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10849 /* add playback controls from the parsed DAC table */
10850 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
10851 const struct auto_pin_cfg *cfg)
10856 spec->multiout.num_dacs = 1; /* only use one dac */
10857 spec->multiout.dac_nids = spec->private_dac_nids;
10858 spec->multiout.dac_nids[0] = 2;
10860 nid = cfg->line_out_pins[0];
10862 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10863 "Front Playback Volume",
10864 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
10867 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10868 "Front Playback Switch",
10869 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10874 nid = cfg->speaker_pins[0];
10876 if (!cfg->line_out_pins[0]) {
10877 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10878 "Speaker Playback Volume",
10879 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10885 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10886 "Speaker Playback Switch",
10887 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10892 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10893 "Speaker Playback Switch",
10894 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10900 nid = cfg->hp_pins[0];
10902 /* spec->multiout.hp_nid = 2; */
10903 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
10904 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10905 "Headphone Playback Volume",
10906 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
10912 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10913 "Headphone Playback Switch",
10914 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10919 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10920 "Headphone Playback Switch",
10921 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10930 #define alc269_auto_create_analog_input_ctls \
10931 alc880_auto_create_analog_input_ctls
10933 #ifdef CONFIG_SND_HDA_POWER_SAVE
10934 #define alc269_loopbacks alc880_loopbacks
10937 /* pcm configuration: identiacal with ALC880 */
10938 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
10939 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
10940 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
10941 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
10944 * BIOS auto configuration
10946 static int alc269_parse_auto_config(struct hda_codec *codec)
10948 struct alc_spec *spec = codec->spec;
10950 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
10952 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10957 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
10960 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
10964 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10966 if (spec->autocfg.dig_out_pin)
10967 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
10969 if (spec->kctl_alloc)
10970 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10972 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs;
10973 spec->num_mux_defs = 1;
10974 spec->input_mux = &spec->private_imux;
10976 err = alc_auto_add_mic_boost(codec);
10983 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
10984 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
10985 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
10988 /* init callback for auto-configuration model -- overriding the default init */
10989 static void alc269_auto_init(struct hda_codec *codec)
10991 struct alc_spec *spec = codec->spec;
10992 alc269_auto_init_multi_out(codec);
10993 alc269_auto_init_hp_out(codec);
10994 alc269_auto_init_analog_input(codec);
10995 if (spec->unsol_event)
10996 alc_sku_automute(codec);
11000 * configuration and preset
11002 static const char *alc269_models[ALC269_MODEL_LAST] = {
11003 [ALC269_BASIC] = "basic",
11006 static struct snd_pci_quirk alc269_cfg_tbl[] = {
11010 static struct alc_config_preset alc269_presets[] = {
11012 .mixers = { alc269_base_mixer },
11013 .init_verbs = { alc269_init_verbs },
11014 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
11015 .dac_nids = alc269_dac_nids,
11017 .num_channel_mode = ARRAY_SIZE(alc269_modes),
11018 .channel_mode = alc269_modes,
11019 .input_mux = &alc269_capture_source,
11023 static int patch_alc269(struct hda_codec *codec)
11025 struct alc_spec *spec;
11029 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11033 codec->spec = spec;
11035 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
11039 if (board_config < 0) {
11040 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
11041 "trying auto-probe from BIOS...\n");
11042 board_config = ALC269_AUTO;
11045 if (board_config == ALC269_AUTO) {
11046 /* automatic parse from the BIOS config */
11047 err = alc269_parse_auto_config(codec);
11053 "hda_codec: Cannot set up configuration "
11054 "from BIOS. Using base mode...\n");
11055 board_config = ALC269_BASIC;
11059 if (board_config != ALC269_AUTO)
11060 setup_preset(spec, &alc269_presets[board_config]);
11062 spec->stream_name_analog = "ALC269 Analog";
11063 spec->stream_analog_playback = &alc269_pcm_analog_playback;
11064 spec->stream_analog_capture = &alc269_pcm_analog_capture;
11066 spec->stream_name_digital = "ALC269 Digital";
11067 spec->stream_digital_playback = &alc269_pcm_digital_playback;
11068 spec->stream_digital_capture = &alc269_pcm_digital_capture;
11070 spec->adc_nids = alc269_adc_nids;
11071 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
11072 spec->mixers[spec->num_mixers] = alc269_capture_mixer;
11073 spec->num_mixers++;
11075 codec->patch_ops = alc_patch_ops;
11076 if (board_config == ALC269_AUTO)
11077 spec->init_hook = alc269_auto_init;
11078 #ifdef CONFIG_SND_HDA_POWER_SAVE
11079 if (!spec->loopback.amplist)
11080 spec->loopback.amplist = alc269_loopbacks;
11087 * ALC861 channel source setting (2/6 channel selection for 3-stack)
11091 * set the path ways for 2 channel output
11092 * need to set the codec line out and mic 1 pin widgets to inputs
11094 static struct hda_verb alc861_threestack_ch2_init[] = {
11095 /* set pin widget 1Ah (line in) for input */
11096 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11097 /* set pin widget 18h (mic1/2) for input, for mic also enable
11100 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11102 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11104 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11105 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11111 * need to set the codec line out and mic 1 pin widgets to outputs
11113 static struct hda_verb alc861_threestack_ch6_init[] = {
11114 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11115 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11116 /* set pin widget 18h (mic1) for output (CLFE)*/
11117 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11119 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11120 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11122 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11124 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11125 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11130 static struct hda_channel_mode alc861_threestack_modes[2] = {
11131 { 2, alc861_threestack_ch2_init },
11132 { 6, alc861_threestack_ch6_init },
11134 /* Set mic1 as input and unmute the mixer */
11135 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
11136 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11137 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11140 /* Set mic1 as output and mute mixer */
11141 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
11142 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11143 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11147 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
11148 { 2, alc861_uniwill_m31_ch2_init },
11149 { 4, alc861_uniwill_m31_ch4_init },
11152 /* Set mic1 and line-in as input and unmute the mixer */
11153 static struct hda_verb alc861_asus_ch2_init[] = {
11154 /* set pin widget 1Ah (line in) for input */
11155 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11156 /* set pin widget 18h (mic1/2) for input, for mic also enable
11159 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11161 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
11163 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
11164 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
11168 /* Set mic1 nad line-in as output and mute mixer */
11169 static struct hda_verb alc861_asus_ch6_init[] = {
11170 /* set pin widget 1Ah (line in) for output (Back Surround)*/
11171 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11172 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11173 /* set pin widget 18h (mic1) for output (CLFE)*/
11174 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11175 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
11176 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
11177 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
11179 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
11181 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
11182 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
11187 static struct hda_channel_mode alc861_asus_modes[2] = {
11188 { 2, alc861_asus_ch2_init },
11189 { 6, alc861_asus_ch6_init },
11194 static struct snd_kcontrol_new alc861_base_mixer[] = {
11195 /* output mixer control */
11196 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11197 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11198 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11199 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11200 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11202 /*Input mixer control */
11203 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11204 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11205 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11206 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11207 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11208 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11210 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11211 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11214 /* Capture mixer control */
11215 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11216 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11218 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11219 .name = "Capture Source",
11221 .info = alc_mux_enum_info,
11222 .get = alc_mux_enum_get,
11223 .put = alc_mux_enum_put,
11228 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
11229 /* output mixer control */
11230 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11231 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11232 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11233 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11234 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11236 /* Input mixer control */
11237 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11238 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11239 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11240 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11241 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11242 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11244 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11245 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11246 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11248 /* Capture mixer control */
11249 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11250 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11253 .name = "Capture Source",
11255 .info = alc_mux_enum_info,
11256 .get = alc_mux_enum_get,
11257 .put = alc_mux_enum_put,
11260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11261 .name = "Channel Mode",
11262 .info = alc_ch_mode_info,
11263 .get = alc_ch_mode_get,
11264 .put = alc_ch_mode_put,
11265 .private_value = ARRAY_SIZE(alc861_threestack_modes),
11270 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
11271 /* output mixer control */
11272 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11274 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11276 /*Capture mixer control */
11277 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11278 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11280 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11281 .name = "Capture Source",
11283 .info = alc_mux_enum_info,
11284 .get = alc_mux_enum_get,
11285 .put = alc_mux_enum_put,
11291 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
11292 /* output mixer control */
11293 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11294 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11295 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11296 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11297 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
11299 /* Input mixer control */
11300 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11301 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
11302 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11303 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11304 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11305 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11307 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11308 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
11311 /* Capture mixer control */
11312 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11313 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11316 .name = "Capture Source",
11318 .info = alc_mux_enum_info,
11319 .get = alc_mux_enum_get,
11320 .put = alc_mux_enum_put,
11323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11324 .name = "Channel Mode",
11325 .info = alc_ch_mode_info,
11326 .get = alc_ch_mode_get,
11327 .put = alc_ch_mode_put,
11328 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
11333 static struct snd_kcontrol_new alc861_asus_mixer[] = {
11334 /* output mixer control */
11335 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11336 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
11337 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
11338 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
11339 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
11341 /* Input mixer control */
11342 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
11343 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11344 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11345 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11346 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
11347 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
11348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
11349 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
11350 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
11351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
11353 /* Capture mixer control */
11354 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11355 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11358 .name = "Capture Source",
11360 .info = alc_mux_enum_info,
11361 .get = alc_mux_enum_get,
11362 .put = alc_mux_enum_put,
11365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11366 .name = "Channel Mode",
11367 .info = alc_ch_mode_info,
11368 .get = alc_ch_mode_get,
11369 .put = alc_ch_mode_put,
11370 .private_value = ARRAY_SIZE(alc861_asus_modes),
11375 /* additional mixer */
11376 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
11377 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
11378 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
11379 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
11380 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
11385 * generic initialization of ADC, input mixers and output mixers
11387 static struct hda_verb alc861_base_init_verbs[] = {
11389 * Unmute ADC0 and set the default input to mic-in
11391 /* port-A for surround (rear panel) */
11392 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11393 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
11394 /* port-B for mic-in (rear panel) with vref */
11395 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11396 /* port-C for line-in (rear panel) */
11397 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11398 /* port-D for Front */
11399 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11400 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11401 /* port-E for HP out (front panel) */
11402 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11403 /* route front PCM to HP */
11404 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11405 /* port-F for mic-in (front panel) with vref */
11406 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11407 /* port-G for CLFE (rear panel) */
11408 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11409 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11410 /* port-H for side (rear panel) */
11411 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11412 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
11414 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11415 /* route front mic to ADC1*/
11416 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11417 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11419 /* Unmute DAC0~3 & spdif out*/
11420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11423 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11426 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11427 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11428 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11429 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11430 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11432 /* Unmute Stereo Mixer 15 */
11433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11441 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11446 /* hp used DAC 3 (Front) */
11447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11453 static struct hda_verb alc861_threestack_init_verbs[] = {
11455 * Unmute ADC0 and set the default input to mic-in
11457 /* port-A for surround (rear panel) */
11458 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11459 /* port-B for mic-in (rear panel) with vref */
11460 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11461 /* port-C for line-in (rear panel) */
11462 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11463 /* port-D for Front */
11464 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11465 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11466 /* port-E for HP out (front panel) */
11467 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
11468 /* route front PCM to HP */
11469 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11470 /* port-F for mic-in (front panel) with vref */
11471 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11472 /* port-G for CLFE (rear panel) */
11473 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11474 /* port-H for side (rear panel) */
11475 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11477 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11478 /* route front mic to ADC1*/
11479 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11480 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11481 /* Unmute DAC0~3 & spdif out*/
11482 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11483 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11484 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11485 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11488 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11489 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11490 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11491 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11492 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11494 /* Unmute Stereo Mixer 15 */
11495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11500 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11502 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11504 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11505 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11507 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11508 /* hp used DAC 3 (Front) */
11509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11514 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
11516 * Unmute ADC0 and set the default input to mic-in
11518 /* port-A for surround (rear panel) */
11519 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11520 /* port-B for mic-in (rear panel) with vref */
11521 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11522 /* port-C for line-in (rear panel) */
11523 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11524 /* port-D for Front */
11525 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11526 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11527 /* port-E for HP out (front panel) */
11528 /* this has to be set to VREF80 */
11529 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11530 /* route front PCM to HP */
11531 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11532 /* port-F for mic-in (front panel) with vref */
11533 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11534 /* port-G for CLFE (rear panel) */
11535 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11536 /* port-H for side (rear panel) */
11537 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11539 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11540 /* route front mic to ADC1*/
11541 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11543 /* Unmute DAC0~3 & spdif out*/
11544 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11545 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11546 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11547 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11550 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11551 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11552 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11553 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11554 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11556 /* Unmute Stereo Mixer 15 */
11557 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11563 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11564 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11565 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11568 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11569 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11570 /* hp used DAC 3 (Front) */
11571 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11572 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11576 static struct hda_verb alc861_asus_init_verbs[] = {
11578 * Unmute ADC0 and set the default input to mic-in
11580 /* port-A for surround (rear panel)
11581 * according to codec#0 this is the HP jack
11583 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
11584 /* route front PCM to HP */
11585 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
11586 /* port-B for mic-in (rear panel) with vref */
11587 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11588 /* port-C for line-in (rear panel) */
11589 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11590 /* port-D for Front */
11591 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11592 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
11593 /* port-E for HP out (front panel) */
11594 /* this has to be set to VREF80 */
11595 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11596 /* route front PCM to HP */
11597 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
11598 /* port-F for mic-in (front panel) with vref */
11599 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
11600 /* port-G for CLFE (rear panel) */
11601 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11602 /* port-H for side (rear panel) */
11603 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
11605 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
11606 /* route front mic to ADC1*/
11607 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11608 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11609 /* Unmute DAC0~3 & spdif out*/
11610 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11611 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11613 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11615 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11616 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11617 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11618 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11619 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11621 /* Unmute Stereo Mixer 15 */
11622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
11627 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11629 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11633 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11635 /* hp used DAC 3 (Front) */
11636 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11641 /* additional init verbs for ASUS laptops */
11642 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
11643 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
11644 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
11649 * generic initialization of ADC, input mixers and output mixers
11651 static struct hda_verb alc861_auto_init_verbs[] = {
11653 * Unmute ADC0 and set the default input to mic-in
11655 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
11656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11658 /* Unmute DAC0~3 & spdif out*/
11659 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11660 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11661 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11662 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11663 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11665 /* Unmute Mixer 14 (mic) 1c (Line in)*/
11666 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11667 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11668 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11669 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11671 /* Unmute Stereo Mixer 15 */
11672 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11673 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11674 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
11677 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11678 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11679 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11680 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11681 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11682 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11683 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11684 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11686 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11687 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11688 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11689 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11690 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11691 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11692 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11693 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
11695 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
11700 static struct hda_verb alc861_toshiba_init_verbs[] = {
11701 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11706 /* toggle speaker-output according to the hp-jack state */
11707 static void alc861_toshiba_automute(struct hda_codec *codec)
11709 unsigned int present;
11711 present = snd_hda_codec_read(codec, 0x0f, 0,
11712 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11713 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
11714 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11715 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
11716 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
11719 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
11722 if ((res >> 26) == ALC880_HP_EVENT)
11723 alc861_toshiba_automute(codec);
11726 /* pcm configuration: identiacal with ALC880 */
11727 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
11728 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
11729 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
11730 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
11733 #define ALC861_DIGOUT_NID 0x07
11735 static struct hda_channel_mode alc861_8ch_modes[1] = {
11739 static hda_nid_t alc861_dac_nids[4] = {
11740 /* front, surround, clfe, side */
11741 0x03, 0x06, 0x05, 0x04
11744 static hda_nid_t alc660_dac_nids[3] = {
11745 /* front, clfe, surround */
11749 static hda_nid_t alc861_adc_nids[1] = {
11754 static struct hda_input_mux alc861_capture_source = {
11758 { "Front Mic", 0x3 },
11765 /* fill in the dac_nids table from the parsed pin configuration */
11766 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
11767 const struct auto_pin_cfg *cfg)
11772 spec->multiout.dac_nids = spec->private_dac_nids;
11773 for (i = 0; i < cfg->line_outs; i++) {
11774 nid = cfg->line_out_pins[i];
11776 if (i >= ARRAY_SIZE(alc861_dac_nids))
11778 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
11781 spec->multiout.num_dacs = cfg->line_outs;
11785 /* add playback controls from the parsed DAC table */
11786 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
11787 const struct auto_pin_cfg *cfg)
11790 static const char *chname[4] = {
11791 "Front", "Surround", NULL /*CLFE*/, "Side"
11796 for (i = 0; i < cfg->line_outs; i++) {
11797 nid = spec->multiout.dac_nids[i];
11802 err = add_control(spec, ALC_CTL_BIND_MUTE,
11803 "Center Playback Switch",
11804 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
11808 err = add_control(spec, ALC_CTL_BIND_MUTE,
11809 "LFE Playback Switch",
11810 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
11815 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
11817 if (nid == alc861_dac_nids[idx])
11819 sprintf(name, "%s Playback Switch", chname[idx]);
11820 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11821 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
11830 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
11838 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
11840 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11841 "Headphone Playback Switch",
11842 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
11845 spec->multiout.hp_nid = nid;
11850 /* create playback/capture controls for input pins */
11851 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
11852 const struct auto_pin_cfg *cfg)
11854 struct hda_input_mux *imux = &spec->private_imux;
11855 int i, err, idx, idx1;
11857 for (i = 0; i < AUTO_PIN_LAST; i++) {
11858 switch (cfg->input_pins[i]) {
11861 idx = 2; /* Line In */
11865 idx = 2; /* Line In */
11869 idx = 1; /* Mic In */
11873 idx = 1; /* Mic In */
11883 err = new_analog_input(spec, cfg->input_pins[i],
11884 auto_pin_cfg_labels[i], idx, 0x15);
11888 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11889 imux->items[imux->num_items].index = idx1;
11895 static struct snd_kcontrol_new alc861_capture_mixer[] = {
11896 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11897 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11901 /* The multiple "Capture Source" controls confuse alsamixer
11902 * So call somewhat different..
11904 /* .name = "Capture Source", */
11905 .name = "Input Source",
11907 .info = alc_mux_enum_info,
11908 .get = alc_mux_enum_get,
11909 .put = alc_mux_enum_put,
11914 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
11916 int pin_type, int dac_idx)
11918 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11920 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
11924 static void alc861_auto_init_multi_out(struct hda_codec *codec)
11926 struct alc_spec *spec = codec->spec;
11929 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
11930 for (i = 0; i < spec->autocfg.line_outs; i++) {
11931 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11932 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11934 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
11935 spec->multiout.dac_nids[i]);
11939 static void alc861_auto_init_hp_out(struct hda_codec *codec)
11941 struct alc_spec *spec = codec->spec;
11944 pin = spec->autocfg.hp_pins[0];
11945 if (pin) /* connect to front */
11946 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
11947 spec->multiout.dac_nids[0]);
11948 pin = spec->autocfg.speaker_pins[0];
11950 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
11953 static void alc861_auto_init_analog_input(struct hda_codec *codec)
11955 struct alc_spec *spec = codec->spec;
11958 for (i = 0; i < AUTO_PIN_LAST; i++) {
11959 hda_nid_t nid = spec->autocfg.input_pins[i];
11960 if (nid >= 0x0c && nid <= 0x11) {
11961 snd_hda_codec_write(codec, nid, 0,
11962 AC_VERB_SET_PIN_WIDGET_CONTROL,
11963 i <= AUTO_PIN_FRONT_MIC ?
11964 PIN_VREF80 : PIN_IN);
11969 /* parse the BIOS configuration and set up the alc_spec */
11970 /* return 1 if successful, 0 if the proper config is not found,
11971 * or a negative error code
11973 static int alc861_parse_auto_config(struct hda_codec *codec)
11975 struct alc_spec *spec = codec->spec;
11977 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
11979 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11983 if (!spec->autocfg.line_outs)
11984 return 0; /* can't find valid BIOS pin config */
11986 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
11989 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
11992 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
11995 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
11999 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12001 if (spec->autocfg.dig_out_pin)
12002 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
12004 if (spec->kctl_alloc)
12005 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12007 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
12009 spec->num_mux_defs = 1;
12010 spec->input_mux = &spec->private_imux;
12012 spec->adc_nids = alc861_adc_nids;
12013 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
12014 spec->mixers[spec->num_mixers] = alc861_capture_mixer;
12015 spec->num_mixers++;
12020 /* additional initialization for auto-configuration model */
12021 static void alc861_auto_init(struct hda_codec *codec)
12023 struct alc_spec *spec = codec->spec;
12024 alc861_auto_init_multi_out(codec);
12025 alc861_auto_init_hp_out(codec);
12026 alc861_auto_init_analog_input(codec);
12027 if (spec->unsol_event)
12028 alc_sku_automute(codec);
12031 #ifdef CONFIG_SND_HDA_POWER_SAVE
12032 static struct hda_amp_list alc861_loopbacks[] = {
12033 { 0x15, HDA_INPUT, 0 },
12034 { 0x15, HDA_INPUT, 1 },
12035 { 0x15, HDA_INPUT, 2 },
12036 { 0x15, HDA_INPUT, 3 },
12043 * configuration and preset
12045 static const char *alc861_models[ALC861_MODEL_LAST] = {
12046 [ALC861_3ST] = "3stack",
12047 [ALC660_3ST] = "3stack-660",
12048 [ALC861_3ST_DIG] = "3stack-dig",
12049 [ALC861_6ST_DIG] = "6stack-dig",
12050 [ALC861_UNIWILL_M31] = "uniwill-m31",
12051 [ALC861_TOSHIBA] = "toshiba",
12052 [ALC861_ASUS] = "asus",
12053 [ALC861_ASUS_LAPTOP] = "asus-laptop",
12054 [ALC861_AUTO] = "auto",
12057 static struct snd_pci_quirk alc861_cfg_tbl[] = {
12058 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
12059 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12060 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
12061 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
12062 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
12063 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
12064 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
12065 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
12066 * Any other models that need this preset?
12068 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
12069 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
12070 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
12071 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
12072 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
12073 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
12074 /* FIXME: the below seems conflict */
12075 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
12076 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
12077 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
12081 static struct alc_config_preset alc861_presets[] = {
12083 .mixers = { alc861_3ST_mixer },
12084 .init_verbs = { alc861_threestack_init_verbs },
12085 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12086 .dac_nids = alc861_dac_nids,
12087 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12088 .channel_mode = alc861_threestack_modes,
12090 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12091 .adc_nids = alc861_adc_nids,
12092 .input_mux = &alc861_capture_source,
12094 [ALC861_3ST_DIG] = {
12095 .mixers = { alc861_base_mixer },
12096 .init_verbs = { alc861_threestack_init_verbs },
12097 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12098 .dac_nids = alc861_dac_nids,
12099 .dig_out_nid = ALC861_DIGOUT_NID,
12100 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12101 .channel_mode = alc861_threestack_modes,
12103 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12104 .adc_nids = alc861_adc_nids,
12105 .input_mux = &alc861_capture_source,
12107 [ALC861_6ST_DIG] = {
12108 .mixers = { alc861_base_mixer },
12109 .init_verbs = { alc861_base_init_verbs },
12110 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12111 .dac_nids = alc861_dac_nids,
12112 .dig_out_nid = ALC861_DIGOUT_NID,
12113 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
12114 .channel_mode = alc861_8ch_modes,
12115 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12116 .adc_nids = alc861_adc_nids,
12117 .input_mux = &alc861_capture_source,
12120 .mixers = { alc861_3ST_mixer },
12121 .init_verbs = { alc861_threestack_init_verbs },
12122 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
12123 .dac_nids = alc660_dac_nids,
12124 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
12125 .channel_mode = alc861_threestack_modes,
12127 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12128 .adc_nids = alc861_adc_nids,
12129 .input_mux = &alc861_capture_source,
12131 [ALC861_UNIWILL_M31] = {
12132 .mixers = { alc861_uniwill_m31_mixer },
12133 .init_verbs = { alc861_uniwill_m31_init_verbs },
12134 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12135 .dac_nids = alc861_dac_nids,
12136 .dig_out_nid = ALC861_DIGOUT_NID,
12137 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
12138 .channel_mode = alc861_uniwill_m31_modes,
12140 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12141 .adc_nids = alc861_adc_nids,
12142 .input_mux = &alc861_capture_source,
12144 [ALC861_TOSHIBA] = {
12145 .mixers = { alc861_toshiba_mixer },
12146 .init_verbs = { alc861_base_init_verbs,
12147 alc861_toshiba_init_verbs },
12148 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12149 .dac_nids = alc861_dac_nids,
12150 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12151 .channel_mode = alc883_3ST_2ch_modes,
12152 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12153 .adc_nids = alc861_adc_nids,
12154 .input_mux = &alc861_capture_source,
12155 .unsol_event = alc861_toshiba_unsol_event,
12156 .init_hook = alc861_toshiba_automute,
12159 .mixers = { alc861_asus_mixer },
12160 .init_verbs = { alc861_asus_init_verbs },
12161 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12162 .dac_nids = alc861_dac_nids,
12163 .dig_out_nid = ALC861_DIGOUT_NID,
12164 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
12165 .channel_mode = alc861_asus_modes,
12168 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12169 .adc_nids = alc861_adc_nids,
12170 .input_mux = &alc861_capture_source,
12172 [ALC861_ASUS_LAPTOP] = {
12173 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
12174 .init_verbs = { alc861_asus_init_verbs,
12175 alc861_asus_laptop_init_verbs },
12176 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
12177 .dac_nids = alc861_dac_nids,
12178 .dig_out_nid = ALC861_DIGOUT_NID,
12179 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
12180 .channel_mode = alc883_3ST_2ch_modes,
12182 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
12183 .adc_nids = alc861_adc_nids,
12184 .input_mux = &alc861_capture_source,
12189 static int patch_alc861(struct hda_codec *codec)
12191 struct alc_spec *spec;
12195 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12199 codec->spec = spec;
12201 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
12205 if (board_config < 0) {
12206 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
12207 "trying auto-probe from BIOS...\n");
12208 board_config = ALC861_AUTO;
12211 if (board_config == ALC861_AUTO) {
12212 /* automatic parse from the BIOS config */
12213 err = alc861_parse_auto_config(codec);
12219 "hda_codec: Cannot set up configuration "
12220 "from BIOS. Using base mode...\n");
12221 board_config = ALC861_3ST_DIG;
12225 if (board_config != ALC861_AUTO)
12226 setup_preset(spec, &alc861_presets[board_config]);
12228 spec->stream_name_analog = "ALC861 Analog";
12229 spec->stream_analog_playback = &alc861_pcm_analog_playback;
12230 spec->stream_analog_capture = &alc861_pcm_analog_capture;
12232 spec->stream_name_digital = "ALC861 Digital";
12233 spec->stream_digital_playback = &alc861_pcm_digital_playback;
12234 spec->stream_digital_capture = &alc861_pcm_digital_capture;
12236 spec->vmaster_nid = 0x03;
12238 codec->patch_ops = alc_patch_ops;
12239 if (board_config == ALC861_AUTO)
12240 spec->init_hook = alc861_auto_init;
12241 #ifdef CONFIG_SND_HDA_POWER_SAVE
12242 if (!spec->loopback.amplist)
12243 spec->loopback.amplist = alc861_loopbacks;
12250 * ALC861-VD support
12254 * In addition, an independent DAC
12256 #define ALC861VD_DIGOUT_NID 0x06
12258 static hda_nid_t alc861vd_dac_nids[4] = {
12259 /* front, surr, clfe, side surr */
12260 0x02, 0x03, 0x04, 0x05
12263 /* dac_nids for ALC660vd are in a different order - according to
12264 * Realtek's driver.
12265 * This should probably tesult in a different mixer for 6stack models
12266 * of ALC660vd codecs, but for now there is only 3stack mixer
12267 * - and it is the same as in 861vd.
12268 * adc_nids in ALC660vd are (is) the same as in 861vd
12270 static hda_nid_t alc660vd_dac_nids[3] = {
12271 /* front, rear, clfe, rear_surr */
12275 static hda_nid_t alc861vd_adc_nids[1] = {
12280 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
12283 /* FIXME: should be a matrix-type input source selection */
12284 static struct hda_input_mux alc861vd_capture_source = {
12288 { "Front Mic", 0x1 },
12294 static struct hda_input_mux alc861vd_dallas_capture_source = {
12297 { "Ext Mic", 0x0 },
12298 { "Int Mic", 0x1 },
12302 static struct hda_input_mux alc861vd_hp_capture_source = {
12305 { "Front Mic", 0x0 },
12306 { "ATAPI Mic", 0x1 },
12310 #define alc861vd_mux_enum_info alc_mux_enum_info
12311 #define alc861vd_mux_enum_get alc_mux_enum_get
12312 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
12313 #define alc861vd_mux_enum_put alc882_mux_enum_put
12318 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
12325 static struct hda_verb alc861vd_6stack_ch6_init[] = {
12326 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12327 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12328 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12329 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12336 static struct hda_verb alc861vd_6stack_ch8_init[] = {
12337 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12338 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12339 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12340 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12344 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
12345 { 6, alc861vd_6stack_ch6_init },
12346 { 8, alc861vd_6stack_ch8_init },
12349 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
12351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12352 .name = "Channel Mode",
12353 .info = alc_ch_mode_info,
12354 .get = alc_ch_mode_get,
12355 .put = alc_ch_mode_put,
12360 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
12361 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
12362 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
12365 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12366 /* The multiple "Capture Source" controls confuse alsamixer
12367 * So call somewhat different..
12369 /* .name = "Capture Source", */
12370 .name = "Input Source",
12372 .info = alc861vd_mux_enum_info,
12373 .get = alc861vd_mux_enum_get,
12374 .put = alc861vd_mux_enum_put,
12379 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
12380 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
12382 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
12383 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12386 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12387 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
12389 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
12391 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
12393 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12394 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
12396 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
12397 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
12399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12401 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12403 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12405 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12406 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12407 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12409 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12410 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12412 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12413 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12415 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12416 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12421 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
12422 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12423 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12425 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12431 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12432 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12433 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12438 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12439 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12441 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
12442 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
12447 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
12448 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12449 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
12450 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12458 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12459 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12460 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12462 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12463 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12468 /* Pin assignment: Speaker=0x14, HP = 0x15,
12469 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
12471 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
12472 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12473 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
12474 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12475 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12476 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12477 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12478 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12479 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12480 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12481 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12482 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
12483 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
12487 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
12488 * Front Mic=0x18, ATAPI Mic = 0x19,
12490 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
12491 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
12493 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12494 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
12495 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12497 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12498 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12504 * generic initialization of ADC, input mixers and output mixers
12506 static struct hda_verb alc861vd_volume_init_verbs[] = {
12508 * Unmute ADC0 and set the default input to mic-in
12510 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12513 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
12514 * the analog-loopback mixer widget
12516 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12523 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
12524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
12530 * Set up output mixers (0x02 - 0x05)
12532 /* set vol=0 to output mixers */
12533 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12534 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12535 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12536 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12538 /* set up input amps for analog loopback */
12539 /* Amp Indices: DAC = 0, mixer = 1 */
12540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12543 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12545 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12546 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12553 * 3-stack pin configuration:
12554 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
12556 static struct hda_verb alc861vd_3stack_init_verbs[] = {
12558 * Set pin mode and muting
12560 /* set front pin widgets 0x14 for output */
12561 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12562 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12563 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12565 /* Mic (rear) pin: input vref at 80% */
12566 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12567 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12568 /* Front Mic pin: input vref at 80% */
12569 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12570 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12571 /* Line In pin: input */
12572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12573 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12574 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12576 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12577 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12578 /* CD pin widget for input */
12579 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12585 * 6-stack pin configuration:
12587 static struct hda_verb alc861vd_6stack_init_verbs[] = {
12589 * Set pin mode and muting
12591 /* set front pin widgets 0x14 for output */
12592 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12593 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12594 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12596 /* Rear Pin: output 1 (0x0d) */
12597 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12598 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12599 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12600 /* CLFE Pin: output 2 (0x0e) */
12601 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12602 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12603 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
12604 /* Side Pin: output 3 (0x0f) */
12605 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12606 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12607 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
12609 /* Mic (rear) pin: input vref at 80% */
12610 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12612 /* Front Mic pin: input vref at 80% */
12613 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12614 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12615 /* Line In pin: input */
12616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12617 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12618 /* Line-2 In: Headphone output (output 0 - 0x0c) */
12619 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12620 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12621 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12622 /* CD pin widget for input */
12623 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12628 static struct hda_verb alc861vd_eapd_verbs[] = {
12629 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12633 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
12634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12637 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12638 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12642 /* toggle speaker-output according to the hp-jack state */
12643 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
12645 unsigned int present;
12646 unsigned char bits;
12648 present = snd_hda_codec_read(codec, 0x1b, 0,
12649 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12650 bits = present ? HDA_AMP_MUTE : 0;
12651 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12652 HDA_AMP_MUTE, bits);
12655 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
12657 unsigned int present;
12658 unsigned char bits;
12660 present = snd_hda_codec_read(codec, 0x18, 0,
12661 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12662 bits = present ? HDA_AMP_MUTE : 0;
12663 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
12664 HDA_AMP_MUTE, bits);
12667 static void alc861vd_lenovo_automute(struct hda_codec *codec)
12669 alc861vd_lenovo_hp_automute(codec);
12670 alc861vd_lenovo_mic_automute(codec);
12673 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
12676 switch (res >> 26) {
12677 case ALC880_HP_EVENT:
12678 alc861vd_lenovo_hp_automute(codec);
12680 case ALC880_MIC_EVENT:
12681 alc861vd_lenovo_mic_automute(codec);
12686 static struct hda_verb alc861vd_dallas_verbs[] = {
12687 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12688 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12689 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12690 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12692 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12694 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12695 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12696 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12697 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12699 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12701 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12702 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12704 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12705 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12706 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12707 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12708 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12710 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12711 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
12713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12714 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12715 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12716 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12717 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12719 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12720 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12721 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12724 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12725 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12726 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12731 /* toggle speaker-output according to the hp-jack state */
12732 static void alc861vd_dallas_automute(struct hda_codec *codec)
12734 unsigned int present;
12736 present = snd_hda_codec_read(codec, 0x15, 0,
12737 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12738 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12739 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
12742 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
12744 if ((res >> 26) == ALC880_HP_EVENT)
12745 alc861vd_dallas_automute(codec);
12748 #ifdef CONFIG_SND_HDA_POWER_SAVE
12749 #define alc861vd_loopbacks alc880_loopbacks
12752 /* pcm configuration: identiacal with ALC880 */
12753 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
12754 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
12755 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
12756 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
12759 * configuration and preset
12761 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
12762 [ALC660VD_3ST] = "3stack-660",
12763 [ALC660VD_3ST_DIG] = "3stack-660-digout",
12764 [ALC861VD_3ST] = "3stack",
12765 [ALC861VD_3ST_DIG] = "3stack-digout",
12766 [ALC861VD_6ST_DIG] = "6stack-digout",
12767 [ALC861VD_LENOVO] = "lenovo",
12768 [ALC861VD_DALLAS] = "dallas",
12769 [ALC861VD_HP] = "hp",
12770 [ALC861VD_AUTO] = "auto",
12773 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
12774 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
12775 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
12776 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
12777 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
12778 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
12779 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
12780 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
12781 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
12782 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
12783 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
12784 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
12785 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
12786 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
12787 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
12788 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
12792 static struct alc_config_preset alc861vd_presets[] = {
12794 .mixers = { alc861vd_3st_mixer },
12795 .init_verbs = { alc861vd_volume_init_verbs,
12796 alc861vd_3stack_init_verbs },
12797 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12798 .dac_nids = alc660vd_dac_nids,
12799 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12800 .channel_mode = alc861vd_3stack_2ch_modes,
12801 .input_mux = &alc861vd_capture_source,
12803 [ALC660VD_3ST_DIG] = {
12804 .mixers = { alc861vd_3st_mixer },
12805 .init_verbs = { alc861vd_volume_init_verbs,
12806 alc861vd_3stack_init_verbs },
12807 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12808 .dac_nids = alc660vd_dac_nids,
12809 .dig_out_nid = ALC861VD_DIGOUT_NID,
12810 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12811 .channel_mode = alc861vd_3stack_2ch_modes,
12812 .input_mux = &alc861vd_capture_source,
12815 .mixers = { alc861vd_3st_mixer },
12816 .init_verbs = { alc861vd_volume_init_verbs,
12817 alc861vd_3stack_init_verbs },
12818 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12819 .dac_nids = alc861vd_dac_nids,
12820 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12821 .channel_mode = alc861vd_3stack_2ch_modes,
12822 .input_mux = &alc861vd_capture_source,
12824 [ALC861VD_3ST_DIG] = {
12825 .mixers = { alc861vd_3st_mixer },
12826 .init_verbs = { alc861vd_volume_init_verbs,
12827 alc861vd_3stack_init_verbs },
12828 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12829 .dac_nids = alc861vd_dac_nids,
12830 .dig_out_nid = ALC861VD_DIGOUT_NID,
12831 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12832 .channel_mode = alc861vd_3stack_2ch_modes,
12833 .input_mux = &alc861vd_capture_source,
12835 [ALC861VD_6ST_DIG] = {
12836 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
12837 .init_verbs = { alc861vd_volume_init_verbs,
12838 alc861vd_6stack_init_verbs },
12839 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12840 .dac_nids = alc861vd_dac_nids,
12841 .dig_out_nid = ALC861VD_DIGOUT_NID,
12842 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
12843 .channel_mode = alc861vd_6stack_modes,
12844 .input_mux = &alc861vd_capture_source,
12846 [ALC861VD_LENOVO] = {
12847 .mixers = { alc861vd_lenovo_mixer },
12848 .init_verbs = { alc861vd_volume_init_verbs,
12849 alc861vd_3stack_init_verbs,
12850 alc861vd_eapd_verbs,
12851 alc861vd_lenovo_unsol_verbs },
12852 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
12853 .dac_nids = alc660vd_dac_nids,
12854 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12855 .channel_mode = alc861vd_3stack_2ch_modes,
12856 .input_mux = &alc861vd_capture_source,
12857 .unsol_event = alc861vd_lenovo_unsol_event,
12858 .init_hook = alc861vd_lenovo_automute,
12860 [ALC861VD_DALLAS] = {
12861 .mixers = { alc861vd_dallas_mixer },
12862 .init_verbs = { alc861vd_dallas_verbs },
12863 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12864 .dac_nids = alc861vd_dac_nids,
12865 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12866 .channel_mode = alc861vd_3stack_2ch_modes,
12867 .input_mux = &alc861vd_dallas_capture_source,
12868 .unsol_event = alc861vd_dallas_unsol_event,
12869 .init_hook = alc861vd_dallas_automute,
12872 .mixers = { alc861vd_hp_mixer },
12873 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
12874 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
12875 .dac_nids = alc861vd_dac_nids,
12876 .dig_out_nid = ALC861VD_DIGOUT_NID,
12877 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
12878 .channel_mode = alc861vd_3stack_2ch_modes,
12879 .input_mux = &alc861vd_hp_capture_source,
12880 .unsol_event = alc861vd_dallas_unsol_event,
12881 .init_hook = alc861vd_dallas_automute,
12886 * BIOS auto configuration
12888 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
12889 hda_nid_t nid, int pin_type, int dac_idx)
12891 alc_set_pin_output(codec, nid, pin_type);
12894 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
12896 struct alc_spec *spec = codec->spec;
12899 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
12900 for (i = 0; i <= HDA_SIDE; i++) {
12901 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12902 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12904 alc861vd_auto_set_output_and_unmute(codec, nid,
12910 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
12912 struct alc_spec *spec = codec->spec;
12915 pin = spec->autocfg.hp_pins[0];
12916 if (pin) /* connect to front and use dac 0 */
12917 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12918 pin = spec->autocfg.speaker_pins[0];
12920 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
12923 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
12924 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
12926 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
12928 struct alc_spec *spec = codec->spec;
12931 for (i = 0; i < AUTO_PIN_LAST; i++) {
12932 hda_nid_t nid = spec->autocfg.input_pins[i];
12933 if (alc861vd_is_input_pin(nid)) {
12934 snd_hda_codec_write(codec, nid, 0,
12935 AC_VERB_SET_PIN_WIDGET_CONTROL,
12936 i <= AUTO_PIN_FRONT_MIC ?
12937 PIN_VREF80 : PIN_IN);
12938 if (nid != ALC861VD_PIN_CD_NID)
12939 snd_hda_codec_write(codec, nid, 0,
12940 AC_VERB_SET_AMP_GAIN_MUTE,
12946 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
12947 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
12949 /* add playback controls from the parsed DAC table */
12950 /* Based on ALC880 version. But ALC861VD has separate,
12951 * different NIDs for mute/unmute switch and volume control */
12952 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
12953 const struct auto_pin_cfg *cfg)
12956 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
12957 hda_nid_t nid_v, nid_s;
12960 for (i = 0; i < cfg->line_outs; i++) {
12961 if (!spec->multiout.dac_nids[i])
12963 nid_v = alc861vd_idx_to_mixer_vol(
12965 spec->multiout.dac_nids[i]));
12966 nid_s = alc861vd_idx_to_mixer_switch(
12968 spec->multiout.dac_nids[i]));
12972 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12973 "Center Playback Volume",
12974 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
12978 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12979 "LFE Playback Volume",
12980 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
12984 err = add_control(spec, ALC_CTL_BIND_MUTE,
12985 "Center Playback Switch",
12986 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
12990 err = add_control(spec, ALC_CTL_BIND_MUTE,
12991 "LFE Playback Switch",
12992 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
12997 sprintf(name, "%s Playback Volume", chname[i]);
12998 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12999 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
13003 sprintf(name, "%s Playback Switch", chname[i]);
13004 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13005 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
13014 /* add playback controls for speaker and HP outputs */
13015 /* Based on ALC880 version. But ALC861VD has separate,
13016 * different NIDs for mute/unmute switch and volume control */
13017 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
13018 hda_nid_t pin, const char *pfx)
13020 hda_nid_t nid_v, nid_s;
13027 if (alc880_is_fixed_pin(pin)) {
13028 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13029 /* specify the DAC as the extra output */
13030 if (!spec->multiout.hp_nid)
13031 spec->multiout.hp_nid = nid_v;
13033 spec->multiout.extra_out_nid[0] = nid_v;
13034 /* control HP volume/switch on the output mixer amp */
13035 nid_v = alc861vd_idx_to_mixer_vol(
13036 alc880_fixed_pin_idx(pin));
13037 nid_s = alc861vd_idx_to_mixer_switch(
13038 alc880_fixed_pin_idx(pin));
13040 sprintf(name, "%s Playback Volume", pfx);
13041 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13042 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
13045 sprintf(name, "%s Playback Switch", pfx);
13046 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13047 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
13050 } else if (alc880_is_multi_pin(pin)) {
13051 /* set manual connection */
13052 /* we have only a switch on HP-out PIN */
13053 sprintf(name, "%s Playback Switch", pfx);
13054 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13055 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13062 /* parse the BIOS configuration and set up the alc_spec
13063 * return 1 if successful, 0 if the proper config is not found,
13064 * or a negative error code
13065 * Based on ALC880 version - had to change it to override
13066 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
13067 static int alc861vd_parse_auto_config(struct hda_codec *codec)
13069 struct alc_spec *spec = codec->spec;
13071 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
13073 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13077 if (!spec->autocfg.line_outs)
13078 return 0; /* can't find valid BIOS pin config */
13080 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
13083 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
13086 err = alc861vd_auto_create_extra_out(spec,
13087 spec->autocfg.speaker_pins[0],
13091 err = alc861vd_auto_create_extra_out(spec,
13092 spec->autocfg.hp_pins[0],
13096 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
13100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13102 if (spec->autocfg.dig_out_pin)
13103 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
13105 if (spec->kctl_alloc)
13106 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
13108 spec->init_verbs[spec->num_init_verbs++]
13109 = alc861vd_volume_init_verbs;
13111 spec->num_mux_defs = 1;
13112 spec->input_mux = &spec->private_imux;
13114 err = alc_auto_add_mic_boost(codec);
13121 /* additional initialization for auto-configuration model */
13122 static void alc861vd_auto_init(struct hda_codec *codec)
13124 struct alc_spec *spec = codec->spec;
13125 alc861vd_auto_init_multi_out(codec);
13126 alc861vd_auto_init_hp_out(codec);
13127 alc861vd_auto_init_analog_input(codec);
13128 if (spec->unsol_event)
13129 alc_sku_automute(codec);
13132 static int patch_alc861vd(struct hda_codec *codec)
13134 struct alc_spec *spec;
13135 int err, board_config;
13137 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13141 codec->spec = spec;
13143 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
13147 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
13148 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
13149 "ALC861VD, trying auto-probe from BIOS...\n");
13150 board_config = ALC861VD_AUTO;
13153 if (board_config == ALC861VD_AUTO) {
13154 /* automatic parse from the BIOS config */
13155 err = alc861vd_parse_auto_config(codec);
13161 "hda_codec: Cannot set up configuration "
13162 "from BIOS. Using base mode...\n");
13163 board_config = ALC861VD_3ST;
13167 if (board_config != ALC861VD_AUTO)
13168 setup_preset(spec, &alc861vd_presets[board_config]);
13170 spec->stream_name_analog = "ALC861VD Analog";
13171 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
13172 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
13174 spec->stream_name_digital = "ALC861VD Digital";
13175 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
13176 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
13178 spec->adc_nids = alc861vd_adc_nids;
13179 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
13180 spec->capsrc_nids = alc861vd_capsrc_nids;
13182 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
13183 spec->num_mixers++;
13185 spec->vmaster_nid = 0x02;
13187 codec->patch_ops = alc_patch_ops;
13189 if (board_config == ALC861VD_AUTO)
13190 spec->init_hook = alc861vd_auto_init;
13191 #ifdef CONFIG_SND_HDA_POWER_SAVE
13192 if (!spec->loopback.amplist)
13193 spec->loopback.amplist = alc861vd_loopbacks;
13202 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
13203 * configuration. Each pin widget can choose any input DACs and a mixer.
13204 * Each ADC is connected from a mixer of all inputs. This makes possible
13205 * 6-channel independent captures.
13207 * In addition, an independent DAC for the multi-playback (not used in this
13210 #define ALC662_DIGOUT_NID 0x06
13211 #define ALC662_DIGIN_NID 0x0a
13213 static hda_nid_t alc662_dac_nids[4] = {
13214 /* front, rear, clfe, rear_surr */
13218 static hda_nid_t alc662_adc_nids[1] = {
13223 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
13226 /* FIXME: should be a matrix-type input source selection */
13227 static struct hda_input_mux alc662_capture_source = {
13231 { "Front Mic", 0x1 },
13237 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
13245 static struct hda_input_mux alc662_eeepc_capture_source = {
13253 #define alc662_mux_enum_info alc_mux_enum_info
13254 #define alc662_mux_enum_get alc_mux_enum_get
13255 #define alc662_mux_enum_put alc882_mux_enum_put
13260 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
13267 static struct hda_verb alc662_3ST_ch2_init[] = {
13268 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
13269 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13270 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
13271 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
13278 static struct hda_verb alc662_3ST_ch6_init[] = {
13279 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13280 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13281 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
13282 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13283 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
13284 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
13288 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
13289 { 2, alc662_3ST_ch2_init },
13290 { 6, alc662_3ST_ch6_init },
13296 static struct hda_verb alc662_sixstack_ch6_init[] = {
13297 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13298 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13299 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13306 static struct hda_verb alc662_sixstack_ch8_init[] = {
13307 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13308 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13309 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13313 static struct hda_channel_mode alc662_5stack_modes[2] = {
13314 { 2, alc662_sixstack_ch6_init },
13315 { 6, alc662_sixstack_ch8_init },
13318 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13319 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13322 static struct snd_kcontrol_new alc662_base_mixer[] = {
13323 /* output mixer control */
13324 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13325 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13326 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13328 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13329 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13331 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13334 /*Input mixer control */
13335 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
13336 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
13337 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
13338 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
13339 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
13340 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
13341 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
13342 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
13346 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
13347 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13348 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13349 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13350 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13351 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13352 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13353 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13354 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13356 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13357 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13358 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13359 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13363 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
13364 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
13366 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
13368 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13369 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13370 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
13371 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
13372 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13379 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13380 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13381 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13382 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13386 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
13387 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13388 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
13389 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13390 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
13391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13392 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13393 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13399 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
13400 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13405 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
13406 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13407 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13409 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
13410 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13411 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13415 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
13416 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13417 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13418 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13419 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
13420 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
13421 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
13422 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
13423 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
13424 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13425 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
13426 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13427 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13428 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13429 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13433 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
13435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13436 .name = "Channel Mode",
13437 .info = alc_ch_mode_info,
13438 .get = alc_ch_mode_get,
13439 .put = alc_ch_mode_put,
13444 static struct hda_verb alc662_init_verbs[] = {
13445 /* ADC: mute amp left and right */
13446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13447 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13448 /* Front mixer: unmute input/output amp left and right (volume = 0) */
13450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13458 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13460 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13461 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13463 /* Front Pin: output 0 (0x0c) */
13464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13465 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13467 /* Rear Pin: output 1 (0x0d) */
13468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13469 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13471 /* CLFE Pin: output 2 (0x0e) */
13472 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13473 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13475 /* Mic (rear) pin: input vref at 80% */
13476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13477 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13478 /* Front Mic pin: input vref at 80% */
13479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13481 /* Line In pin: input */
13482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13484 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13486 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13487 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13488 /* CD pin widget for input */
13489 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13491 /* FIXME: use matrix-type input source selection */
13492 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13496 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13501 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13502 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13506 static struct hda_verb alc662_sue_init_verbs[] = {
13507 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
13508 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
13512 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
13513 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13514 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13518 /* Set Unsolicited Event*/
13519 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
13520 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13521 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13526 * generic initialization of ADC, input mixers and output mixers
13528 static struct hda_verb alc662_auto_init_verbs[] = {
13530 * Unmute ADC and set the default input to mic-in
13532 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13535 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
13537 * Note: PASD motherboards uses the Line In 2 as the input for front
13538 * panel mic (mic 2)
13540 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13545 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13548 * Set up output mixers (0x0c - 0x0f)
13550 /* set vol=0 to output mixers */
13551 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13552 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13553 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13555 /* set up input amps for analog loopback */
13556 /* Amp Indices: DAC = 0, mixer = 1 */
13557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13562 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13565 /* FIXME: use matrix-type input source selection */
13566 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
13568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13569 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13573 /* capture mixer elements */
13574 static struct snd_kcontrol_new alc662_capture_mixer[] = {
13575 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13576 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13578 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13579 /* The multiple "Capture Source" controls confuse alsamixer
13580 * So call somewhat different..
13582 /* .name = "Capture Source", */
13583 .name = "Input Source",
13585 .info = alc662_mux_enum_info,
13586 .get = alc662_mux_enum_get,
13587 .put = alc662_mux_enum_put,
13592 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
13594 unsigned int present;
13595 unsigned char bits;
13597 present = snd_hda_codec_read(codec, 0x14, 0,
13598 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13599 bits = present ? HDA_AMP_MUTE : 0;
13600 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13601 HDA_AMP_MUTE, bits);
13604 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
13606 unsigned int present;
13607 unsigned char bits;
13609 present = snd_hda_codec_read(codec, 0x1b, 0,
13610 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13611 bits = present ? HDA_AMP_MUTE : 0;
13612 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13613 HDA_AMP_MUTE, bits);
13614 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
13615 HDA_AMP_MUTE, bits);
13618 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
13621 if ((res >> 26) == ALC880_HP_EVENT)
13622 alc662_lenovo_101e_all_automute(codec);
13623 if ((res >> 26) == ALC880_FRONT_EVENT)
13624 alc662_lenovo_101e_ispeaker_automute(codec);
13627 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
13629 unsigned int present;
13631 present = snd_hda_codec_read(codec, 0x18, 0,
13632 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13633 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13634 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13635 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13636 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13637 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13638 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13639 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13640 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13643 /* unsolicited event for HP jack sensing */
13644 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
13647 if ((res >> 26) == ALC880_HP_EVENT)
13648 alc262_hippo1_automute( codec );
13650 if ((res >> 26) == ALC880_MIC_EVENT)
13651 alc662_eeepc_mic_automute(codec);
13654 static void alc662_eeepc_inithook(struct hda_codec *codec)
13656 alc262_hippo1_automute( codec );
13657 alc662_eeepc_mic_automute(codec);
13660 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
13663 unsigned int present;
13665 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
13666 present = snd_hda_codec_read(codec, 0x14, 0,
13667 AC_VERB_GET_PIN_SENSE, 0);
13668 present = (present & 0x80000000) != 0;
13670 /* mute internal speaker */
13671 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13672 HDA_AMP_MUTE, HDA_AMP_MUTE);
13674 /* unmute internal speaker if necessary */
13675 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13676 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
13677 HDA_AMP_MUTE, mute);
13681 /* unsolicited event for HP jack sensing */
13682 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
13685 if ((res >> 26) == ALC880_HP_EVENT)
13686 alc662_eeepc_ep20_automute(codec);
13689 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
13691 alc662_eeepc_ep20_automute(codec);
13694 #ifdef CONFIG_SND_HDA_POWER_SAVE
13695 #define alc662_loopbacks alc880_loopbacks
13699 /* pcm configuration: identiacal with ALC880 */
13700 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
13701 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
13702 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
13703 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
13706 * configuration and preset
13708 static const char *alc662_models[ALC662_MODEL_LAST] = {
13709 [ALC662_3ST_2ch_DIG] = "3stack-dig",
13710 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
13711 [ALC662_3ST_6ch] = "3stack-6ch",
13712 [ALC662_5ST_DIG] = "6stack-dig",
13713 [ALC662_LENOVO_101E] = "lenovo-101e",
13714 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
13715 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
13716 [ALC662_AUTO] = "auto",
13719 static struct snd_pci_quirk alc662_cfg_tbl[] = {
13720 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
13721 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
13722 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
13723 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
13727 static struct alc_config_preset alc662_presets[] = {
13728 [ALC662_3ST_2ch_DIG] = {
13729 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
13730 .init_verbs = { alc662_init_verbs },
13731 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13732 .dac_nids = alc662_dac_nids,
13733 .dig_out_nid = ALC662_DIGOUT_NID,
13734 .dig_in_nid = ALC662_DIGIN_NID,
13735 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13736 .channel_mode = alc662_3ST_2ch_modes,
13737 .input_mux = &alc662_capture_source,
13739 [ALC662_3ST_6ch_DIG] = {
13740 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13741 alc662_capture_mixer },
13742 .init_verbs = { alc662_init_verbs },
13743 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13744 .dac_nids = alc662_dac_nids,
13745 .dig_out_nid = ALC662_DIGOUT_NID,
13746 .dig_in_nid = ALC662_DIGIN_NID,
13747 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13748 .channel_mode = alc662_3ST_6ch_modes,
13750 .input_mux = &alc662_capture_source,
13752 [ALC662_3ST_6ch] = {
13753 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
13754 alc662_capture_mixer },
13755 .init_verbs = { alc662_init_verbs },
13756 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13757 .dac_nids = alc662_dac_nids,
13758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13759 .channel_mode = alc662_3ST_6ch_modes,
13761 .input_mux = &alc662_capture_source,
13763 [ALC662_5ST_DIG] = {
13764 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
13765 alc662_capture_mixer },
13766 .init_verbs = { alc662_init_verbs },
13767 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13768 .dac_nids = alc662_dac_nids,
13769 .dig_out_nid = ALC662_DIGOUT_NID,
13770 .dig_in_nid = ALC662_DIGIN_NID,
13771 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
13772 .channel_mode = alc662_5stack_modes,
13773 .input_mux = &alc662_capture_source,
13775 [ALC662_LENOVO_101E] = {
13776 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
13777 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
13778 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13779 .dac_nids = alc662_dac_nids,
13780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13781 .channel_mode = alc662_3ST_2ch_modes,
13782 .input_mux = &alc662_lenovo_101e_capture_source,
13783 .unsol_event = alc662_lenovo_101e_unsol_event,
13784 .init_hook = alc662_lenovo_101e_all_automute,
13786 [ALC662_ASUS_EEEPC_P701] = {
13787 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
13788 .init_verbs = { alc662_init_verbs,
13789 alc662_eeepc_sue_init_verbs },
13790 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13791 .dac_nids = alc662_dac_nids,
13792 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
13793 .channel_mode = alc662_3ST_2ch_modes,
13794 .input_mux = &alc662_eeepc_capture_source,
13795 .unsol_event = alc662_eeepc_unsol_event,
13796 .init_hook = alc662_eeepc_inithook,
13798 [ALC662_ASUS_EEEPC_EP20] = {
13799 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
13800 alc662_chmode_mixer },
13801 .init_verbs = { alc662_init_verbs,
13802 alc662_eeepc_ep20_sue_init_verbs },
13803 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
13804 .dac_nids = alc662_dac_nids,
13805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
13806 .channel_mode = alc662_3ST_6ch_modes,
13807 .input_mux = &alc662_lenovo_101e_capture_source,
13808 .unsol_event = alc662_eeepc_ep20_unsol_event,
13809 .init_hook = alc662_eeepc_ep20_inithook,
13816 * BIOS auto configuration
13819 /* add playback controls from the parsed DAC table */
13820 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
13821 const struct auto_pin_cfg *cfg)
13824 static const char *chname[4] = {
13825 "Front", "Surround", NULL /*CLFE*/, "Side"
13830 for (i = 0; i < cfg->line_outs; i++) {
13831 if (!spec->multiout.dac_nids[i])
13833 nid = alc880_idx_to_dac(i);
13836 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13837 "Center Playback Volume",
13838 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13842 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13843 "LFE Playback Volume",
13844 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13848 err = add_control(spec, ALC_CTL_BIND_MUTE,
13849 "Center Playback Switch",
13850 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
13854 err = add_control(spec, ALC_CTL_BIND_MUTE,
13855 "LFE Playback Switch",
13856 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
13861 sprintf(name, "%s Playback Volume", chname[i]);
13862 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13863 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13867 sprintf(name, "%s Playback Switch", chname[i]);
13868 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13869 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
13878 /* add playback controls for speaker and HP outputs */
13879 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
13889 if (alc880_is_fixed_pin(pin)) {
13890 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13891 /* printk("DAC nid=%x\n",nid); */
13892 /* specify the DAC as the extra output */
13893 if (!spec->multiout.hp_nid)
13894 spec->multiout.hp_nid = nid;
13896 spec->multiout.extra_out_nid[0] = nid;
13897 /* control HP volume/switch on the output mixer amp */
13898 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
13899 sprintf(name, "%s Playback Volume", pfx);
13900 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
13901 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13904 sprintf(name, "%s Playback Switch", pfx);
13905 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13906 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
13909 } else if (alc880_is_multi_pin(pin)) {
13910 /* set manual connection */
13911 /* we have only a switch on HP-out PIN */
13912 sprintf(name, "%s Playback Switch", pfx);
13913 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
13914 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
13921 /* create playback/capture controls for input pins */
13922 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
13923 const struct auto_pin_cfg *cfg)
13925 struct hda_input_mux *imux = &spec->private_imux;
13928 for (i = 0; i < AUTO_PIN_LAST; i++) {
13929 if (alc880_is_input_pin(cfg->input_pins[i])) {
13930 idx = alc880_input_pin_idx(cfg->input_pins[i]);
13931 err = new_analog_input(spec, cfg->input_pins[i],
13932 auto_pin_cfg_labels[i],
13936 imux->items[imux->num_items].label =
13937 auto_pin_cfg_labels[i];
13938 imux->items[imux->num_items].index =
13939 alc880_input_pin_idx(cfg->input_pins[i]);
13946 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
13947 hda_nid_t nid, int pin_type,
13950 alc_set_pin_output(codec, nid, pin_type);
13951 /* need the manual connection? */
13952 if (alc880_is_multi_pin(nid)) {
13953 struct alc_spec *spec = codec->spec;
13954 int idx = alc880_multi_pin_idx(nid);
13955 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
13956 AC_VERB_SET_CONNECT_SEL,
13957 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
13961 static void alc662_auto_init_multi_out(struct hda_codec *codec)
13963 struct alc_spec *spec = codec->spec;
13966 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13967 for (i = 0; i <= HDA_SIDE; i++) {
13968 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13969 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13971 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
13976 static void alc662_auto_init_hp_out(struct hda_codec *codec)
13978 struct alc_spec *spec = codec->spec;
13981 pin = spec->autocfg.hp_pins[0];
13982 if (pin) /* connect to front */
13984 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
13985 pin = spec->autocfg.speaker_pins[0];
13987 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13990 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
13991 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
13993 static void alc662_auto_init_analog_input(struct hda_codec *codec)
13995 struct alc_spec *spec = codec->spec;
13998 for (i = 0; i < AUTO_PIN_LAST; i++) {
13999 hda_nid_t nid = spec->autocfg.input_pins[i];
14000 if (alc662_is_input_pin(nid)) {
14001 snd_hda_codec_write(codec, nid, 0,
14002 AC_VERB_SET_PIN_WIDGET_CONTROL,
14003 (i <= AUTO_PIN_FRONT_MIC ?
14004 PIN_VREF80 : PIN_IN));
14005 if (nid != ALC662_PIN_CD_NID)
14006 snd_hda_codec_write(codec, nid, 0,
14007 AC_VERB_SET_AMP_GAIN_MUTE,
14013 static int alc662_parse_auto_config(struct hda_codec *codec)
14015 struct alc_spec *spec = codec->spec;
14017 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
14019 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14023 if (!spec->autocfg.line_outs)
14024 return 0; /* can't find valid BIOS pin config */
14026 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14029 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
14032 err = alc662_auto_create_extra_out(spec,
14033 spec->autocfg.speaker_pins[0],
14037 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
14041 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
14045 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14047 if (spec->autocfg.dig_out_pin)
14048 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
14050 if (spec->kctl_alloc)
14051 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
14053 spec->num_mux_defs = 1;
14054 spec->input_mux = &spec->private_imux;
14056 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
14057 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
14058 spec->num_mixers++;
14062 /* additional initialization for auto-configuration model */
14063 static void alc662_auto_init(struct hda_codec *codec)
14065 struct alc_spec *spec = codec->spec;
14066 alc662_auto_init_multi_out(codec);
14067 alc662_auto_init_hp_out(codec);
14068 alc662_auto_init_analog_input(codec);
14069 if (spec->unsol_event)
14070 alc_sku_automute(codec);
14073 static int patch_alc662(struct hda_codec *codec)
14075 struct alc_spec *spec;
14076 int err, board_config;
14078 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14082 codec->spec = spec;
14084 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
14087 if (board_config < 0) {
14088 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
14089 "trying auto-probe from BIOS...\n");
14090 board_config = ALC662_AUTO;
14093 if (board_config == ALC662_AUTO) {
14094 /* automatic parse from the BIOS config */
14095 err = alc662_parse_auto_config(codec);
14101 "hda_codec: Cannot set up configuration "
14102 "from BIOS. Using base mode...\n");
14103 board_config = ALC662_3ST_2ch_DIG;
14107 if (board_config != ALC662_AUTO)
14108 setup_preset(spec, &alc662_presets[board_config]);
14110 spec->stream_name_analog = "ALC662 Analog";
14111 spec->stream_analog_playback = &alc662_pcm_analog_playback;
14112 spec->stream_analog_capture = &alc662_pcm_analog_capture;
14114 spec->stream_name_digital = "ALC662 Digital";
14115 spec->stream_digital_playback = &alc662_pcm_digital_playback;
14116 spec->stream_digital_capture = &alc662_pcm_digital_capture;
14118 spec->adc_nids = alc662_adc_nids;
14119 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
14120 spec->capsrc_nids = alc662_capsrc_nids;
14122 spec->vmaster_nid = 0x02;
14124 codec->patch_ops = alc_patch_ops;
14125 if (board_config == ALC662_AUTO)
14126 spec->init_hook = alc662_auto_init;
14127 #ifdef CONFIG_SND_HDA_POWER_SAVE
14128 if (!spec->loopback.amplist)
14129 spec->loopback.amplist = alc662_loopbacks;
14138 struct hda_codec_preset snd_hda_preset_realtek[] = {
14139 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
14140 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
14141 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
14142 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
14143 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
14144 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
14145 .patch = patch_alc861 },
14146 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
14147 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
14148 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
14149 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
14150 .patch = patch_alc883 },
14151 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
14152 .patch = patch_alc662 },
14153 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
14154 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
14155 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
14156 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
14157 .patch = patch_alc882 }, /* should be patch_alc883() in future */
14158 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
14159 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
14160 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
14161 {} /* terminator */