2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
64 #ifdef CONFIG_SND_DEBUG
68 ALC880_MODEL_LAST
/* last tag */
82 #ifdef CONFIG_SND_DEBUG
86 ALC260_MODEL_LAST
/* last tag */
96 ALC262_HP_BPC_D7000_WL
,
97 ALC262_HP_BPC_D7000_WF
,
110 ALC262_MODEL_LAST
/* last tag */
120 ALC268_ACER_ASPIRE_ONE
,
123 #ifdef CONFIG_SND_DEBUG
127 ALC268_MODEL_LAST
/* last tag */
134 ALC269_ASUS_EEEPC_P703
,
135 ALC269_ASUS_EEEPC_P901
,
139 ALC269_MODEL_LAST
/* last tag */
156 /* ALC861-VD models */
178 ALC662_ASUS_EEEPC_P701
,
179 ALC662_ASUS_EEEPC_EP20
,
218 ALC883_TARGA_2ch_DIG
,
221 ALC888_ACER_ASPIRE_4930G
,
225 ALC883_LENOVO_101E_2ch
,
226 ALC883_LENOVO_NB0763
,
227 ALC888_LENOVO_MS7195_DIG
,
234 ALC883_FUJITSU_PI2515
,
235 ALC888_FUJITSU_XA3530
,
236 ALC883_3ST_6ch_INTEL
,
244 /* styles of capture selection */
246 CAPT_MUX
= 0, /* only mux based */
247 CAPT_MIX
, /* only mixer based */
248 CAPT_1MUX_MIX
, /* first mux and other mixers */
252 #define GPIO_MASK 0x03
255 /* codec parameterization */
256 struct snd_kcontrol_new
*mixers
[5]; /* mixer arrays */
257 unsigned int num_mixers
;
258 struct snd_kcontrol_new
*cap_mixer
; /* capture mixer */
259 unsigned int beep_amp
; /* beep amp value, set via set_beep_amp() */
261 const struct hda_verb
*init_verbs
[5]; /* initialization verbs
265 unsigned int num_init_verbs
;
267 char *stream_name_analog
; /* analog PCM stream */
268 struct hda_pcm_stream
*stream_analog_playback
;
269 struct hda_pcm_stream
*stream_analog_capture
;
270 struct hda_pcm_stream
*stream_analog_alt_playback
;
271 struct hda_pcm_stream
*stream_analog_alt_capture
;
273 char *stream_name_digital
; /* digital PCM stream */
274 struct hda_pcm_stream
*stream_digital_playback
;
275 struct hda_pcm_stream
*stream_digital_capture
;
278 struct hda_multi_out multiout
; /* playback set-up
279 * max_channels, dacs must be set
280 * dig_out_nid and hp_nid are optional
282 hda_nid_t alt_dac_nid
;
283 hda_nid_t slave_dig_outs
[3]; /* optional - for auto-parsing */
287 unsigned int num_adc_nids
;
289 hda_nid_t
*capsrc_nids
;
290 hda_nid_t dig_in_nid
; /* digital-in NID; optional */
291 int capture_style
; /* capture style (CAPT_*) */
294 unsigned int num_mux_defs
;
295 const struct hda_input_mux
*input_mux
;
296 unsigned int cur_mux
[3];
299 const struct hda_channel_mode
*channel_mode
;
300 int num_channel_mode
;
303 /* PCM information */
304 struct hda_pcm pcm_rec
[3]; /* used in alc_build_pcms() */
306 /* dynamic controls, init_verbs and input_mux */
307 struct auto_pin_cfg autocfg
;
308 struct snd_array kctls
;
309 struct hda_input_mux private_imux
[3];
310 hda_nid_t private_dac_nids
[AUTO_CFG_MAX_OUTS
];
313 void (*init_hook
)(struct hda_codec
*codec
);
314 void (*unsol_event
)(struct hda_codec
*codec
, unsigned int res
);
316 /* for pin sensing */
317 unsigned int sense_updated
: 1;
318 unsigned int jack_present
: 1;
319 unsigned int master_sw
: 1;
322 unsigned int no_analog
:1; /* digital I/O only */
324 /* for virtual master */
325 hda_nid_t vmaster_nid
;
326 #ifdef CONFIG_SND_HDA_POWER_SAVE
327 struct hda_loopback_check loopback
;
332 unsigned int pll_coef_idx
, pll_coef_bit
;
336 * configuration template - to be copied to the spec instance
338 struct alc_config_preset
{
339 struct snd_kcontrol_new
*mixers
[5]; /* should be identical size
342 struct snd_kcontrol_new
*cap_mixer
; /* capture mixer */
343 const struct hda_verb
*init_verbs
[5];
344 unsigned int num_dacs
;
346 hda_nid_t dig_out_nid
; /* optional */
347 hda_nid_t hp_nid
; /* optional */
348 hda_nid_t
*slave_dig_outs
;
349 unsigned int num_adc_nids
;
351 hda_nid_t
*capsrc_nids
;
352 hda_nid_t dig_in_nid
;
353 unsigned int num_channel_mode
;
354 const struct hda_channel_mode
*channel_mode
;
356 unsigned int num_mux_defs
;
357 const struct hda_input_mux
*input_mux
;
358 void (*unsol_event
)(struct hda_codec
*, unsigned int);
359 void (*init_hook
)(struct hda_codec
*);
360 #ifdef CONFIG_SND_HDA_POWER_SAVE
361 struct hda_amp_list
*loopbacks
;
369 static int alc_mux_enum_info(struct snd_kcontrol
*kcontrol
,
370 struct snd_ctl_elem_info
*uinfo
)
372 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
373 struct alc_spec
*spec
= codec
->spec
;
374 unsigned int mux_idx
= snd_ctl_get_ioffidx(kcontrol
, &uinfo
->id
);
375 if (mux_idx
>= spec
->num_mux_defs
)
377 return snd_hda_input_mux_info(&spec
->input_mux
[mux_idx
], uinfo
);
380 static int alc_mux_enum_get(struct snd_kcontrol
*kcontrol
,
381 struct snd_ctl_elem_value
*ucontrol
)
383 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
384 struct alc_spec
*spec
= codec
->spec
;
385 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
387 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
391 static int alc_mux_enum_put(struct snd_kcontrol
*kcontrol
,
392 struct snd_ctl_elem_value
*ucontrol
)
394 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
395 struct alc_spec
*spec
= codec
->spec
;
396 const struct hda_input_mux
*imux
;
397 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
398 unsigned int mux_idx
;
399 hda_nid_t nid
= spec
->capsrc_nids
?
400 spec
->capsrc_nids
[adc_idx
] : spec
->adc_nids
[adc_idx
];
402 mux_idx
= adc_idx
>= spec
->num_mux_defs
? 0 : adc_idx
;
403 imux
= &spec
->input_mux
[mux_idx
];
405 if (spec
->capture_style
&&
406 !(spec
->capture_style
== CAPT_1MUX_MIX
&& !adc_idx
)) {
407 /* Matrix-mixer style (e.g. ALC882) */
408 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
411 idx
= ucontrol
->value
.enumerated
.item
[0];
412 if (idx
>= imux
->num_items
)
413 idx
= imux
->num_items
- 1;
416 for (i
= 0; i
< imux
->num_items
; i
++) {
417 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
418 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
419 imux
->items
[i
].index
,
425 /* MUX style (e.g. ALC880) */
426 return snd_hda_input_mux_put(codec
, imux
, ucontrol
, nid
,
427 &spec
->cur_mux
[adc_idx
]);
432 * channel mode setting
434 static int alc_ch_mode_info(struct snd_kcontrol
*kcontrol
,
435 struct snd_ctl_elem_info
*uinfo
)
437 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
438 struct alc_spec
*spec
= codec
->spec
;
439 return snd_hda_ch_mode_info(codec
, uinfo
, spec
->channel_mode
,
440 spec
->num_channel_mode
);
443 static int alc_ch_mode_get(struct snd_kcontrol
*kcontrol
,
444 struct snd_ctl_elem_value
*ucontrol
)
446 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
447 struct alc_spec
*spec
= codec
->spec
;
448 return snd_hda_ch_mode_get(codec
, ucontrol
, spec
->channel_mode
,
449 spec
->num_channel_mode
,
450 spec
->multiout
.max_channels
);
453 static int alc_ch_mode_put(struct snd_kcontrol
*kcontrol
,
454 struct snd_ctl_elem_value
*ucontrol
)
456 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
457 struct alc_spec
*spec
= codec
->spec
;
458 int err
= snd_hda_ch_mode_put(codec
, ucontrol
, spec
->channel_mode
,
459 spec
->num_channel_mode
,
460 &spec
->multiout
.max_channels
);
461 if (err
>= 0 && spec
->need_dac_fix
)
462 spec
->multiout
.num_dacs
= spec
->multiout
.max_channels
/ 2;
467 * Control the mode of pin widget settings via the mixer. "pc" is used
468 * instead of "%" to avoid consequences of accidently treating the % as
469 * being part of a format specifier. Maximum allowed length of a value is
470 * 63 characters plus NULL terminator.
472 * Note: some retasking pin complexes seem to ignore requests for input
473 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
474 * are requested. Therefore order this list so that this behaviour will not
475 * cause problems when mixer clients move through the enum sequentially.
476 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
479 static char *alc_pin_mode_names
[] = {
480 "Mic 50pc bias", "Mic 80pc bias",
481 "Line in", "Line out", "Headphone out",
483 static unsigned char alc_pin_mode_values
[] = {
484 PIN_VREF50
, PIN_VREF80
, PIN_IN
, PIN_OUT
, PIN_HP
,
486 /* The control can present all 5 options, or it can limit the options based
487 * in the pin being assumed to be exclusively an input or an output pin. In
488 * addition, "input" pins may or may not process the mic bias option
489 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
490 * accept requests for bias as of chip versions up to March 2006) and/or
491 * wiring in the computer.
493 #define ALC_PIN_DIR_IN 0x00
494 #define ALC_PIN_DIR_OUT 0x01
495 #define ALC_PIN_DIR_INOUT 0x02
496 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
497 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
499 /* Info about the pin modes supported by the different pin direction modes.
500 * For each direction the minimum and maximum values are given.
502 static signed char alc_pin_mode_dir_info
[5][2] = {
503 { 0, 2 }, /* ALC_PIN_DIR_IN */
504 { 3, 4 }, /* ALC_PIN_DIR_OUT */
505 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
506 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
507 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
509 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
510 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
511 #define alc_pin_mode_n_items(_dir) \
512 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
514 static int alc_pin_mode_info(struct snd_kcontrol
*kcontrol
,
515 struct snd_ctl_elem_info
*uinfo
)
517 unsigned int item_num
= uinfo
->value
.enumerated
.item
;
518 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
520 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
522 uinfo
->value
.enumerated
.items
= alc_pin_mode_n_items(dir
);
524 if (item_num
<alc_pin_mode_min(dir
) || item_num
>alc_pin_mode_max(dir
))
525 item_num
= alc_pin_mode_min(dir
);
526 strcpy(uinfo
->value
.enumerated
.name
, alc_pin_mode_names
[item_num
]);
530 static int alc_pin_mode_get(struct snd_kcontrol
*kcontrol
,
531 struct snd_ctl_elem_value
*ucontrol
)
534 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
535 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
536 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
537 long *valp
= ucontrol
->value
.integer
.value
;
538 unsigned int pinctl
= snd_hda_codec_read(codec
, nid
, 0,
539 AC_VERB_GET_PIN_WIDGET_CONTROL
,
542 /* Find enumerated value for current pinctl setting */
543 i
= alc_pin_mode_min(dir
);
544 while (alc_pin_mode_values
[i
] != pinctl
&& i
<= alc_pin_mode_max(dir
))
546 *valp
= i
<= alc_pin_mode_max(dir
) ? i
: alc_pin_mode_min(dir
);
550 static int alc_pin_mode_put(struct snd_kcontrol
*kcontrol
,
551 struct snd_ctl_elem_value
*ucontrol
)
554 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
555 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
556 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
557 long val
= *ucontrol
->value
.integer
.value
;
558 unsigned int pinctl
= snd_hda_codec_read(codec
, nid
, 0,
559 AC_VERB_GET_PIN_WIDGET_CONTROL
,
562 if (val
< alc_pin_mode_min(dir
) || val
> alc_pin_mode_max(dir
))
563 val
= alc_pin_mode_min(dir
);
565 change
= pinctl
!= alc_pin_mode_values
[val
];
567 /* Set pin mode to that requested */
568 snd_hda_codec_write_cache(codec
, nid
, 0,
569 AC_VERB_SET_PIN_WIDGET_CONTROL
,
570 alc_pin_mode_values
[val
]);
572 /* Also enable the retasking pin's input/output as required
573 * for the requested pin mode. Enum values of 2 or less are
576 * Dynamically switching the input/output buffers probably
577 * reduces noise slightly (particularly on input) so we'll
578 * do it. However, having both input and output buffers
579 * enabled simultaneously doesn't seem to be problematic if
580 * this turns out to be necessary in the future.
583 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
584 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
585 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
, 0,
588 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
, 0,
589 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
590 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
597 #define ALC_PIN_MODE(xname, nid, dir) \
598 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
599 .info = alc_pin_mode_info, \
600 .get = alc_pin_mode_get, \
601 .put = alc_pin_mode_put, \
602 .private_value = nid | (dir<<16) }
604 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
605 * together using a mask with more than one bit set. This control is
606 * currently used only by the ALC260 test model. At this stage they are not
607 * needed for any "production" models.
609 #ifdef CONFIG_SND_DEBUG
610 #define alc_gpio_data_info snd_ctl_boolean_mono_info
612 static int alc_gpio_data_get(struct snd_kcontrol
*kcontrol
,
613 struct snd_ctl_elem_value
*ucontrol
)
615 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
616 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
617 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
618 long *valp
= ucontrol
->value
.integer
.value
;
619 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
620 AC_VERB_GET_GPIO_DATA
, 0x00);
622 *valp
= (val
& mask
) != 0;
625 static int alc_gpio_data_put(struct snd_kcontrol
*kcontrol
,
626 struct snd_ctl_elem_value
*ucontrol
)
629 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
630 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
631 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
632 long val
= *ucontrol
->value
.integer
.value
;
633 unsigned int gpio_data
= snd_hda_codec_read(codec
, nid
, 0,
634 AC_VERB_GET_GPIO_DATA
,
637 /* Set/unset the masked GPIO bit(s) as needed */
638 change
= (val
== 0 ? 0 : mask
) != (gpio_data
& mask
);
643 snd_hda_codec_write_cache(codec
, nid
, 0,
644 AC_VERB_SET_GPIO_DATA
, gpio_data
);
648 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
649 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
650 .info = alc_gpio_data_info, \
651 .get = alc_gpio_data_get, \
652 .put = alc_gpio_data_put, \
653 .private_value = nid | (mask<<16) }
654 #endif /* CONFIG_SND_DEBUG */
656 /* A switch control to allow the enabling of the digital IO pins on the
657 * ALC260. This is incredibly simplistic; the intention of this control is
658 * to provide something in the test model allowing digital outputs to be
659 * identified if present. If models are found which can utilise these
660 * outputs a more complete mixer control can be devised for those models if
663 #ifdef CONFIG_SND_DEBUG
664 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
666 static int alc_spdif_ctrl_get(struct snd_kcontrol
*kcontrol
,
667 struct snd_ctl_elem_value
*ucontrol
)
669 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
670 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
671 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
672 long *valp
= ucontrol
->value
.integer
.value
;
673 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
674 AC_VERB_GET_DIGI_CONVERT_1
, 0x00);
676 *valp
= (val
& mask
) != 0;
679 static int alc_spdif_ctrl_put(struct snd_kcontrol
*kcontrol
,
680 struct snd_ctl_elem_value
*ucontrol
)
683 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
684 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
685 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
686 long val
= *ucontrol
->value
.integer
.value
;
687 unsigned int ctrl_data
= snd_hda_codec_read(codec
, nid
, 0,
688 AC_VERB_GET_DIGI_CONVERT_1
,
691 /* Set/unset the masked control bit(s) as needed */
692 change
= (val
== 0 ? 0 : mask
) != (ctrl_data
& mask
);
697 snd_hda_codec_write_cache(codec
, nid
, 0, AC_VERB_SET_DIGI_CONVERT_1
,
702 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
703 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
704 .info = alc_spdif_ctrl_info, \
705 .get = alc_spdif_ctrl_get, \
706 .put = alc_spdif_ctrl_put, \
707 .private_value = nid | (mask<<16) }
708 #endif /* CONFIG_SND_DEBUG */
710 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
711 * Again, this is only used in the ALC26x test models to help identify when
712 * the EAPD line must be asserted for features to work.
714 #ifdef CONFIG_SND_DEBUG
715 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
717 static int alc_eapd_ctrl_get(struct snd_kcontrol
*kcontrol
,
718 struct snd_ctl_elem_value
*ucontrol
)
720 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
721 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
722 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
723 long *valp
= ucontrol
->value
.integer
.value
;
724 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
725 AC_VERB_GET_EAPD_BTLENABLE
, 0x00);
727 *valp
= (val
& mask
) != 0;
731 static int alc_eapd_ctrl_put(struct snd_kcontrol
*kcontrol
,
732 struct snd_ctl_elem_value
*ucontrol
)
735 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
736 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
737 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
738 long val
= *ucontrol
->value
.integer
.value
;
739 unsigned int ctrl_data
= snd_hda_codec_read(codec
, nid
, 0,
740 AC_VERB_GET_EAPD_BTLENABLE
,
743 /* Set/unset the masked control bit(s) as needed */
744 change
= (!val
? 0 : mask
) != (ctrl_data
& mask
);
749 snd_hda_codec_write_cache(codec
, nid
, 0, AC_VERB_SET_EAPD_BTLENABLE
,
755 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
756 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
757 .info = alc_eapd_ctrl_info, \
758 .get = alc_eapd_ctrl_get, \
759 .put = alc_eapd_ctrl_put, \
760 .private_value = nid | (mask<<16) }
761 #endif /* CONFIG_SND_DEBUG */
765 static void add_mixer(struct alc_spec
*spec
, struct snd_kcontrol_new
*mix
)
767 if (snd_BUG_ON(spec
->num_mixers
>= ARRAY_SIZE(spec
->mixers
)))
769 spec
->mixers
[spec
->num_mixers
++] = mix
;
772 static void add_verb(struct alc_spec
*spec
, const struct hda_verb
*verb
)
774 if (snd_BUG_ON(spec
->num_init_verbs
>= ARRAY_SIZE(spec
->init_verbs
)))
776 spec
->init_verbs
[spec
->num_init_verbs
++] = verb
;
779 #ifdef CONFIG_PROC_FS
783 static void print_realtek_coef(struct snd_info_buffer
*buffer
,
784 struct hda_codec
*codec
, hda_nid_t nid
)
790 coeff
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_PROC_COEF
, 0);
791 snd_iprintf(buffer
, " Processing Coefficient: 0x%02x\n", coeff
);
792 coeff
= snd_hda_codec_read(codec
, nid
, 0,
793 AC_VERB_GET_COEF_INDEX
, 0);
794 snd_iprintf(buffer
, " Coefficient Index: 0x%02x\n", coeff
);
797 #define print_realtek_coef NULL
801 * set up from the preset table
803 static void setup_preset(struct alc_spec
*spec
,
804 const struct alc_config_preset
*preset
)
808 for (i
= 0; i
< ARRAY_SIZE(preset
->mixers
) && preset
->mixers
[i
]; i
++)
809 add_mixer(spec
, preset
->mixers
[i
]);
810 spec
->cap_mixer
= preset
->cap_mixer
;
811 for (i
= 0; i
< ARRAY_SIZE(preset
->init_verbs
) && preset
->init_verbs
[i
];
813 add_verb(spec
, preset
->init_verbs
[i
]);
815 spec
->channel_mode
= preset
->channel_mode
;
816 spec
->num_channel_mode
= preset
->num_channel_mode
;
817 spec
->need_dac_fix
= preset
->need_dac_fix
;
819 spec
->multiout
.max_channels
= spec
->channel_mode
[0].channels
;
821 spec
->multiout
.num_dacs
= preset
->num_dacs
;
822 spec
->multiout
.dac_nids
= preset
->dac_nids
;
823 spec
->multiout
.dig_out_nid
= preset
->dig_out_nid
;
824 spec
->multiout
.slave_dig_outs
= preset
->slave_dig_outs
;
825 spec
->multiout
.hp_nid
= preset
->hp_nid
;
827 spec
->num_mux_defs
= preset
->num_mux_defs
;
828 if (!spec
->num_mux_defs
)
829 spec
->num_mux_defs
= 1;
830 spec
->input_mux
= preset
->input_mux
;
832 spec
->num_adc_nids
= preset
->num_adc_nids
;
833 spec
->adc_nids
= preset
->adc_nids
;
834 spec
->capsrc_nids
= preset
->capsrc_nids
;
835 spec
->dig_in_nid
= preset
->dig_in_nid
;
837 spec
->unsol_event
= preset
->unsol_event
;
838 spec
->init_hook
= preset
->init_hook
;
839 #ifdef CONFIG_SND_HDA_POWER_SAVE
840 spec
->loopback
.amplist
= preset
->loopbacks
;
844 /* Enable GPIO mask and set output */
845 static struct hda_verb alc_gpio1_init_verbs
[] = {
846 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
847 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
848 {0x01, AC_VERB_SET_GPIO_DATA
, 0x01},
852 static struct hda_verb alc_gpio2_init_verbs
[] = {
853 {0x01, AC_VERB_SET_GPIO_MASK
, 0x02},
854 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x02},
855 {0x01, AC_VERB_SET_GPIO_DATA
, 0x02},
859 static struct hda_verb alc_gpio3_init_verbs
[] = {
860 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
861 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
862 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
867 * Fix hardware PLL issue
868 * On some codecs, the analog PLL gating control must be off while
869 * the default value is 1.
871 static void alc_fix_pll(struct hda_codec
*codec
)
873 struct alc_spec
*spec
= codec
->spec
;
878 snd_hda_codec_write(codec
, spec
->pll_nid
, 0, AC_VERB_SET_COEF_INDEX
,
880 val
= snd_hda_codec_read(codec
, spec
->pll_nid
, 0,
881 AC_VERB_GET_PROC_COEF
, 0);
882 snd_hda_codec_write(codec
, spec
->pll_nid
, 0, AC_VERB_SET_COEF_INDEX
,
884 snd_hda_codec_write(codec
, spec
->pll_nid
, 0, AC_VERB_SET_PROC_COEF
,
885 val
& ~(1 << spec
->pll_coef_bit
));
888 static void alc_fix_pll_init(struct hda_codec
*codec
, hda_nid_t nid
,
889 unsigned int coef_idx
, unsigned int coef_bit
)
891 struct alc_spec
*spec
= codec
->spec
;
893 spec
->pll_coef_idx
= coef_idx
;
894 spec
->pll_coef_bit
= coef_bit
;
898 static void alc_sku_automute(struct hda_codec
*codec
)
900 struct alc_spec
*spec
= codec
->spec
;
901 unsigned int present
;
902 unsigned int hp_nid
= spec
->autocfg
.hp_pins
[0];
903 unsigned int sp_nid
= spec
->autocfg
.speaker_pins
[0];
905 /* need to execute and sync at first */
906 snd_hda_codec_read(codec
, hp_nid
, 0, AC_VERB_SET_PIN_SENSE
, 0);
907 present
= snd_hda_codec_read(codec
, hp_nid
, 0,
908 AC_VERB_GET_PIN_SENSE
, 0);
909 spec
->jack_present
= (present
& 0x80000000) != 0;
910 snd_hda_codec_write(codec
, sp_nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
911 spec
->jack_present
? 0 : PIN_OUT
);
914 #if 0 /* it's broken in some acses -- temporarily disabled */
915 static void alc_mic_automute(struct hda_codec
*codec
)
917 struct alc_spec
*spec
= codec
->spec
;
918 unsigned int present
;
919 unsigned int mic_nid
= spec
->autocfg
.input_pins
[AUTO_PIN_MIC
];
920 unsigned int fmic_nid
= spec
->autocfg
.input_pins
[AUTO_PIN_FRONT_MIC
];
921 unsigned int mix_nid
= spec
->capsrc_nids
[0];
922 unsigned int capsrc_idx_mic
, capsrc_idx_fmic
;
924 capsrc_idx_mic
= mic_nid
- 0x18;
925 capsrc_idx_fmic
= fmic_nid
- 0x18;
926 present
= snd_hda_codec_read(codec
, mic_nid
, 0,
927 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
928 snd_hda_codec_write(codec
, mix_nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
929 0x7000 | (capsrc_idx_mic
<< 8) | (present
? 0 : 0x80));
930 snd_hda_codec_write(codec
, mix_nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
931 0x7000 | (capsrc_idx_fmic
<< 8) | (present
? 0x80 : 0));
932 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, capsrc_idx_fmic
,
933 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
936 #define alc_mic_automute(codec) do {} while(0) /* NOP */
937 #endif /* disabled */
939 /* unsolicited event for HP jack sensing */
940 static void alc_sku_unsol_event(struct hda_codec
*codec
, unsigned int res
)
942 if (codec
->vendor_id
== 0x10ec0880)
946 if (res
== ALC880_HP_EVENT
)
947 alc_sku_automute(codec
);
949 if (res
== ALC880_MIC_EVENT
)
950 alc_mic_automute(codec
);
953 static void alc_inithook(struct hda_codec
*codec
)
955 alc_sku_automute(codec
);
956 alc_mic_automute(codec
);
959 /* additional initialization for ALC888 variants */
960 static void alc888_coef_init(struct hda_codec
*codec
)
964 snd_hda_codec_write(codec
, 0x20, 0, AC_VERB_SET_COEF_INDEX
, 0);
965 tmp
= snd_hda_codec_read(codec
, 0x20, 0, AC_VERB_GET_PROC_COEF
, 0);
966 snd_hda_codec_write(codec
, 0x20, 0, AC_VERB_SET_COEF_INDEX
, 7);
967 if ((tmp
& 0xf0) == 2)
969 snd_hda_codec_read(codec
, 0x20, 0,
970 AC_VERB_SET_PROC_COEF
, 0x830);
973 snd_hda_codec_read(codec
, 0x20, 0,
974 AC_VERB_SET_PROC_COEF
, 0x3030);
977 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
978 * 31 ~ 16 : Manufacture ID
980 * 7 ~ 0 : Assembly ID
981 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
983 static void alc_subsystem_id(struct hda_codec
*codec
,
984 unsigned int porta
, unsigned int porte
,
987 unsigned int ass
, tmp
, i
;
989 struct alc_spec
*spec
= codec
->spec
;
991 ass
= codec
->subsystem_id
& 0xffff;
992 if ((ass
!= codec
->bus
->pci
->subsystem_device
) && (ass
& 1))
996 * 31~30 : port conetcivity
999 * 19~16 : Check sum (15:1)
1004 if (codec
->vendor_id
== 0x10ec0260)
1006 ass
= snd_hda_codec_get_pincfg(codec
, nid
);
1007 if (!(ass
& 1) && !(ass
& 0x100000))
1009 if ((ass
>> 30) != 1) /* no physical connection */
1014 for (i
= 1; i
< 16; i
++) {
1018 if (((ass
>> 16) & 0xf) != tmp
)
1024 * 2 : 0 --> Desktop, 1 --> Laptop
1025 * 3~5 : External Amplifier control
1028 tmp
= (ass
& 0x38) >> 3; /* external Amp control */
1031 snd_hda_sequence_write(codec
, alc_gpio1_init_verbs
);
1034 snd_hda_sequence_write(codec
, alc_gpio2_init_verbs
);
1037 snd_hda_sequence_write(codec
, alc_gpio3_init_verbs
);
1039 case 5: /* set EAPD output high */
1040 switch (codec
->vendor_id
) {
1042 snd_hda_codec_write(codec
, 0x0f, 0,
1043 AC_VERB_SET_EAPD_BTLENABLE
, 2);
1044 snd_hda_codec_write(codec
, 0x10, 0,
1045 AC_VERB_SET_EAPD_BTLENABLE
, 2);
1057 snd_hda_codec_write(codec
, 0x14, 0,
1058 AC_VERB_SET_EAPD_BTLENABLE
, 2);
1059 snd_hda_codec_write(codec
, 0x15, 0,
1060 AC_VERB_SET_EAPD_BTLENABLE
, 2);
1063 switch (codec
->vendor_id
) {
1065 snd_hda_codec_write(codec
, 0x1a, 0,
1066 AC_VERB_SET_COEF_INDEX
, 7);
1067 tmp
= snd_hda_codec_read(codec
, 0x1a, 0,
1068 AC_VERB_GET_PROC_COEF
, 0);
1069 snd_hda_codec_write(codec
, 0x1a, 0,
1070 AC_VERB_SET_COEF_INDEX
, 7);
1071 snd_hda_codec_write(codec
, 0x1a, 0,
1072 AC_VERB_SET_PROC_COEF
,
1082 snd_hda_codec_write(codec
, 0x20, 0,
1083 AC_VERB_SET_COEF_INDEX
, 7);
1084 tmp
= snd_hda_codec_read(codec
, 0x20, 0,
1085 AC_VERB_GET_PROC_COEF
, 0);
1086 snd_hda_codec_write(codec
, 0x20, 0,
1087 AC_VERB_SET_COEF_INDEX
, 7);
1088 snd_hda_codec_write(codec
, 0x20, 0,
1089 AC_VERB_SET_PROC_COEF
,
1093 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1097 snd_hda_codec_write(codec
, 0x20, 0,
1098 AC_VERB_SET_COEF_INDEX
, 7);
1099 tmp
= snd_hda_codec_read(codec
, 0x20, 0,
1100 AC_VERB_GET_PROC_COEF
, 0);
1101 snd_hda_codec_write(codec
, 0x20, 0,
1102 AC_VERB_SET_COEF_INDEX
, 7);
1103 snd_hda_codec_write(codec
, 0x20, 0,
1104 AC_VERB_SET_PROC_COEF
,
1112 /* is laptop or Desktop and enable the function "Mute internal speaker
1113 * when the external headphone out jack is plugged"
1115 if (!(ass
& 0x8000))
1118 * 10~8 : Jack location
1119 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1121 * 15 : 1 --> enable the function "Mute internal speaker
1122 * when the external headphone out jack is plugged"
1124 if (!spec
->autocfg
.speaker_pins
[0]) {
1125 if (spec
->autocfg
.line_out_pins
[0])
1126 spec
->autocfg
.speaker_pins
[0] =
1127 spec
->autocfg
.line_out_pins
[0];
1132 if (!spec
->autocfg
.hp_pins
[0]) {
1133 tmp
= (ass
>> 11) & 0x3; /* HP to chassis */
1135 spec
->autocfg
.hp_pins
[0] = porta
;
1137 spec
->autocfg
.hp_pins
[0] = porte
;
1139 spec
->autocfg
.hp_pins
[0] = portd
;
1143 if (spec
->autocfg
.hp_pins
[0])
1144 snd_hda_codec_write(codec
, spec
->autocfg
.hp_pins
[0], 0,
1145 AC_VERB_SET_UNSOLICITED_ENABLE
,
1146 AC_USRSP_EN
| ALC880_HP_EVENT
);
1148 #if 0 /* it's broken in some acses -- temporarily disabled */
1149 if (spec
->autocfg
.input_pins
[AUTO_PIN_MIC
] &&
1150 spec
->autocfg
.input_pins
[AUTO_PIN_FRONT_MIC
])
1151 snd_hda_codec_write(codec
,
1152 spec
->autocfg
.input_pins
[AUTO_PIN_MIC
], 0,
1153 AC_VERB_SET_UNSOLICITED_ENABLE
,
1154 AC_USRSP_EN
| ALC880_MIC_EVENT
);
1155 #endif /* disabled */
1157 spec
->unsol_event
= alc_sku_unsol_event
;
1161 * Fix-up pin default configurations
1169 static void alc_fix_pincfg(struct hda_codec
*codec
,
1170 const struct snd_pci_quirk
*quirk
,
1171 const struct alc_pincfg
**pinfix
)
1173 const struct alc_pincfg
*cfg
;
1175 quirk
= snd_pci_quirk_lookup(codec
->bus
->pci
, quirk
);
1179 cfg
= pinfix
[quirk
->value
];
1180 for (; cfg
->nid
; cfg
++)
1181 snd_hda_codec_set_pincfg(codec
, cfg
->nid
, cfg
->val
);
1191 static struct hda_verb alc888_4ST_ch2_intel_init
[] = {
1192 /* Mic-in jack as mic in */
1193 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1194 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1195 /* Line-in jack as Line in */
1196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1198 /* Line-Out as Front */
1199 { 0x17, AC_VERB_SET_CONNECT_SEL
, 0x00},
1206 static struct hda_verb alc888_4ST_ch4_intel_init
[] = {
1207 /* Mic-in jack as mic in */
1208 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1209 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1210 /* Line-in jack as Surround */
1211 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1212 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1213 /* Line-Out as Front */
1214 { 0x17, AC_VERB_SET_CONNECT_SEL
, 0x00},
1221 static struct hda_verb alc888_4ST_ch6_intel_init
[] = {
1222 /* Mic-in jack as CLFE */
1223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1225 /* Line-in jack as Surround */
1226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1228 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1229 { 0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
1236 static struct hda_verb alc888_4ST_ch8_intel_init
[] = {
1237 /* Mic-in jack as CLFE */
1238 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1239 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1240 /* Line-in jack as Surround */
1241 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1242 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1243 /* Line-Out as Side */
1244 { 0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
1248 static struct hda_channel_mode alc888_4ST_8ch_intel_modes
[4] = {
1249 { 2, alc888_4ST_ch2_intel_init
},
1250 { 4, alc888_4ST_ch4_intel_init
},
1251 { 6, alc888_4ST_ch6_intel_init
},
1252 { 8, alc888_4ST_ch8_intel_init
},
1256 * ALC888 Fujitsu Siemens Amillo xa3530
1259 static struct hda_verb alc888_fujitsu_xa3530_verbs
[] = {
1260 /* Front Mic: set to PIN_IN (empty by default) */
1261 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1262 /* Connect Internal HP to Front */
1263 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1264 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1265 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
1266 /* Connect Bass HP to Front */
1267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1269 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
1270 /* Connect Line-Out side jack (SPDIF) to Side */
1271 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1272 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1273 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
1274 /* Connect Mic jack to CLFE */
1275 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1277 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02},
1278 /* Connect Line-in jack to Surround */
1279 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1281 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01},
1282 /* Connect HP out jack to Front */
1283 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1284 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1285 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
1286 /* Enable unsolicited event for HP jack and Line-out jack */
1287 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
1288 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
1292 static void alc888_fujitsu_xa3530_automute(struct hda_codec
*codec
)
1294 unsigned int present
;
1296 /* Line out presence */
1297 present
= snd_hda_codec_read(codec
, 0x17, 0,
1298 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1299 /* HP out presence */
1300 present
= present
|| snd_hda_codec_read(codec
, 0x1b, 0,
1301 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1302 bits
= present
? HDA_AMP_MUTE
: 0;
1303 /* Toggle internal speakers muting */
1304 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
1305 HDA_AMP_MUTE
, bits
);
1306 /* Toggle internal bass muting */
1307 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
1308 HDA_AMP_MUTE
, bits
);
1311 static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec
*codec
,
1314 if (res
>> 26 == ALC880_HP_EVENT
)
1315 alc888_fujitsu_xa3530_automute(codec
);
1320 * ALC888 Acer Aspire 4930G model
1323 static struct hda_verb alc888_acer_aspire_4930g_verbs
[] = {
1324 /* Front Mic: set to PIN_IN (empty by default) */
1325 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1326 /* Unselect Front Mic by default in input mixer 3 */
1327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0xb)},
1328 /* Enable unsolicited event for HP jack */
1329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
1330 /* Connect Internal HP to front */
1331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1332 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1333 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
1334 /* Connect HP out to front */
1335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1336 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1337 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
1341 static struct hda_input_mux alc888_2_capture_sources
[2] = {
1342 /* Front mic only available on one ADC */
1349 { "Front Mic", 0xb },
1362 static struct snd_kcontrol_new alc888_base_mixer
[] = {
1363 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1364 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1365 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1366 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1367 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1369 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1370 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1371 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1372 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
1373 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
1374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1376 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1377 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1378 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1379 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
1380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1384 static void alc888_acer_aspire_4930g_automute(struct hda_codec
*codec
)
1386 unsigned int present
;
1388 present
= snd_hda_codec_read(codec
, 0x15, 0,
1389 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1390 bits
= present
? HDA_AMP_MUTE
: 0;
1391 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
1392 HDA_AMP_MUTE
, bits
);
1395 static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec
*codec
,
1398 if (res
>> 26 == ALC880_HP_EVENT
)
1399 alc888_acer_aspire_4930g_automute(codec
);
1403 * ALC880 3-stack model
1405 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1406 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1407 * F-Mic = 0x1b, HP = 0x19
1410 static hda_nid_t alc880_dac_nids
[4] = {
1411 /* front, rear, clfe, rear_surr */
1412 0x02, 0x05, 0x04, 0x03
1415 static hda_nid_t alc880_adc_nids
[3] = {
1420 /* The datasheet says the node 0x07 is connected from inputs,
1421 * but it shows zero connection in the real implementation on some devices.
1422 * Note: this is a 915GAV bug, fixed on 915GLV
1424 static hda_nid_t alc880_adc_nids_alt
[2] = {
1429 #define ALC880_DIGOUT_NID 0x06
1430 #define ALC880_DIGIN_NID 0x0a
1432 static struct hda_input_mux alc880_capture_source
= {
1436 { "Front Mic", 0x3 },
1442 /* channel source setting (2/6 channel selection for 3-stack) */
1444 static struct hda_verb alc880_threestack_ch2_init
[] = {
1445 /* set line-in to input, mute it */
1446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1448 /* set mic-in to input vref 80%, mute it */
1449 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1450 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1455 static struct hda_verb alc880_threestack_ch6_init
[] = {
1456 /* set line-in to output, unmute it */
1457 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1458 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1459 /* set mic-in to output, unmute it */
1460 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1461 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1465 static struct hda_channel_mode alc880_threestack_modes
[2] = {
1466 { 2, alc880_threestack_ch2_init
},
1467 { 6, alc880_threestack_ch6_init
},
1470 static struct snd_kcontrol_new alc880_three_stack_mixer
[] = {
1471 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1472 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1473 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
1474 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT
),
1475 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1476 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1477 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1478 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1479 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1480 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1483 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1485 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT
),
1486 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT
),
1487 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT
),
1489 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1490 .name
= "Channel Mode",
1491 .info
= alc_ch_mode_info
,
1492 .get
= alc_ch_mode_get
,
1493 .put
= alc_ch_mode_put
,
1498 /* capture mixer elements */
1499 static int alc_cap_vol_info(struct snd_kcontrol
*kcontrol
,
1500 struct snd_ctl_elem_info
*uinfo
)
1502 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1503 struct alc_spec
*spec
= codec
->spec
;
1506 mutex_lock(&codec
->control_mutex
);
1507 kcontrol
->private_value
= HDA_COMPOSE_AMP_VAL(spec
->adc_nids
[0], 3, 0,
1509 err
= snd_hda_mixer_amp_volume_info(kcontrol
, uinfo
);
1510 mutex_unlock(&codec
->control_mutex
);
1514 static int alc_cap_vol_tlv(struct snd_kcontrol
*kcontrol
, int op_flag
,
1515 unsigned int size
, unsigned int __user
*tlv
)
1517 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1518 struct alc_spec
*spec
= codec
->spec
;
1521 mutex_lock(&codec
->control_mutex
);
1522 kcontrol
->private_value
= HDA_COMPOSE_AMP_VAL(spec
->adc_nids
[0], 3, 0,
1524 err
= snd_hda_mixer_amp_tlv(kcontrol
, op_flag
, size
, tlv
);
1525 mutex_unlock(&codec
->control_mutex
);
1529 typedef int (*getput_call_t
)(struct snd_kcontrol
*kcontrol
,
1530 struct snd_ctl_elem_value
*ucontrol
);
1532 static int alc_cap_getput_caller(struct snd_kcontrol
*kcontrol
,
1533 struct snd_ctl_elem_value
*ucontrol
,
1536 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
1537 struct alc_spec
*spec
= codec
->spec
;
1538 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
1541 mutex_lock(&codec
->control_mutex
);
1542 kcontrol
->private_value
= HDA_COMPOSE_AMP_VAL(spec
->adc_nids
[adc_idx
],
1544 err
= func(kcontrol
, ucontrol
);
1545 mutex_unlock(&codec
->control_mutex
);
1549 static int alc_cap_vol_get(struct snd_kcontrol
*kcontrol
,
1550 struct snd_ctl_elem_value
*ucontrol
)
1552 return alc_cap_getput_caller(kcontrol
, ucontrol
,
1553 snd_hda_mixer_amp_volume_get
);
1556 static int alc_cap_vol_put(struct snd_kcontrol
*kcontrol
,
1557 struct snd_ctl_elem_value
*ucontrol
)
1559 return alc_cap_getput_caller(kcontrol
, ucontrol
,
1560 snd_hda_mixer_amp_volume_put
);
1563 /* capture mixer elements */
1564 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1566 static int alc_cap_sw_get(struct snd_kcontrol
*kcontrol
,
1567 struct snd_ctl_elem_value
*ucontrol
)
1569 return alc_cap_getput_caller(kcontrol
, ucontrol
,
1570 snd_hda_mixer_amp_switch_get
);
1573 static int alc_cap_sw_put(struct snd_kcontrol
*kcontrol
,
1574 struct snd_ctl_elem_value
*ucontrol
)
1576 return alc_cap_getput_caller(kcontrol
, ucontrol
,
1577 snd_hda_mixer_amp_switch_put
);
1580 #define DEFINE_CAPMIX(num) \
1581 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1584 .name = "Capture Switch", \
1585 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1587 .info = alc_cap_sw_info, \
1588 .get = alc_cap_sw_get, \
1589 .put = alc_cap_sw_put, \
1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1593 .name = "Capture Volume", \
1594 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1595 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1596 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1598 .info = alc_cap_vol_info, \
1599 .get = alc_cap_vol_get, \
1600 .put = alc_cap_vol_put, \
1601 .tlv = { .c = alc_cap_vol_tlv }, \
1604 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1605 /* .name = "Capture Source", */ \
1606 .name = "Input Source", \
1608 .info = alc_mux_enum_info, \
1609 .get = alc_mux_enum_get, \
1610 .put = alc_mux_enum_put, \
1615 /* up to three ADCs */
1622 * ALC880 5-stack model
1624 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1626 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1627 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1630 /* additional mixers to alc880_three_stack_mixer */
1631 static struct snd_kcontrol_new alc880_five_stack_mixer
[] = {
1632 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1633 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT
),
1637 /* channel source setting (6/8 channel selection for 5-stack) */
1639 static struct hda_verb alc880_fivestack_ch6_init
[] = {
1640 /* set line-in to input, mute it */
1641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1647 static struct hda_verb alc880_fivestack_ch8_init
[] = {
1648 /* set line-in to output, unmute it */
1649 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1650 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1654 static struct hda_channel_mode alc880_fivestack_modes
[2] = {
1655 { 6, alc880_fivestack_ch6_init
},
1656 { 8, alc880_fivestack_ch8_init
},
1661 * ALC880 6-stack model
1663 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1664 * Side = 0x05 (0x0f)
1665 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1666 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1669 static hda_nid_t alc880_6st_dac_nids
[4] = {
1670 /* front, rear, clfe, rear_surr */
1671 0x02, 0x03, 0x04, 0x05
1674 static struct hda_input_mux alc880_6stack_capture_source
= {
1678 { "Front Mic", 0x1 },
1684 /* fixed 8-channels */
1685 static struct hda_channel_mode alc880_sixstack_modes
[1] = {
1689 static struct snd_kcontrol_new alc880_six_stack_mixer
[] = {
1690 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1691 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1692 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1693 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1694 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1695 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1696 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1697 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1698 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
1699 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
1700 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1701 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1702 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1703 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1704 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1705 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1706 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1707 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1709 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1710 .name
= "Channel Mode",
1711 .info
= alc_ch_mode_info
,
1712 .get
= alc_ch_mode_get
,
1713 .put
= alc_ch_mode_put
,
1722 * W810 has rear IO for:
1725 * Center/LFE (DAC 04)
1728 * The system also has a pair of internal speakers, and a headphone jack.
1729 * These are both connected to Line2 on the codec, hence to DAC 02.
1731 * There is a variable resistor to control the speaker or headphone
1732 * volume. This is a hardware-only device without a software API.
1734 * Plugging headphones in will disable the internal speakers. This is
1735 * implemented in hardware, not via the driver using jack sense. In
1736 * a similar fashion, plugging into the rear socket marked "front" will
1737 * disable both the speakers and headphones.
1739 * For input, there's a microphone jack, and an "audio in" jack.
1740 * These may not do anything useful with this driver yet, because I
1741 * haven't setup any initialization verbs for these yet...
1744 static hda_nid_t alc880_w810_dac_nids
[3] = {
1745 /* front, rear/surround, clfe */
1749 /* fixed 6 channels */
1750 static struct hda_channel_mode alc880_w810_modes
[1] = {
1754 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1755 static struct snd_kcontrol_new alc880_w810_base_mixer
[] = {
1756 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1758 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1759 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1760 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1761 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1762 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
1772 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1773 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1777 static hda_nid_t alc880_z71v_dac_nids
[1] = {
1780 #define ALC880_Z71V_HP_DAC 0x03
1782 /* fixed 2 channels */
1783 static struct hda_channel_mode alc880_2_jack_modes
[1] = {
1787 static struct snd_kcontrol_new alc880_z71v_mixer
[] = {
1788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1789 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1790 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1791 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT
),
1792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1801 * ALC880 F1734 model
1803 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1804 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1807 static hda_nid_t alc880_f1734_dac_nids
[1] = {
1810 #define ALC880_F1734_HP_DAC 0x02
1812 static struct snd_kcontrol_new alc880_f1734_mixer
[] = {
1813 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1814 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1815 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1816 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1817 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1818 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1824 static struct hda_input_mux alc880_f1734_capture_source
= {
1836 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1837 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1838 * Mic = 0x18, Line = 0x1a
1841 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1842 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1844 static struct snd_kcontrol_new alc880_asus_mixer
[] = {
1845 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1846 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1847 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1849 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1850 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1851 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1852 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1854 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1855 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1856 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1860 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1861 .name
= "Channel Mode",
1862 .info
= alc_ch_mode_info
,
1863 .get
= alc_ch_mode_get
,
1864 .put
= alc_ch_mode_put
,
1870 * ALC880 ASUS W1V model
1872 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1873 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1874 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1877 /* additional mixers to alc880_asus_mixer */
1878 static struct snd_kcontrol_new alc880_asus_w1v_mixer
[] = {
1879 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT
),
1880 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT
),
1885 static struct snd_kcontrol_new alc880_tcl_s700_mixer
[] = {
1886 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1887 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
1888 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
1889 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT
),
1890 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT
),
1891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT
),
1892 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT
),
1893 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
1894 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
1899 static struct snd_kcontrol_new alc880_uniwill_mixer
[] = {
1900 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1901 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1902 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1903 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1904 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1908 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1909 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1910 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1911 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1914 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1915 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1917 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1918 .name
= "Channel Mode",
1919 .info
= alc_ch_mode_info
,
1920 .get
= alc_ch_mode_get
,
1921 .put
= alc_ch_mode_put
,
1926 static struct snd_kcontrol_new alc880_fujitsu_mixer
[] = {
1927 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1928 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1929 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1930 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1931 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1932 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1933 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1934 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1935 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1936 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1940 static struct snd_kcontrol_new alc880_uniwill_p53_mixer
[] = {
1941 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1942 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1944 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1946 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1951 * virtual master controls
1955 * slave controls for virtual master
1957 static const char *alc_slave_vols
[] = {
1958 "Front Playback Volume",
1959 "Surround Playback Volume",
1960 "Center Playback Volume",
1961 "LFE Playback Volume",
1962 "Side Playback Volume",
1963 "Headphone Playback Volume",
1964 "Speaker Playback Volume",
1965 "Mono Playback Volume",
1966 "Line-Out Playback Volume",
1967 "PCM Playback Volume",
1971 static const char *alc_slave_sws
[] = {
1972 "Front Playback Switch",
1973 "Surround Playback Switch",
1974 "Center Playback Switch",
1975 "LFE Playback Switch",
1976 "Side Playback Switch",
1977 "Headphone Playback Switch",
1978 "Speaker Playback Switch",
1979 "Mono Playback Switch",
1980 "IEC958 Playback Switch",
1985 * build control elements
1988 static void alc_free_kctls(struct hda_codec
*codec
);
1990 /* additional beep mixers; the actual parameters are overwritten at build */
1991 static struct snd_kcontrol_new alc_beep_mixer
[] = {
1992 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT
),
1993 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT
),
1997 static int alc_build_controls(struct hda_codec
*codec
)
1999 struct alc_spec
*spec
= codec
->spec
;
2003 for (i
= 0; i
< spec
->num_mixers
; i
++) {
2004 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
2008 if (spec
->cap_mixer
) {
2009 err
= snd_hda_add_new_ctls(codec
, spec
->cap_mixer
);
2013 if (spec
->multiout
.dig_out_nid
) {
2014 err
= snd_hda_create_spdif_out_ctls(codec
,
2015 spec
->multiout
.dig_out_nid
);
2018 if (!spec
->no_analog
) {
2019 err
= snd_hda_create_spdif_share_sw(codec
,
2023 spec
->multiout
.share_spdif
= 1;
2026 if (spec
->dig_in_nid
) {
2027 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
2032 /* create beep controls if needed */
2033 if (spec
->beep_amp
) {
2034 struct snd_kcontrol_new
*knew
;
2035 for (knew
= alc_beep_mixer
; knew
->name
; knew
++) {
2036 struct snd_kcontrol
*kctl
;
2037 kctl
= snd_ctl_new1(knew
, codec
);
2040 kctl
->private_value
= spec
->beep_amp
;
2041 err
= snd_hda_ctl_add(codec
, kctl
);
2047 /* if we have no master control, let's create it */
2048 if (!spec
->no_analog
&&
2049 !snd_hda_find_mixer_ctl(codec
, "Master Playback Volume")) {
2050 unsigned int vmaster_tlv
[4];
2051 snd_hda_set_vmaster_tlv(codec
, spec
->vmaster_nid
,
2052 HDA_OUTPUT
, vmaster_tlv
);
2053 err
= snd_hda_add_vmaster(codec
, "Master Playback Volume",
2054 vmaster_tlv
, alc_slave_vols
);
2058 if (!spec
->no_analog
&&
2059 !snd_hda_find_mixer_ctl(codec
, "Master Playback Switch")) {
2060 err
= snd_hda_add_vmaster(codec
, "Master Playback Switch",
2061 NULL
, alc_slave_sws
);
2066 alc_free_kctls(codec
); /* no longer needed */
2072 * initialize the codec volumes, etc
2076 * generic initialization of ADC, input mixers and output mixers
2078 static struct hda_verb alc880_volume_init_verbs
[] = {
2080 * Unmute ADC0-2 and set the default input to mic-in
2082 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
2083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2084 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
2085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2086 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
2087 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2089 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2091 * Note: PASD motherboards uses the Line In 2 as the input for front
2094 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
2098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
2099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
2100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)},
2101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)},
2104 * Set up output mixers (0x0c - 0x0f)
2106 /* set vol=0 to output mixers */
2107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2110 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2111 /* set up input amps for analog loopback */
2112 /* Amp Indices: DAC = 0, mixer = 1 */
2113 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2116 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2117 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2118 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2119 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2120 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2126 * 3-stack pin configuration:
2127 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2129 static struct hda_verb alc880_pin_3stack_init_verbs
[] = {
2131 * preset connection lists of input pins
2132 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2134 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
2135 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2136 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x03}, /* line/surround */
2139 * Set pin mode and muting
2141 /* set front pin widgets 0x14 for output */
2142 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2143 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2144 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2145 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2146 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2147 /* Mic2 (as headphone out) for HP output */
2148 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2149 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2150 /* Line In pin widget for input */
2151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2153 /* Line2 (as front mic) pin widget for input and vref at 80% */
2154 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2155 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2156 /* CD pin widget for input */
2157 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2163 * 5-stack pin configuration:
2164 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2165 * line-in/side = 0x1a, f-mic = 0x1b
2167 static struct hda_verb alc880_pin_5stack_init_verbs
[] = {
2169 * preset connection lists of input pins
2170 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2172 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2173 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/side */
2176 * Set pin mode and muting
2178 /* set pin widgets 0x14-0x17 for output */
2179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2183 /* unmute pins for output (no gain on this amp) */
2184 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2185 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2186 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2187 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2189 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2190 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2191 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2192 /* Mic2 (as headphone out) for HP output */
2193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2194 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2195 /* Line In pin widget for input */
2196 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2197 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2198 /* Line2 (as front mic) pin widget for input and vref at 80% */
2199 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2200 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2201 /* CD pin widget for input */
2202 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2208 * W810 pin configuration:
2209 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2211 static struct hda_verb alc880_pin_w810_init_verbs
[] = {
2212 /* hphone/speaker input selector: front DAC */
2213 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x0},
2215 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2218 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2219 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2220 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2222 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2223 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2229 * Z71V pin configuration:
2230 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2232 static struct hda_verb alc880_pin_z71v_init_verbs
[] = {
2233 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2234 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2238 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2239 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2241 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2247 * 6-stack pin configuration:
2248 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2249 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2251 static struct hda_verb alc880_pin_6stack_init_verbs
[] = {
2252 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2260 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2261 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2263 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2264 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2265 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2266 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2269 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2270 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2271 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2277 * Uniwill pin configuration:
2278 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2281 static struct hda_verb alc880_uniwill_init_verbs
[] = {
2282 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2284 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2285 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2286 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2287 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2288 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2289 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2290 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2291 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2292 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2293 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2294 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2295 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2296 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2297 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2301 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2302 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2303 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2304 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2305 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2306 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2307 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2309 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
2310 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
2317 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2319 static struct hda_verb alc880_uniwill_p53_init_verbs
[] = {
2320 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2323 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2326 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2327 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2329 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2330 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2332 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
2333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
2335 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2336 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2337 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2338 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2340 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2342 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
2343 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_DCVOL_EVENT
},
2348 static struct hda_verb alc880_beep_init_verbs
[] = {
2349 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5) },
2353 /* toggle speaker-output according to the hp-jack state */
2354 static void alc880_uniwill_hp_automute(struct hda_codec
*codec
)
2356 unsigned int present
;
2359 present
= snd_hda_codec_read(codec
, 0x14, 0,
2360 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
2361 bits
= present
? HDA_AMP_MUTE
: 0;
2362 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
2363 HDA_AMP_MUTE
, bits
);
2364 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
2365 HDA_AMP_MUTE
, bits
);
2368 /* auto-toggle front mic */
2369 static void alc880_uniwill_mic_automute(struct hda_codec
*codec
)
2371 unsigned int present
;
2374 present
= snd_hda_codec_read(codec
, 0x18, 0,
2375 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
2376 bits
= present
? HDA_AMP_MUTE
: 0;
2377 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, 1, HDA_AMP_MUTE
, bits
);
2380 static void alc880_uniwill_automute(struct hda_codec
*codec
)
2382 alc880_uniwill_hp_automute(codec
);
2383 alc880_uniwill_mic_automute(codec
);
2386 static void alc880_uniwill_unsol_event(struct hda_codec
*codec
,
2389 /* Looks like the unsol event is incompatible with the standard
2390 * definition. 4bit tag is placed at 28 bit!
2392 switch (res
>> 28) {
2393 case ALC880_HP_EVENT
:
2394 alc880_uniwill_hp_automute(codec
);
2396 case ALC880_MIC_EVENT
:
2397 alc880_uniwill_mic_automute(codec
);
2402 static void alc880_uniwill_p53_hp_automute(struct hda_codec
*codec
)
2404 unsigned int present
;
2407 present
= snd_hda_codec_read(codec
, 0x14, 0,
2408 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
2409 bits
= present
? HDA_AMP_MUTE
: 0;
2410 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0, HDA_AMP_MUTE
, bits
);
2413 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec
*codec
)
2415 unsigned int present
;
2417 present
= snd_hda_codec_read(codec
, 0x21, 0,
2418 AC_VERB_GET_VOLUME_KNOB_CONTROL
, 0);
2419 present
&= HDA_AMP_VOLMASK
;
2420 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_OUTPUT
, 0,
2421 HDA_AMP_VOLMASK
, present
);
2422 snd_hda_codec_amp_stereo(codec
, 0x0d, HDA_OUTPUT
, 0,
2423 HDA_AMP_VOLMASK
, present
);
2426 static void alc880_uniwill_p53_unsol_event(struct hda_codec
*codec
,
2429 /* Looks like the unsol event is incompatible with the standard
2430 * definition. 4bit tag is placed at 28 bit!
2432 if ((res
>> 28) == ALC880_HP_EVENT
)
2433 alc880_uniwill_p53_hp_automute(codec
);
2434 if ((res
>> 28) == ALC880_DCVOL_EVENT
)
2435 alc880_uniwill_p53_dcvol_automute(codec
);
2439 * F1734 pin configuration:
2440 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2442 static struct hda_verb alc880_pin_f1734_init_verbs
[] = {
2443 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x01},
2444 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02},
2445 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00},
2446 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01},
2447 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00},
2449 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2450 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2451 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2454 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2455 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2456 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
2457 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2458 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2459 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2460 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2461 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2462 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2464 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_HP_EVENT
},
2465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_DCVOL_EVENT
},
2471 * ASUS pin configuration:
2472 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2474 static struct hda_verb alc880_pin_asus_init_verbs
[] = {
2475 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02},
2476 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00},
2477 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01},
2478 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00},
2480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2484 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2485 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2486 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2487 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2491 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2492 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2493 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2497 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2502 /* Enable GPIO mask and set output */
2503 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2504 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2506 /* Clevo m520g init */
2507 static struct hda_verb alc880_pin_clevo_init_verbs
[] = {
2508 /* headphone output */
2509 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x01},
2511 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2512 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2514 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2515 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2517 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2518 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2519 /* Mic1 (rear panel) */
2520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2522 /* Mic2 (front panel) */
2523 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2524 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2526 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2527 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2528 /* change to EAPD mode */
2529 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
2530 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
2535 static struct hda_verb alc880_pin_tcl_S700_init_verbs
[] = {
2536 /* change to EAPD mode */
2537 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
2538 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
2540 /* Headphone output */
2541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2544 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
2546 /* Line In pin widget for input */
2547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2548 /* CD pin widget for input */
2549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2550 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2551 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2553 /* change to EAPD mode */
2554 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
2555 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
2561 * LG m1 express dual
2564 * Rear Line-In/Out (blue): 0x14
2565 * Build-in Mic-In: 0x15
2567 * HP-Out (green): 0x1b
2568 * Mic-In/Out (red): 0x19
2572 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2573 static hda_nid_t alc880_lg_dac_nids
[3] = {
2577 /* seems analog CD is not working */
2578 static struct hda_input_mux alc880_lg_capture_source
= {
2583 { "Internal Mic", 0x6 },
2587 /* 2,4,6 channel modes */
2588 static struct hda_verb alc880_lg_ch2_init
[] = {
2589 /* set line-in and mic-in to input */
2590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2591 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2595 static struct hda_verb alc880_lg_ch4_init
[] = {
2596 /* set line-in to out and mic-in to input */
2597 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2598 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2602 static struct hda_verb alc880_lg_ch6_init
[] = {
2603 /* set line-in and mic-in to output */
2604 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2605 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2609 static struct hda_channel_mode alc880_lg_ch_modes
[3] = {
2610 { 2, alc880_lg_ch2_init
},
2611 { 4, alc880_lg_ch4_init
},
2612 { 6, alc880_lg_ch6_init
},
2615 static struct snd_kcontrol_new alc880_lg_mixer
[] = {
2616 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
2617 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT
),
2618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
2619 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT
),
2620 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT
),
2621 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT
),
2622 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT
),
2623 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT
),
2624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
2625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
2626 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT
),
2627 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT
),
2628 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT
),
2629 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT
),
2631 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2632 .name
= "Channel Mode",
2633 .info
= alc_ch_mode_info
,
2634 .get
= alc_ch_mode_get
,
2635 .put
= alc_ch_mode_put
,
2640 static struct hda_verb alc880_lg_init_verbs
[] = {
2641 /* set capture source to mic-in */
2642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2643 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2644 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2645 /* mute all amp mixer inputs */
2646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5)},
2647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)},
2648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)},
2649 /* line-in to input */
2650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2651 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2654 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2656 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2657 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2658 /* mic-in to input */
2659 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x01},
2660 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2661 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2663 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x03},
2664 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2665 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2667 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| 0x1},
2671 /* toggle speaker-output according to the hp-jack state */
2672 static void alc880_lg_automute(struct hda_codec
*codec
)
2674 unsigned int present
;
2677 present
= snd_hda_codec_read(codec
, 0x1b, 0,
2678 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
2679 bits
= present
? HDA_AMP_MUTE
: 0;
2680 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
2681 HDA_AMP_MUTE
, bits
);
2684 static void alc880_lg_unsol_event(struct hda_codec
*codec
, unsigned int res
)
2686 /* Looks like the unsol event is incompatible with the standard
2687 * definition. 4bit tag is placed at 28 bit!
2689 if ((res
>> 28) == 0x01)
2690 alc880_lg_automute(codec
);
2699 * Built-in Mic-In: 0x19
2705 static struct hda_input_mux alc880_lg_lw_capture_source
= {
2709 { "Internal Mic", 0x1 },
2714 #define alc880_lg_lw_modes alc880_threestack_modes
2716 static struct snd_kcontrol_new alc880_lg_lw_mixer
[] = {
2717 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
2718 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
2719 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
2720 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT
),
2721 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
2722 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
2723 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
2724 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
2725 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
2726 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
2727 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
2728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
2729 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
2730 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
2732 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2733 .name
= "Channel Mode",
2734 .info
= alc_ch_mode_info
,
2735 .get
= alc_ch_mode_get
,
2736 .put
= alc_ch_mode_put
,
2741 static struct hda_verb alc880_lg_lw_init_verbs
[] = {
2742 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2743 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
2744 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x03}, /* line/surround */
2746 /* set capture source to mic-in */
2747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2748 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2750 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)},
2752 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2753 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2757 /* mic-in to input */
2758 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2759 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2761 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2762 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| 0x1},
2768 /* toggle speaker-output according to the hp-jack state */
2769 static void alc880_lg_lw_automute(struct hda_codec
*codec
)
2771 unsigned int present
;
2774 present
= snd_hda_codec_read(codec
, 0x1b, 0,
2775 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
2776 bits
= present
? HDA_AMP_MUTE
: 0;
2777 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
2778 HDA_AMP_MUTE
, bits
);
2781 static void alc880_lg_lw_unsol_event(struct hda_codec
*codec
, unsigned int res
)
2783 /* Looks like the unsol event is incompatible with the standard
2784 * definition. 4bit tag is placed at 28 bit!
2786 if ((res
>> 28) == 0x01)
2787 alc880_lg_lw_automute(codec
);
2790 static struct snd_kcontrol_new alc880_medion_rim_mixer
[] = {
2791 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
2792 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT
),
2793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
2794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
2795 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
2796 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT
),
2800 static struct hda_input_mux alc880_medion_rim_capture_source
= {
2804 { "Internal Mic", 0x1 },
2808 static struct hda_verb alc880_medion_rim_init_verbs
[] = {
2809 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
2811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2814 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2817 /* Mic2 (as headphone out) for HP output */
2818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
2819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2820 /* Internal Speaker */
2821 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2824 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
2825 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
2827 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
2831 /* toggle speaker-output according to the hp-jack state */
2832 static void alc880_medion_rim_automute(struct hda_codec
*codec
)
2834 unsigned int present
;
2837 present
= snd_hda_codec_read(codec
, 0x14, 0,
2838 AC_VERB_GET_PIN_SENSE
, 0)
2839 & AC_PINSENSE_PRESENCE
;
2840 bits
= present
? HDA_AMP_MUTE
: 0;
2841 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
2842 HDA_AMP_MUTE
, bits
);
2844 snd_hda_codec_write(codec
, 0x01, 0, AC_VERB_SET_GPIO_DATA
, 0);
2846 snd_hda_codec_write(codec
, 0x01, 0, AC_VERB_SET_GPIO_DATA
, 2);
2849 static void alc880_medion_rim_unsol_event(struct hda_codec
*codec
,
2852 /* Looks like the unsol event is incompatible with the standard
2853 * definition. 4bit tag is placed at 28 bit!
2855 if ((res
>> 28) == ALC880_HP_EVENT
)
2856 alc880_medion_rim_automute(codec
);
2859 #ifdef CONFIG_SND_HDA_POWER_SAVE
2860 static struct hda_amp_list alc880_loopbacks
[] = {
2861 { 0x0b, HDA_INPUT
, 0 },
2862 { 0x0b, HDA_INPUT
, 1 },
2863 { 0x0b, HDA_INPUT
, 2 },
2864 { 0x0b, HDA_INPUT
, 3 },
2865 { 0x0b, HDA_INPUT
, 4 },
2869 static struct hda_amp_list alc880_lg_loopbacks
[] = {
2870 { 0x0b, HDA_INPUT
, 1 },
2871 { 0x0b, HDA_INPUT
, 6 },
2872 { 0x0b, HDA_INPUT
, 7 },
2881 static int alc_init(struct hda_codec
*codec
)
2883 struct alc_spec
*spec
= codec
->spec
;
2887 if (codec
->vendor_id
== 0x10ec0888)
2888 alc888_coef_init(codec
);
2890 for (i
= 0; i
< spec
->num_init_verbs
; i
++)
2891 snd_hda_sequence_write(codec
, spec
->init_verbs
[i
]);
2893 if (spec
->init_hook
)
2894 spec
->init_hook(codec
);
2899 static void alc_unsol_event(struct hda_codec
*codec
, unsigned int res
)
2901 struct alc_spec
*spec
= codec
->spec
;
2903 if (spec
->unsol_event
)
2904 spec
->unsol_event(codec
, res
);
2907 #ifdef CONFIG_SND_HDA_POWER_SAVE
2908 static int alc_check_power_status(struct hda_codec
*codec
, hda_nid_t nid
)
2910 struct alc_spec
*spec
= codec
->spec
;
2911 return snd_hda_check_amp_list_power(codec
, &spec
->loopback
, nid
);
2916 * Analog playback callbacks
2918 static int alc880_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
2919 struct hda_codec
*codec
,
2920 struct snd_pcm_substream
*substream
)
2922 struct alc_spec
*spec
= codec
->spec
;
2923 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
,
2927 static int alc880_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2928 struct hda_codec
*codec
,
2929 unsigned int stream_tag
,
2930 unsigned int format
,
2931 struct snd_pcm_substream
*substream
)
2933 struct alc_spec
*spec
= codec
->spec
;
2934 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
,
2935 stream_tag
, format
, substream
);
2938 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
2939 struct hda_codec
*codec
,
2940 struct snd_pcm_substream
*substream
)
2942 struct alc_spec
*spec
= codec
->spec
;
2943 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
2949 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
2950 struct hda_codec
*codec
,
2951 struct snd_pcm_substream
*substream
)
2953 struct alc_spec
*spec
= codec
->spec
;
2954 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
2957 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2958 struct hda_codec
*codec
,
2959 unsigned int stream_tag
,
2960 unsigned int format
,
2961 struct snd_pcm_substream
*substream
)
2963 struct alc_spec
*spec
= codec
->spec
;
2964 return snd_hda_multi_out_dig_prepare(codec
, &spec
->multiout
,
2965 stream_tag
, format
, substream
);
2968 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
2969 struct hda_codec
*codec
,
2970 struct snd_pcm_substream
*substream
)
2972 struct alc_spec
*spec
= codec
->spec
;
2973 return snd_hda_multi_out_dig_cleanup(codec
, &spec
->multiout
);
2976 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
2977 struct hda_codec
*codec
,
2978 struct snd_pcm_substream
*substream
)
2980 struct alc_spec
*spec
= codec
->spec
;
2981 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
2987 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2988 struct hda_codec
*codec
,
2989 unsigned int stream_tag
,
2990 unsigned int format
,
2991 struct snd_pcm_substream
*substream
)
2993 struct alc_spec
*spec
= codec
->spec
;
2995 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
+ 1],
2996 stream_tag
, 0, format
);
3000 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
3001 struct hda_codec
*codec
,
3002 struct snd_pcm_substream
*substream
)
3004 struct alc_spec
*spec
= codec
->spec
;
3006 snd_hda_codec_cleanup_stream(codec
,
3007 spec
->adc_nids
[substream
->number
+ 1]);
3014 static struct hda_pcm_stream alc880_pcm_analog_playback
= {
3018 /* NID is set in alc_build_pcms */
3020 .open
= alc880_playback_pcm_open
,
3021 .prepare
= alc880_playback_pcm_prepare
,
3022 .cleanup
= alc880_playback_pcm_cleanup
3026 static struct hda_pcm_stream alc880_pcm_analog_capture
= {
3030 /* NID is set in alc_build_pcms */
3033 static struct hda_pcm_stream alc880_pcm_analog_alt_playback
= {
3037 /* NID is set in alc_build_pcms */
3040 static struct hda_pcm_stream alc880_pcm_analog_alt_capture
= {
3041 .substreams
= 2, /* can be overridden */
3044 /* NID is set in alc_build_pcms */
3046 .prepare
= alc880_alt_capture_pcm_prepare
,
3047 .cleanup
= alc880_alt_capture_pcm_cleanup
3051 static struct hda_pcm_stream alc880_pcm_digital_playback
= {
3055 /* NID is set in alc_build_pcms */
3057 .open
= alc880_dig_playback_pcm_open
,
3058 .close
= alc880_dig_playback_pcm_close
,
3059 .prepare
= alc880_dig_playback_pcm_prepare
,
3060 .cleanup
= alc880_dig_playback_pcm_cleanup
3064 static struct hda_pcm_stream alc880_pcm_digital_capture
= {
3068 /* NID is set in alc_build_pcms */
3071 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3072 static struct hda_pcm_stream alc_pcm_null_stream
= {
3078 static int alc_build_pcms(struct hda_codec
*codec
)
3080 struct alc_spec
*spec
= codec
->spec
;
3081 struct hda_pcm
*info
= spec
->pcm_rec
;
3084 codec
->num_pcms
= 1;
3085 codec
->pcm_info
= info
;
3087 if (spec
->no_analog
)
3090 info
->name
= spec
->stream_name_analog
;
3091 if (spec
->stream_analog_playback
) {
3092 if (snd_BUG_ON(!spec
->multiout
.dac_nids
))
3094 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = *(spec
->stream_analog_playback
);
3095 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dac_nids
[0];
3097 if (spec
->stream_analog_capture
) {
3098 if (snd_BUG_ON(!spec
->adc_nids
))
3100 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_analog_capture
);
3101 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
3104 if (spec
->channel_mode
) {
3105 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
= 0;
3106 for (i
= 0; i
< spec
->num_channel_mode
; i
++) {
3107 if (spec
->channel_mode
[i
].channels
> info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
) {
3108 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
= spec
->channel_mode
[i
].channels
;
3114 /* SPDIF for stream index #1 */
3115 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
3116 codec
->num_pcms
= 2;
3117 codec
->slave_dig_outs
= spec
->multiout
.slave_dig_outs
;
3118 info
= spec
->pcm_rec
+ 1;
3119 info
->name
= spec
->stream_name_digital
;
3120 if (spec
->dig_out_type
)
3121 info
->pcm_type
= spec
->dig_out_type
;
3123 info
->pcm_type
= HDA_PCM_TYPE_SPDIF
;
3124 if (spec
->multiout
.dig_out_nid
&&
3125 spec
->stream_digital_playback
) {
3126 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = *(spec
->stream_digital_playback
);
3127 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
3129 if (spec
->dig_in_nid
&&
3130 spec
->stream_digital_capture
) {
3131 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_digital_capture
);
3132 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
3134 /* FIXME: do we need this for all Realtek codec models? */
3135 codec
->spdif_status_reset
= 1;
3138 if (spec
->no_analog
)
3141 /* If the use of more than one ADC is requested for the current
3142 * model, configure a second analog capture-only PCM.
3144 /* Additional Analaog capture for index #2 */
3145 if ((spec
->alt_dac_nid
&& spec
->stream_analog_alt_playback
) ||
3146 (spec
->num_adc_nids
> 1 && spec
->stream_analog_alt_capture
)) {
3147 codec
->num_pcms
= 3;
3148 info
= spec
->pcm_rec
+ 2;
3149 info
->name
= spec
->stream_name_analog
;
3150 if (spec
->alt_dac_nid
) {
3151 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] =
3152 *spec
->stream_analog_alt_playback
;
3153 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
=
3156 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] =
3157 alc_pcm_null_stream
;
3158 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= 0;
3160 if (spec
->num_adc_nids
> 1) {
3161 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] =
3162 *spec
->stream_analog_alt_capture
;
3163 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
=
3165 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].substreams
=
3166 spec
->num_adc_nids
- 1;
3168 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] =
3169 alc_pcm_null_stream
;
3170 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= 0;
3177 static void alc_free_kctls(struct hda_codec
*codec
)
3179 struct alc_spec
*spec
= codec
->spec
;
3181 if (spec
->kctls
.list
) {
3182 struct snd_kcontrol_new
*kctl
= spec
->kctls
.list
;
3184 for (i
= 0; i
< spec
->kctls
.used
; i
++)
3185 kfree(kctl
[i
].name
);
3187 snd_array_free(&spec
->kctls
);
3190 static void alc_free(struct hda_codec
*codec
)
3192 struct alc_spec
*spec
= codec
->spec
;
3197 alc_free_kctls(codec
);
3199 snd_hda_detach_beep_device(codec
);
3202 #ifdef SND_HDA_NEEDS_RESUME
3203 static int alc_resume(struct hda_codec
*codec
)
3205 codec
->patch_ops
.init(codec
);
3206 snd_hda_codec_resume_amp(codec
);
3207 snd_hda_codec_resume_cache(codec
);
3214 static struct hda_codec_ops alc_patch_ops
= {
3215 .build_controls
= alc_build_controls
,
3216 .build_pcms
= alc_build_pcms
,
3219 .unsol_event
= alc_unsol_event
,
3220 #ifdef SND_HDA_NEEDS_RESUME
3221 .resume
= alc_resume
,
3223 #ifdef CONFIG_SND_HDA_POWER_SAVE
3224 .check_power_status
= alc_check_power_status
,
3230 * Test configuration for debugging
3232 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3235 #ifdef CONFIG_SND_DEBUG
3236 static hda_nid_t alc880_test_dac_nids
[4] = {
3237 0x02, 0x03, 0x04, 0x05
3240 static struct hda_input_mux alc880_test_capture_source
= {
3249 { "Surround", 0x6 },
3253 static struct hda_channel_mode alc880_test_modes
[4] = {
3260 static int alc_test_pin_ctl_info(struct snd_kcontrol
*kcontrol
,
3261 struct snd_ctl_elem_info
*uinfo
)
3263 static char *texts
[] = {
3264 "N/A", "Line Out", "HP Out",
3265 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3267 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
3269 uinfo
->value
.enumerated
.items
= 8;
3270 if (uinfo
->value
.enumerated
.item
>= 8)
3271 uinfo
->value
.enumerated
.item
= 7;
3272 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
3276 static int alc_test_pin_ctl_get(struct snd_kcontrol
*kcontrol
,
3277 struct snd_ctl_elem_value
*ucontrol
)
3279 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
3280 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
3281 unsigned int pin_ctl
, item
= 0;
3283 pin_ctl
= snd_hda_codec_read(codec
, nid
, 0,
3284 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
3285 if (pin_ctl
& AC_PINCTL_OUT_EN
) {
3286 if (pin_ctl
& AC_PINCTL_HP_EN
)
3290 } else if (pin_ctl
& AC_PINCTL_IN_EN
) {
3291 switch (pin_ctl
& AC_PINCTL_VREFEN
) {
3292 case AC_PINCTL_VREF_HIZ
: item
= 3; break;
3293 case AC_PINCTL_VREF_50
: item
= 4; break;
3294 case AC_PINCTL_VREF_GRD
: item
= 5; break;
3295 case AC_PINCTL_VREF_80
: item
= 6; break;
3296 case AC_PINCTL_VREF_100
: item
= 7; break;
3299 ucontrol
->value
.enumerated
.item
[0] = item
;
3303 static int alc_test_pin_ctl_put(struct snd_kcontrol
*kcontrol
,
3304 struct snd_ctl_elem_value
*ucontrol
)
3306 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
3307 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
3308 static unsigned int ctls
[] = {
3309 0, AC_PINCTL_OUT_EN
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
,
3310 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_HIZ
,
3311 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_50
,
3312 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_GRD
,
3313 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_80
,
3314 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_100
,
3316 unsigned int old_ctl
, new_ctl
;
3318 old_ctl
= snd_hda_codec_read(codec
, nid
, 0,
3319 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
3320 new_ctl
= ctls
[ucontrol
->value
.enumerated
.item
[0]];
3321 if (old_ctl
!= new_ctl
) {
3323 snd_hda_codec_write_cache(codec
, nid
, 0,
3324 AC_VERB_SET_PIN_WIDGET_CONTROL
,
3326 val
= ucontrol
->value
.enumerated
.item
[0] >= 3 ?
3328 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
3335 static int alc_test_pin_src_info(struct snd_kcontrol
*kcontrol
,
3336 struct snd_ctl_elem_info
*uinfo
)
3338 static char *texts
[] = {
3339 "Front", "Surround", "CLFE", "Side"
3341 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
3343 uinfo
->value
.enumerated
.items
= 4;
3344 if (uinfo
->value
.enumerated
.item
>= 4)
3345 uinfo
->value
.enumerated
.item
= 3;
3346 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
3350 static int alc_test_pin_src_get(struct snd_kcontrol
*kcontrol
,
3351 struct snd_ctl_elem_value
*ucontrol
)
3353 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
3354 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
3357 sel
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONNECT_SEL
, 0);
3358 ucontrol
->value
.enumerated
.item
[0] = sel
& 3;
3362 static int alc_test_pin_src_put(struct snd_kcontrol
*kcontrol
,
3363 struct snd_ctl_elem_value
*ucontrol
)
3365 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
3366 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
3369 sel
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONNECT_SEL
, 0) & 3;
3370 if (ucontrol
->value
.enumerated
.item
[0] != sel
) {
3371 sel
= ucontrol
->value
.enumerated
.item
[0] & 3;
3372 snd_hda_codec_write_cache(codec
, nid
, 0,
3373 AC_VERB_SET_CONNECT_SEL
, sel
);
3379 #define PIN_CTL_TEST(xname,nid) { \
3380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3382 .info = alc_test_pin_ctl_info, \
3383 .get = alc_test_pin_ctl_get, \
3384 .put = alc_test_pin_ctl_put, \
3385 .private_value = nid \
3388 #define PIN_SRC_TEST(xname,nid) { \
3389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3391 .info = alc_test_pin_src_info, \
3392 .get = alc_test_pin_src_get, \
3393 .put = alc_test_pin_src_put, \
3394 .private_value = nid \
3397 static struct snd_kcontrol_new alc880_test_mixer
[] = {
3398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
3399 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
3400 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
3401 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
3402 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
3403 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
3404 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT
),
3405 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
3406 PIN_CTL_TEST("Front Pin Mode", 0x14),
3407 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3408 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3409 PIN_CTL_TEST("Side Pin Mode", 0x17),
3410 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3411 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3412 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3413 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3414 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3415 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3416 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3417 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3418 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT
),
3419 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT
),
3420 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT
),
3421 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT
),
3422 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT
),
3423 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT
),
3424 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT
),
3425 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT
),
3426 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT
),
3427 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT
),
3429 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3430 .name
= "Channel Mode",
3431 .info
= alc_ch_mode_info
,
3432 .get
= alc_ch_mode_get
,
3433 .put
= alc_ch_mode_put
,
3438 static struct hda_verb alc880_test_init_verbs
[] = {
3439 /* Unmute inputs of 0x0c - 0x0f */
3440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3441 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
3442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3443 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
3444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3445 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
3446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3447 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
3448 /* Vol output for 0x0c-0x0f */
3449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3450 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3451 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3452 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3453 /* Set output pins 0x14-0x17 */
3454 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3456 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3457 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3458 /* Unmute output pins 0x14-0x17 */
3459 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3461 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3462 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3463 /* Set input pins 0x18-0x1c */
3464 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
3465 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
3466 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3467 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3468 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3469 /* Mute input pins 0x18-0x1b */
3470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
3471 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
3472 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
3473 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
3475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3476 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
3477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3478 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
3479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3480 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
3481 /* Analog input/passthru */
3482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
3485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
3486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
3494 static const char *alc880_models
[ALC880_MODEL_LAST
] = {
3495 [ALC880_3ST
] = "3stack",
3496 [ALC880_TCL_S700
] = "tcl",
3497 [ALC880_3ST_DIG
] = "3stack-digout",
3498 [ALC880_CLEVO
] = "clevo",
3499 [ALC880_5ST
] = "5stack",
3500 [ALC880_5ST_DIG
] = "5stack-digout",
3501 [ALC880_W810
] = "w810",
3502 [ALC880_Z71V
] = "z71v",
3503 [ALC880_6ST
] = "6stack",
3504 [ALC880_6ST_DIG
] = "6stack-digout",
3505 [ALC880_ASUS
] = "asus",
3506 [ALC880_ASUS_W1V
] = "asus-w1v",
3507 [ALC880_ASUS_DIG
] = "asus-dig",
3508 [ALC880_ASUS_DIG2
] = "asus-dig2",
3509 [ALC880_UNIWILL_DIG
] = "uniwill",
3510 [ALC880_UNIWILL_P53
] = "uniwill-p53",
3511 [ALC880_FUJITSU
] = "fujitsu",
3512 [ALC880_F1734
] = "F1734",
3514 [ALC880_LG_LW
] = "lg-lw",
3515 [ALC880_MEDION_RIM
] = "medion",
3516 #ifdef CONFIG_SND_DEBUG
3517 [ALC880_TEST
] = "test",
3519 [ALC880_AUTO
] = "auto",
3522 static struct snd_pci_quirk alc880_cfg_tbl
[] = {
3523 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810
),
3524 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG
),
3525 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST
),
3526 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG
),
3527 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG
),
3528 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG
),
3529 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG
),
3530 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG
),
3531 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST
),
3532 SND_PCI_QUIRK(0x1039, 0x1234, NULL
, ALC880_6ST_DIG
),
3533 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST
),
3534 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V
),
3535 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG
),
3536 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG
),
3537 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG
),
3538 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG
),
3539 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG
),
3540 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V
),
3541 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3542 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG
),
3543 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG
),
3544 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG
),
3545 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG
),
3546 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST
),
3547 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST
),
3548 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS
), /* default ASUS */
3549 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST
),
3550 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST
),
3551 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST
),
3552 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST
),
3553 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST
),
3554 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG
),
3555 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG
),
3556 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG
),
3557 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG
),
3558 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO
),
3559 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO
),
3560 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2
),
3561 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG
),
3562 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG
),
3563 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734
),
3564 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL
),
3565 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53
),
3566 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810
),
3567 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM
),
3568 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG
),
3569 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG
),
3570 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734
),
3571 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU
),
3572 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL
),
3573 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU
),
3574 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW
),
3575 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG
),
3576 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG
),
3577 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW
),
3578 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700
),
3579 SND_PCI_QUIRK(0x2668, 0x8086, NULL
, ALC880_6ST_DIG
), /* broken BIOS */
3580 SND_PCI_QUIRK(0x8086, 0x2668, NULL
, ALC880_6ST_DIG
),
3581 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG
),
3582 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG
),
3583 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG
),
3584 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG
),
3585 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG
),
3586 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG
),
3587 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG
),
3588 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG
),
3589 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG
),
3590 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG
),
3592 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST
),
3593 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG
),
3594 SND_PCI_QUIRK(0xe803, 0x1019, NULL
, ALC880_6ST_DIG
),
3599 * ALC880 codec presets
3601 static struct alc_config_preset alc880_presets
[] = {
3603 .mixers
= { alc880_three_stack_mixer
},
3604 .init_verbs
= { alc880_volume_init_verbs
,
3605 alc880_pin_3stack_init_verbs
},
3606 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3607 .dac_nids
= alc880_dac_nids
,
3608 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
3609 .channel_mode
= alc880_threestack_modes
,
3611 .input_mux
= &alc880_capture_source
,
3613 [ALC880_3ST_DIG
] = {
3614 .mixers
= { alc880_three_stack_mixer
},
3615 .init_verbs
= { alc880_volume_init_verbs
,
3616 alc880_pin_3stack_init_verbs
},
3617 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3618 .dac_nids
= alc880_dac_nids
,
3619 .dig_out_nid
= ALC880_DIGOUT_NID
,
3620 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
3621 .channel_mode
= alc880_threestack_modes
,
3623 .input_mux
= &alc880_capture_source
,
3625 [ALC880_TCL_S700
] = {
3626 .mixers
= { alc880_tcl_s700_mixer
},
3627 .init_verbs
= { alc880_volume_init_verbs
,
3628 alc880_pin_tcl_S700_init_verbs
,
3629 alc880_gpio2_init_verbs
},
3630 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3631 .dac_nids
= alc880_dac_nids
,
3632 .adc_nids
= alc880_adc_nids_alt
, /* FIXME: correct? */
3633 .num_adc_nids
= 1, /* single ADC */
3635 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
3636 .channel_mode
= alc880_2_jack_modes
,
3637 .input_mux
= &alc880_capture_source
,
3640 .mixers
= { alc880_three_stack_mixer
,
3641 alc880_five_stack_mixer
},
3642 .init_verbs
= { alc880_volume_init_verbs
,
3643 alc880_pin_5stack_init_verbs
},
3644 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3645 .dac_nids
= alc880_dac_nids
,
3646 .num_channel_mode
= ARRAY_SIZE(alc880_fivestack_modes
),
3647 .channel_mode
= alc880_fivestack_modes
,
3648 .input_mux
= &alc880_capture_source
,
3650 [ALC880_5ST_DIG
] = {
3651 .mixers
= { alc880_three_stack_mixer
,
3652 alc880_five_stack_mixer
},
3653 .init_verbs
= { alc880_volume_init_verbs
,
3654 alc880_pin_5stack_init_verbs
},
3655 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3656 .dac_nids
= alc880_dac_nids
,
3657 .dig_out_nid
= ALC880_DIGOUT_NID
,
3658 .num_channel_mode
= ARRAY_SIZE(alc880_fivestack_modes
),
3659 .channel_mode
= alc880_fivestack_modes
,
3660 .input_mux
= &alc880_capture_source
,
3663 .mixers
= { alc880_six_stack_mixer
},
3664 .init_verbs
= { alc880_volume_init_verbs
,
3665 alc880_pin_6stack_init_verbs
},
3666 .num_dacs
= ARRAY_SIZE(alc880_6st_dac_nids
),
3667 .dac_nids
= alc880_6st_dac_nids
,
3668 .num_channel_mode
= ARRAY_SIZE(alc880_sixstack_modes
),
3669 .channel_mode
= alc880_sixstack_modes
,
3670 .input_mux
= &alc880_6stack_capture_source
,
3672 [ALC880_6ST_DIG
] = {
3673 .mixers
= { alc880_six_stack_mixer
},
3674 .init_verbs
= { alc880_volume_init_verbs
,
3675 alc880_pin_6stack_init_verbs
},
3676 .num_dacs
= ARRAY_SIZE(alc880_6st_dac_nids
),
3677 .dac_nids
= alc880_6st_dac_nids
,
3678 .dig_out_nid
= ALC880_DIGOUT_NID
,
3679 .num_channel_mode
= ARRAY_SIZE(alc880_sixstack_modes
),
3680 .channel_mode
= alc880_sixstack_modes
,
3681 .input_mux
= &alc880_6stack_capture_source
,
3684 .mixers
= { alc880_w810_base_mixer
},
3685 .init_verbs
= { alc880_volume_init_verbs
,
3686 alc880_pin_w810_init_verbs
,
3687 alc880_gpio2_init_verbs
},
3688 .num_dacs
= ARRAY_SIZE(alc880_w810_dac_nids
),
3689 .dac_nids
= alc880_w810_dac_nids
,
3690 .dig_out_nid
= ALC880_DIGOUT_NID
,
3691 .num_channel_mode
= ARRAY_SIZE(alc880_w810_modes
),
3692 .channel_mode
= alc880_w810_modes
,
3693 .input_mux
= &alc880_capture_source
,
3696 .mixers
= { alc880_z71v_mixer
},
3697 .init_verbs
= { alc880_volume_init_verbs
,
3698 alc880_pin_z71v_init_verbs
},
3699 .num_dacs
= ARRAY_SIZE(alc880_z71v_dac_nids
),
3700 .dac_nids
= alc880_z71v_dac_nids
,
3701 .dig_out_nid
= ALC880_DIGOUT_NID
,
3703 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
3704 .channel_mode
= alc880_2_jack_modes
,
3705 .input_mux
= &alc880_capture_source
,
3708 .mixers
= { alc880_f1734_mixer
},
3709 .init_verbs
= { alc880_volume_init_verbs
,
3710 alc880_pin_f1734_init_verbs
},
3711 .num_dacs
= ARRAY_SIZE(alc880_f1734_dac_nids
),
3712 .dac_nids
= alc880_f1734_dac_nids
,
3714 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
3715 .channel_mode
= alc880_2_jack_modes
,
3716 .input_mux
= &alc880_f1734_capture_source
,
3717 .unsol_event
= alc880_uniwill_p53_unsol_event
,
3718 .init_hook
= alc880_uniwill_p53_hp_automute
,
3721 .mixers
= { alc880_asus_mixer
},
3722 .init_verbs
= { alc880_volume_init_verbs
,
3723 alc880_pin_asus_init_verbs
,
3724 alc880_gpio1_init_verbs
},
3725 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3726 .dac_nids
= alc880_asus_dac_nids
,
3727 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
3728 .channel_mode
= alc880_asus_modes
,
3730 .input_mux
= &alc880_capture_source
,
3732 [ALC880_ASUS_DIG
] = {
3733 .mixers
= { alc880_asus_mixer
},
3734 .init_verbs
= { alc880_volume_init_verbs
,
3735 alc880_pin_asus_init_verbs
,
3736 alc880_gpio1_init_verbs
},
3737 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3738 .dac_nids
= alc880_asus_dac_nids
,
3739 .dig_out_nid
= ALC880_DIGOUT_NID
,
3740 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
3741 .channel_mode
= alc880_asus_modes
,
3743 .input_mux
= &alc880_capture_source
,
3745 [ALC880_ASUS_DIG2
] = {
3746 .mixers
= { alc880_asus_mixer
},
3747 .init_verbs
= { alc880_volume_init_verbs
,
3748 alc880_pin_asus_init_verbs
,
3749 alc880_gpio2_init_verbs
}, /* use GPIO2 */
3750 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3751 .dac_nids
= alc880_asus_dac_nids
,
3752 .dig_out_nid
= ALC880_DIGOUT_NID
,
3753 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
3754 .channel_mode
= alc880_asus_modes
,
3756 .input_mux
= &alc880_capture_source
,
3758 [ALC880_ASUS_W1V
] = {
3759 .mixers
= { alc880_asus_mixer
, alc880_asus_w1v_mixer
},
3760 .init_verbs
= { alc880_volume_init_verbs
,
3761 alc880_pin_asus_init_verbs
,
3762 alc880_gpio1_init_verbs
},
3763 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3764 .dac_nids
= alc880_asus_dac_nids
,
3765 .dig_out_nid
= ALC880_DIGOUT_NID
,
3766 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
3767 .channel_mode
= alc880_asus_modes
,
3769 .input_mux
= &alc880_capture_source
,
3771 [ALC880_UNIWILL_DIG
] = {
3772 .mixers
= { alc880_asus_mixer
},
3773 .init_verbs
= { alc880_volume_init_verbs
,
3774 alc880_pin_asus_init_verbs
},
3775 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3776 .dac_nids
= alc880_asus_dac_nids
,
3777 .dig_out_nid
= ALC880_DIGOUT_NID
,
3778 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
3779 .channel_mode
= alc880_asus_modes
,
3781 .input_mux
= &alc880_capture_source
,
3783 [ALC880_UNIWILL
] = {
3784 .mixers
= { alc880_uniwill_mixer
},
3785 .init_verbs
= { alc880_volume_init_verbs
,
3786 alc880_uniwill_init_verbs
},
3787 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3788 .dac_nids
= alc880_asus_dac_nids
,
3789 .dig_out_nid
= ALC880_DIGOUT_NID
,
3790 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
3791 .channel_mode
= alc880_threestack_modes
,
3793 .input_mux
= &alc880_capture_source
,
3794 .unsol_event
= alc880_uniwill_unsol_event
,
3795 .init_hook
= alc880_uniwill_automute
,
3797 [ALC880_UNIWILL_P53
] = {
3798 .mixers
= { alc880_uniwill_p53_mixer
},
3799 .init_verbs
= { alc880_volume_init_verbs
,
3800 alc880_uniwill_p53_init_verbs
},
3801 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
3802 .dac_nids
= alc880_asus_dac_nids
,
3803 .num_channel_mode
= ARRAY_SIZE(alc880_w810_modes
),
3804 .channel_mode
= alc880_threestack_modes
,
3805 .input_mux
= &alc880_capture_source
,
3806 .unsol_event
= alc880_uniwill_p53_unsol_event
,
3807 .init_hook
= alc880_uniwill_p53_hp_automute
,
3809 [ALC880_FUJITSU
] = {
3810 .mixers
= { alc880_fujitsu_mixer
},
3811 .init_verbs
= { alc880_volume_init_verbs
,
3812 alc880_uniwill_p53_init_verbs
,
3813 alc880_beep_init_verbs
},
3814 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3815 .dac_nids
= alc880_dac_nids
,
3816 .dig_out_nid
= ALC880_DIGOUT_NID
,
3817 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
3818 .channel_mode
= alc880_2_jack_modes
,
3819 .input_mux
= &alc880_capture_source
,
3820 .unsol_event
= alc880_uniwill_p53_unsol_event
,
3821 .init_hook
= alc880_uniwill_p53_hp_automute
,
3824 .mixers
= { alc880_three_stack_mixer
},
3825 .init_verbs
= { alc880_volume_init_verbs
,
3826 alc880_pin_clevo_init_verbs
},
3827 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3828 .dac_nids
= alc880_dac_nids
,
3830 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
3831 .channel_mode
= alc880_threestack_modes
,
3833 .input_mux
= &alc880_capture_source
,
3836 .mixers
= { alc880_lg_mixer
},
3837 .init_verbs
= { alc880_volume_init_verbs
,
3838 alc880_lg_init_verbs
},
3839 .num_dacs
= ARRAY_SIZE(alc880_lg_dac_nids
),
3840 .dac_nids
= alc880_lg_dac_nids
,
3841 .dig_out_nid
= ALC880_DIGOUT_NID
,
3842 .num_channel_mode
= ARRAY_SIZE(alc880_lg_ch_modes
),
3843 .channel_mode
= alc880_lg_ch_modes
,
3845 .input_mux
= &alc880_lg_capture_source
,
3846 .unsol_event
= alc880_lg_unsol_event
,
3847 .init_hook
= alc880_lg_automute
,
3848 #ifdef CONFIG_SND_HDA_POWER_SAVE
3849 .loopbacks
= alc880_lg_loopbacks
,
3853 .mixers
= { alc880_lg_lw_mixer
},
3854 .init_verbs
= { alc880_volume_init_verbs
,
3855 alc880_lg_lw_init_verbs
},
3856 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3857 .dac_nids
= alc880_dac_nids
,
3858 .dig_out_nid
= ALC880_DIGOUT_NID
,
3859 .num_channel_mode
= ARRAY_SIZE(alc880_lg_lw_modes
),
3860 .channel_mode
= alc880_lg_lw_modes
,
3861 .input_mux
= &alc880_lg_lw_capture_source
,
3862 .unsol_event
= alc880_lg_lw_unsol_event
,
3863 .init_hook
= alc880_lg_lw_automute
,
3865 [ALC880_MEDION_RIM
] = {
3866 .mixers
= { alc880_medion_rim_mixer
},
3867 .init_verbs
= { alc880_volume_init_verbs
,
3868 alc880_medion_rim_init_verbs
,
3869 alc_gpio2_init_verbs
},
3870 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
3871 .dac_nids
= alc880_dac_nids
,
3872 .dig_out_nid
= ALC880_DIGOUT_NID
,
3873 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
3874 .channel_mode
= alc880_2_jack_modes
,
3875 .input_mux
= &alc880_medion_rim_capture_source
,
3876 .unsol_event
= alc880_medion_rim_unsol_event
,
3877 .init_hook
= alc880_medion_rim_automute
,
3879 #ifdef CONFIG_SND_DEBUG
3881 .mixers
= { alc880_test_mixer
},
3882 .init_verbs
= { alc880_test_init_verbs
},
3883 .num_dacs
= ARRAY_SIZE(alc880_test_dac_nids
),
3884 .dac_nids
= alc880_test_dac_nids
,
3885 .dig_out_nid
= ALC880_DIGOUT_NID
,
3886 .num_channel_mode
= ARRAY_SIZE(alc880_test_modes
),
3887 .channel_mode
= alc880_test_modes
,
3888 .input_mux
= &alc880_test_capture_source
,
3894 * Automatic parse of I/O pins from the BIOS configuration
3899 ALC_CTL_WIDGET_MUTE
,
3902 static struct snd_kcontrol_new alc880_control_templates
[] = {
3903 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
3904 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
3905 HDA_BIND_MUTE(NULL
, 0, 0, 0),
3908 /* add dynamic controls */
3909 static int add_control(struct alc_spec
*spec
, int type
, const char *name
,
3912 struct snd_kcontrol_new
*knew
;
3914 snd_array_init(&spec
->kctls
, sizeof(*knew
), 32);
3915 knew
= snd_array_new(&spec
->kctls
);
3918 *knew
= alc880_control_templates
[type
];
3919 knew
->name
= kstrdup(name
, GFP_KERNEL
);
3922 knew
->private_value
= val
;
3926 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3927 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3928 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3929 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3930 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3931 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3932 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3933 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3934 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3935 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3936 #define ALC880_PIN_CD_NID 0x1c
3938 /* fill in the dac_nids table from the parsed pin configuration */
3939 static int alc880_auto_fill_dac_nids(struct alc_spec
*spec
,
3940 const struct auto_pin_cfg
*cfg
)
3946 memset(assigned
, 0, sizeof(assigned
));
3947 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
3949 /* check the pins hardwired to audio widget */
3950 for (i
= 0; i
< cfg
->line_outs
; i
++) {
3951 nid
= cfg
->line_out_pins
[i
];
3952 if (alc880_is_fixed_pin(nid
)) {
3953 int idx
= alc880_fixed_pin_idx(nid
);
3954 spec
->multiout
.dac_nids
[i
] = alc880_idx_to_dac(idx
);
3958 /* left pins can be connect to any audio widget */
3959 for (i
= 0; i
< cfg
->line_outs
; i
++) {
3960 nid
= cfg
->line_out_pins
[i
];
3961 if (alc880_is_fixed_pin(nid
))
3963 /* search for an empty channel */
3964 for (j
= 0; j
< cfg
->line_outs
; j
++) {
3966 spec
->multiout
.dac_nids
[i
] =
3967 alc880_idx_to_dac(j
);
3973 spec
->multiout
.num_dacs
= cfg
->line_outs
;
3977 /* add playback controls from the parsed DAC table */
3978 static int alc880_auto_create_multi_out_ctls(struct alc_spec
*spec
,
3979 const struct auto_pin_cfg
*cfg
)
3982 static const char *chname
[4] = {
3983 "Front", "Surround", NULL
/*CLFE*/, "Side"
3988 for (i
= 0; i
< cfg
->line_outs
; i
++) {
3989 if (!spec
->multiout
.dac_nids
[i
])
3991 nid
= alc880_idx_to_mixer(alc880_dac_to_idx(spec
->multiout
.dac_nids
[i
]));
3994 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
3995 "Center Playback Volume",
3996 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
4000 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
4001 "LFE Playback Volume",
4002 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
4006 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
4007 "Center Playback Switch",
4008 HDA_COMPOSE_AMP_VAL(nid
, 1, 2,
4012 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
4013 "LFE Playback Switch",
4014 HDA_COMPOSE_AMP_VAL(nid
, 2, 2,
4019 sprintf(name
, "%s Playback Volume", chname
[i
]);
4020 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
4021 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
4025 sprintf(name
, "%s Playback Switch", chname
[i
]);
4026 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
4027 HDA_COMPOSE_AMP_VAL(nid
, 3, 2,
4036 /* add playback controls for speaker and HP outputs */
4037 static int alc880_auto_create_extra_out(struct alc_spec
*spec
, hda_nid_t pin
,
4047 if (alc880_is_fixed_pin(pin
)) {
4048 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
4049 /* specify the DAC as the extra output */
4050 if (!spec
->multiout
.hp_nid
)
4051 spec
->multiout
.hp_nid
= nid
;
4053 spec
->multiout
.extra_out_nid
[0] = nid
;
4054 /* control HP volume/switch on the output mixer amp */
4055 nid
= alc880_idx_to_mixer(alc880_fixed_pin_idx(pin
));
4056 sprintf(name
, "%s Playback Volume", pfx
);
4057 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
4058 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
4061 sprintf(name
, "%s Playback Switch", pfx
);
4062 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
4063 HDA_COMPOSE_AMP_VAL(nid
, 3, 2, HDA_INPUT
));
4066 } else if (alc880_is_multi_pin(pin
)) {
4067 /* set manual connection */
4068 /* we have only a switch on HP-out PIN */
4069 sprintf(name
, "%s Playback Switch", pfx
);
4070 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
4071 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
4078 /* create input playback/capture controls for the given pin */
4079 static int new_analog_input(struct alc_spec
*spec
, hda_nid_t pin
,
4080 const char *ctlname
,
4081 int idx
, hda_nid_t mix_nid
)
4086 sprintf(name
, "%s Playback Volume", ctlname
);
4087 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
4088 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
4091 sprintf(name
, "%s Playback Switch", ctlname
);
4092 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
4093 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
4099 /* create playback/capture controls for input pins */
4100 static int alc880_auto_create_analog_input_ctls(struct alc_spec
*spec
,
4101 const struct auto_pin_cfg
*cfg
)
4103 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
4106 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
4107 if (alc880_is_input_pin(cfg
->input_pins
[i
])) {
4108 idx
= alc880_input_pin_idx(cfg
->input_pins
[i
]);
4109 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
4110 auto_pin_cfg_labels
[i
],
4114 imux
->items
[imux
->num_items
].label
=
4115 auto_pin_cfg_labels
[i
];
4116 imux
->items
[imux
->num_items
].index
=
4117 alc880_input_pin_idx(cfg
->input_pins
[i
]);
4124 static void alc_set_pin_output(struct hda_codec
*codec
, hda_nid_t nid
,
4125 unsigned int pin_type
)
4127 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4130 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
4134 static void alc880_auto_set_output_and_unmute(struct hda_codec
*codec
,
4135 hda_nid_t nid
, int pin_type
,
4138 alc_set_pin_output(codec
, nid
, pin_type
);
4139 /* need the manual connection? */
4140 if (alc880_is_multi_pin(nid
)) {
4141 struct alc_spec
*spec
= codec
->spec
;
4142 int idx
= alc880_multi_pin_idx(nid
);
4143 snd_hda_codec_write(codec
, alc880_idx_to_selector(idx
), 0,
4144 AC_VERB_SET_CONNECT_SEL
,
4145 alc880_dac_to_idx(spec
->multiout
.dac_nids
[dac_idx
]));
4149 static int get_pin_type(int line_out_type
)
4151 if (line_out_type
== AUTO_PIN_HP_OUT
)
4157 static void alc880_auto_init_multi_out(struct hda_codec
*codec
)
4159 struct alc_spec
*spec
= codec
->spec
;
4162 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
4163 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
4164 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
4165 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
4166 alc880_auto_set_output_and_unmute(codec
, nid
, pin_type
, i
);
4170 static void alc880_auto_init_extra_out(struct hda_codec
*codec
)
4172 struct alc_spec
*spec
= codec
->spec
;
4175 pin
= spec
->autocfg
.speaker_pins
[0];
4176 if (pin
) /* connect to front */
4177 alc880_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
4178 pin
= spec
->autocfg
.hp_pins
[0];
4179 if (pin
) /* connect to front */
4180 alc880_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
4183 static void alc880_auto_init_analog_input(struct hda_codec
*codec
)
4185 struct alc_spec
*spec
= codec
->spec
;
4188 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
4189 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
4190 if (alc880_is_input_pin(nid
)) {
4191 snd_hda_codec_write(codec
, nid
, 0,
4192 AC_VERB_SET_PIN_WIDGET_CONTROL
,
4193 i
<= AUTO_PIN_FRONT_MIC
?
4194 PIN_VREF80
: PIN_IN
);
4195 if (nid
!= ALC880_PIN_CD_NID
)
4196 snd_hda_codec_write(codec
, nid
, 0,
4197 AC_VERB_SET_AMP_GAIN_MUTE
,
4203 /* parse the BIOS configuration and set up the alc_spec */
4204 /* return 1 if successful, 0 if the proper config is not found,
4205 * or a negative error code
4207 static int alc880_parse_auto_config(struct hda_codec
*codec
)
4209 struct alc_spec
*spec
= codec
->spec
;
4211 static hda_nid_t alc880_ignore
[] = { 0x1d, 0 };
4213 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
4217 if (!spec
->autocfg
.line_outs
)
4218 return 0; /* can't find valid BIOS pin config */
4220 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
4223 err
= alc880_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
4226 err
= alc880_auto_create_extra_out(spec
,
4227 spec
->autocfg
.speaker_pins
[0],
4231 err
= alc880_auto_create_extra_out(spec
, spec
->autocfg
.hp_pins
[0],
4235 err
= alc880_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
4239 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
4241 /* check multiple SPDIF-out (for recent codecs) */
4242 for (i
= 0; i
< spec
->autocfg
.dig_outs
; i
++) {
4244 err
= snd_hda_get_connections(codec
,
4245 spec
->autocfg
.dig_out_pins
[i
],
4250 spec
->multiout
.dig_out_nid
= dig_nid
;
4252 spec
->multiout
.slave_dig_outs
= spec
->slave_dig_outs
;
4253 spec
->slave_dig_outs
[i
- 1] = dig_nid
;
4254 if (i
== ARRAY_SIZE(spec
->slave_dig_outs
) - 1)
4258 if (spec
->autocfg
.dig_in_pin
)
4259 spec
->dig_in_nid
= ALC880_DIGIN_NID
;
4261 if (spec
->kctls
.list
)
4262 add_mixer(spec
, spec
->kctls
.list
);
4264 add_verb(spec
, alc880_volume_init_verbs
);
4266 spec
->num_mux_defs
= 1;
4267 spec
->input_mux
= &spec
->private_imux
[0];
4272 /* additional initialization for auto-configuration model */
4273 static void alc880_auto_init(struct hda_codec
*codec
)
4275 struct alc_spec
*spec
= codec
->spec
;
4276 alc880_auto_init_multi_out(codec
);
4277 alc880_auto_init_extra_out(codec
);
4278 alc880_auto_init_analog_input(codec
);
4279 if (spec
->unsol_event
)
4280 alc_inithook(codec
);
4283 static void set_capture_mixer(struct alc_spec
*spec
)
4285 static struct snd_kcontrol_new
*caps
[3] = {
4290 if (spec
->num_adc_nids
> 0 && spec
->num_adc_nids
<= 3)
4291 spec
->cap_mixer
= caps
[spec
->num_adc_nids
- 1];
4294 #define set_beep_amp(spec, nid, idx, dir) \
4295 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4298 * OK, here we have finally the patch for ALC880
4301 static int patch_alc880(struct hda_codec
*codec
)
4303 struct alc_spec
*spec
;
4307 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
4313 board_config
= snd_hda_check_board_config(codec
, ALC880_MODEL_LAST
,
4316 if (board_config
< 0) {
4317 printk(KERN_INFO
"hda_codec: Unknown model for ALC880, "
4318 "trying auto-probe from BIOS...\n");
4319 board_config
= ALC880_AUTO
;
4322 if (board_config
== ALC880_AUTO
) {
4323 /* automatic parse from the BIOS config */
4324 err
= alc880_parse_auto_config(codec
);
4330 "hda_codec: Cannot set up configuration "
4331 "from BIOS. Using 3-stack mode...\n");
4332 board_config
= ALC880_3ST
;
4336 err
= snd_hda_attach_beep_device(codec
, 0x1);
4342 if (board_config
!= ALC880_AUTO
)
4343 setup_preset(spec
, &alc880_presets
[board_config
]);
4345 spec
->stream_name_analog
= "ALC880 Analog";
4346 spec
->stream_analog_playback
= &alc880_pcm_analog_playback
;
4347 spec
->stream_analog_capture
= &alc880_pcm_analog_capture
;
4348 spec
->stream_analog_alt_capture
= &alc880_pcm_analog_alt_capture
;
4350 spec
->stream_name_digital
= "ALC880 Digital";
4351 spec
->stream_digital_playback
= &alc880_pcm_digital_playback
;
4352 spec
->stream_digital_capture
= &alc880_pcm_digital_capture
;
4354 if (!spec
->adc_nids
&& spec
->input_mux
) {
4355 /* check whether NID 0x07 is valid */
4356 unsigned int wcap
= get_wcaps(codec
, alc880_adc_nids
[0]);
4358 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
4359 if (wcap
!= AC_WID_AUD_IN
) {
4360 spec
->adc_nids
= alc880_adc_nids_alt
;
4361 spec
->num_adc_nids
= ARRAY_SIZE(alc880_adc_nids_alt
);
4363 spec
->adc_nids
= alc880_adc_nids
;
4364 spec
->num_adc_nids
= ARRAY_SIZE(alc880_adc_nids
);
4367 set_capture_mixer(spec
);
4368 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
4370 spec
->vmaster_nid
= 0x0c;
4372 codec
->patch_ops
= alc_patch_ops
;
4373 if (board_config
== ALC880_AUTO
)
4374 spec
->init_hook
= alc880_auto_init
;
4375 #ifdef CONFIG_SND_HDA_POWER_SAVE
4376 if (!spec
->loopback
.amplist
)
4377 spec
->loopback
.amplist
= alc880_loopbacks
;
4379 codec
->proc_widget_hook
= print_realtek_coef
;
4389 static hda_nid_t alc260_dac_nids
[1] = {
4394 static hda_nid_t alc260_adc_nids
[1] = {
4399 static hda_nid_t alc260_adc_nids_alt
[1] = {
4404 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4405 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4407 static hda_nid_t alc260_dual_adc_nids
[2] = {
4412 #define ALC260_DIGOUT_NID 0x03
4413 #define ALC260_DIGIN_NID 0x06
4415 static struct hda_input_mux alc260_capture_source
= {
4419 { "Front Mic", 0x1 },
4425 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4426 * headphone jack and the internal CD lines since these are the only pins at
4427 * which audio can appear. For flexibility, also allow the option of
4428 * recording the mixer output on the second ADC (ADC0 doesn't have a
4429 * connection to the mixer output).
4431 static struct hda_input_mux alc260_fujitsu_capture_sources
[2] = {
4435 { "Mic/Line", 0x0 },
4437 { "Headphone", 0x2 },
4443 { "Mic/Line", 0x0 },
4445 { "Headphone", 0x2 },
4452 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4453 * the Fujitsu S702x, but jacks are marked differently.
4455 static struct hda_input_mux alc260_acer_capture_sources
[2] = {
4462 { "Headphone", 0x5 },
4471 { "Headphone", 0x6 },
4477 /* Maxdata Favorit 100XS */
4478 static struct hda_input_mux alc260_favorit100_capture_sources
[2] = {
4482 { "Line/Mic", 0x0 },
4489 { "Line/Mic", 0x0 },
4497 * This is just place-holder, so there's something for alc_build_pcms to look
4498 * at when it calculates the maximum number of channels. ALC260 has no mixer
4499 * element which allows changing the channel mode, so the verb list is
4502 static struct hda_channel_mode alc260_modes
[1] = {
4507 /* Mixer combinations
4509 * basic: base_output + input + pc_beep + capture
4510 * HP: base_output + input + capture_alt
4511 * HP_3013: hp_3013 + input + capture
4512 * fujitsu: fujitsu + capture
4513 * acer: acer + capture
4516 static struct snd_kcontrol_new alc260_base_output_mixer
[] = {
4517 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4518 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT
),
4519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
4520 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT
),
4521 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
4522 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT
),
4526 static struct snd_kcontrol_new alc260_input_mixer
[] = {
4527 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
4528 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
4529 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
4530 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
4531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
4532 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
4533 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT
),
4534 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT
),
4538 /* update HP, line and mono out pins according to the master switch */
4539 static void alc260_hp_master_update(struct hda_codec
*codec
,
4540 hda_nid_t hp
, hda_nid_t line
,
4543 struct alc_spec
*spec
= codec
->spec
;
4544 unsigned int val
= spec
->master_sw
? PIN_HP
: 0;
4545 /* change HP and line-out pins */
4546 snd_hda_codec_write(codec
, hp
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4548 snd_hda_codec_write(codec
, line
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4550 /* mono (speaker) depending on the HP jack sense */
4551 val
= (val
&& !spec
->jack_present
) ? PIN_OUT
: 0;
4552 snd_hda_codec_write(codec
, mono
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4556 static int alc260_hp_master_sw_get(struct snd_kcontrol
*kcontrol
,
4557 struct snd_ctl_elem_value
*ucontrol
)
4559 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
4560 struct alc_spec
*spec
= codec
->spec
;
4561 *ucontrol
->value
.integer
.value
= spec
->master_sw
;
4565 static int alc260_hp_master_sw_put(struct snd_kcontrol
*kcontrol
,
4566 struct snd_ctl_elem_value
*ucontrol
)
4568 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
4569 struct alc_spec
*spec
= codec
->spec
;
4570 int val
= !!*ucontrol
->value
.integer
.value
;
4571 hda_nid_t hp
, line
, mono
;
4573 if (val
== spec
->master_sw
)
4575 spec
->master_sw
= val
;
4576 hp
= (kcontrol
->private_value
>> 16) & 0xff;
4577 line
= (kcontrol
->private_value
>> 8) & 0xff;
4578 mono
= kcontrol
->private_value
& 0xff;
4579 alc260_hp_master_update(codec
, hp
, line
, mono
);
4583 static struct snd_kcontrol_new alc260_hp_output_mixer
[] = {
4585 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
4586 .name
= "Master Playback Switch",
4587 .info
= snd_ctl_boolean_mono_info
,
4588 .get
= alc260_hp_master_sw_get
,
4589 .put
= alc260_hp_master_sw_put
,
4590 .private_value
= (0x0f << 16) | (0x10 << 8) | 0x11
4592 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4593 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT
),
4594 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
4595 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT
),
4596 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4598 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT
),
4602 static struct hda_verb alc260_hp_unsol_verbs
[] = {
4603 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
4607 static void alc260_hp_automute(struct hda_codec
*codec
)
4609 struct alc_spec
*spec
= codec
->spec
;
4610 unsigned int present
;
4612 present
= snd_hda_codec_read(codec
, 0x10, 0,
4613 AC_VERB_GET_PIN_SENSE
, 0);
4614 spec
->jack_present
= (present
& AC_PINSENSE_PRESENCE
) != 0;
4615 alc260_hp_master_update(codec
, 0x0f, 0x10, 0x11);
4618 static void alc260_hp_unsol_event(struct hda_codec
*codec
, unsigned int res
)
4620 if ((res
>> 26) == ALC880_HP_EVENT
)
4621 alc260_hp_automute(codec
);
4624 static struct snd_kcontrol_new alc260_hp_3013_mixer
[] = {
4626 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
4627 .name
= "Master Playback Switch",
4628 .info
= snd_ctl_boolean_mono_info
,
4629 .get
= alc260_hp_master_sw_get
,
4630 .put
= alc260_hp_master_sw_put
,
4631 .private_value
= (0x15 << 16) | (0x10 << 8) | 0x11
4633 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
4634 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT
),
4635 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT
),
4636 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT
),
4637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
4639 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
4640 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT
),
4644 static struct hda_bind_ctls alc260_dc7600_bind_master_vol
= {
4645 .ops
= &snd_hda_bind_vol
,
4647 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT
),
4648 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT
),
4649 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT
),
4654 static struct hda_bind_ctls alc260_dc7600_bind_switch
= {
4655 .ops
= &snd_hda_bind_sw
,
4657 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT
),
4658 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
4663 static struct snd_kcontrol_new alc260_hp_dc7600_mixer
[] = {
4664 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol
),
4665 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch
),
4666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT
),
4667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT
),
4671 static struct hda_verb alc260_hp_3013_unsol_verbs
[] = {
4672 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
4676 static void alc260_hp_3013_automute(struct hda_codec
*codec
)
4678 struct alc_spec
*spec
= codec
->spec
;
4679 unsigned int present
;
4681 present
= snd_hda_codec_read(codec
, 0x15, 0,
4682 AC_VERB_GET_PIN_SENSE
, 0);
4683 spec
->jack_present
= (present
& AC_PINSENSE_PRESENCE
) != 0;
4684 alc260_hp_master_update(codec
, 0x15, 0x10, 0x11);
4687 static void alc260_hp_3013_unsol_event(struct hda_codec
*codec
,
4690 if ((res
>> 26) == ALC880_HP_EVENT
)
4691 alc260_hp_3013_automute(codec
);
4694 static void alc260_hp_3012_automute(struct hda_codec
*codec
)
4696 unsigned int present
, bits
;
4698 present
= snd_hda_codec_read(codec
, 0x10, 0,
4699 AC_VERB_GET_PIN_SENSE
, 0) & AC_PINSENSE_PRESENCE
;
4701 bits
= present
? 0 : PIN_OUT
;
4702 snd_hda_codec_write(codec
, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4704 snd_hda_codec_write(codec
, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4706 snd_hda_codec_write(codec
, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4710 static void alc260_hp_3012_unsol_event(struct hda_codec
*codec
,
4713 if ((res
>> 26) == ALC880_HP_EVENT
)
4714 alc260_hp_3012_automute(codec
);
4717 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4718 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4720 static struct snd_kcontrol_new alc260_fujitsu_mixer
[] = {
4721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4722 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT
),
4723 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
4724 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
4725 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
4726 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT
),
4727 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT
),
4728 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN
),
4729 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
4730 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT
),
4734 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4735 * versions of the ALC260 don't act on requests to enable mic bias from NID
4736 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4737 * datasheet doesn't mention this restriction. At this stage it's not clear
4738 * whether this behaviour is intentional or is a hardware bug in chip
4739 * revisions available in early 2006. Therefore for now allow the
4740 * "Headphone Jack Mode" control to span all choices, but if it turns out
4741 * that the lack of mic bias for this NID is intentional we could change the
4742 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4744 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4745 * don't appear to make the mic bias available from the "line" jack, even
4746 * though the NID used for this jack (0x14) can supply it. The theory is
4747 * that perhaps Acer have included blocking capacitors between the ALC260
4748 * and the output jack. If this turns out to be the case for all such
4749 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4750 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4752 * The C20x Tablet series have a mono internal speaker which is controlled
4753 * via the chip's Mono sum widget and pin complex, so include the necessary
4754 * controls for such models. On models without a "mono speaker" the control
4755 * won't do anything.
4757 static struct snd_kcontrol_new alc260_acer_mixer
[] = {
4758 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4759 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT
),
4760 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT
),
4761 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4763 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4765 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
4766 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
4767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
4768 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
4769 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
4770 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
4771 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
4772 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
4776 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
4778 static struct snd_kcontrol_new alc260_favorit100_mixer
[] = {
4779 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4780 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT
),
4781 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT
),
4782 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
4783 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
4784 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
4788 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4789 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4791 static struct snd_kcontrol_new alc260_will_mixer
[] = {
4792 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4793 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT
),
4794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
4795 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
4796 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
4797 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
4798 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
4799 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
4800 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
4801 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
4805 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4806 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4808 static struct snd_kcontrol_new alc260_replacer_672v_mixer
[] = {
4809 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4810 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT
),
4811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
4812 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
4813 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
4814 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT
),
4815 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT
),
4816 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
4817 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
4818 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
4823 * initialization verbs
4825 static struct hda_verb alc260_init_verbs
[] = {
4826 /* Line In pin widget for input */
4827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
4828 /* CD pin widget for input */
4829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
4830 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4831 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
4832 /* Mic2 (front panel) pin widget for input and vref at 80% */
4833 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
4834 /* LINE-2 is used for line-out in rear */
4835 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4836 /* select line-out */
4837 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00},
4839 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4841 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
4843 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4844 /* mute capture amp left and right */
4845 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4846 /* set connection select to line in (default select for this ADC) */
4847 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
4848 /* mute capture amp left and right */
4849 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4850 /* set connection select to line in (default select for this ADC) */
4851 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x02},
4852 /* set vol=0 Line-Out mixer amp left and right */
4853 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4854 /* unmute pin widget amp left and right (no gain on this amp) */
4855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4856 /* set vol=0 HP mixer amp left and right */
4857 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4858 /* unmute pin widget amp left and right (no gain on this amp) */
4859 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4860 /* set vol=0 Mono mixer amp left and right */
4861 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4862 /* unmute pin widget amp left and right (no gain on this amp) */
4863 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4864 /* unmute LINE-2 out pin */
4865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4866 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4869 /* mute analog inputs */
4870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4875 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4876 /* mute Front out path */
4877 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4878 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4879 /* mute Headphone out path */
4880 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4882 /* mute Mono out path */
4883 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4884 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4888 #if 0 /* should be identical with alc260_init_verbs? */
4889 static struct hda_verb alc260_hp_init_verbs
[] = {
4890 /* Headphone and output */
4891 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
4893 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
4894 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4895 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
4896 /* Mic2 (front panel) pin widget for input and vref at 80% */
4897 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
4898 /* Line In pin widget for input */
4899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
4900 /* Line-2 pin widget for output */
4901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
4902 /* CD pin widget for input */
4903 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
4904 /* unmute amp left and right */
4905 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000},
4906 /* set connection select to line in (default select for this ADC) */
4907 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
4908 /* unmute Line-Out mixer amp left and right (volume = 0) */
4909 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
4910 /* mute pin widget amp left and right (no gain on this amp) */
4911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
4912 /* unmute HP mixer amp left and right (volume = 0) */
4913 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
4914 /* mute pin widget amp left and right (no gain on this amp) */
4915 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
4916 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4919 /* mute analog inputs */
4920 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4921 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4922 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4924 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4925 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4926 /* Unmute Front out path */
4927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4928 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4929 /* Unmute Headphone out path */
4930 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4931 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4932 /* Unmute Mono out path */
4933 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4934 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4939 static struct hda_verb alc260_hp_3013_init_verbs
[] = {
4940 /* Line out and output */
4941 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
4943 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
4944 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4945 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
4946 /* Mic2 (front panel) pin widget for input and vref at 80% */
4947 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
4948 /* Line In pin widget for input */
4949 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
4950 /* Headphone pin widget for output */
4951 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
4952 /* CD pin widget for input */
4953 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
4954 /* unmute amp left and right */
4955 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000},
4956 /* set connection select to line in (default select for this ADC) */
4957 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
4958 /* unmute Line-Out mixer amp left and right (volume = 0) */
4959 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
4960 /* mute pin widget amp left and right (no gain on this amp) */
4961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
4962 /* unmute HP mixer amp left and right (volume = 0) */
4963 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
4964 /* mute pin widget amp left and right (no gain on this amp) */
4965 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
4966 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4969 /* mute analog inputs */
4970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4975 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4976 /* Unmute Front out path */
4977 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4978 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4979 /* Unmute Headphone out path */
4980 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4982 /* Unmute Mono out path */
4983 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
4984 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
4988 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4989 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4990 * audio = 0x16, internal speaker = 0x10.
4992 static struct hda_verb alc260_fujitsu_init_verbs
[] = {
4993 /* Disable all GPIOs */
4994 {0x01, AC_VERB_SET_GPIO_MASK
, 0},
4995 /* Internal speaker is connected to headphone pin */
4996 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
4997 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4998 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4999 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5000 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
5001 /* Ensure all other unused pins are disabled and muted. */
5002 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5004 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5005 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5006 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5007 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5008 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5009 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5011 /* Disable digital (SPDIF) pins */
5012 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5013 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5015 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5016 * when acting as an output.
5018 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
5020 /* Start with output sum widgets muted and their output gains at min */
5021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5023 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5024 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5025 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5026 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5027 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5028 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5029 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5031 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5032 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5033 /* Unmute Line1 pin widget output buffer since it starts as an output.
5034 * If the pin mode is changed by the user the pin mode control will
5035 * take care of enabling the pin's input/output buffers as needed.
5036 * Therefore there's no need to enable the input buffer at this
5039 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5040 /* Unmute input buffer of pin widget used for Line-in (no equiv
5043 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5045 /* Mute capture amp left and right */
5046 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5047 /* Set ADC connection select to match default mixer setting - line
5050 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
5052 /* Do the same for the second ADC: mute capture input amp and
5053 * set ADC connection to line in (on mic1 pin)
5055 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5056 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
5058 /* Mute all inputs to mixer widget (even unconnected ones) */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
5063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
5064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
5066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
5071 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5072 * similar laptops (adapted from Fujitsu init verbs).
5074 static struct hda_verb alc260_acer_init_verbs
[] = {
5075 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5076 * the headphone jack. Turn this on and rely on the standard mute
5077 * methods whenever the user wants to turn these outputs off.
5079 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
5080 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
5081 {0x01, AC_VERB_SET_GPIO_DATA
, 0x01},
5082 /* Internal speaker/Headphone jack is connected to Line-out pin */
5083 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5084 /* Internal microphone/Mic jack is connected to Mic1 pin */
5085 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
5086 /* Line In jack is connected to Line1 pin */
5087 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
5088 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5089 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5090 /* Ensure all other unused pins are disabled and muted. */
5091 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5092 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5093 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5094 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5095 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5096 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5097 /* Disable digital (SPDIF) pins */
5098 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5099 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5101 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5102 * bus when acting as outputs.
5104 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0},
5105 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
5107 /* Start with output sum widgets muted and their output gains at min */
5108 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5109 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5110 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5111 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5112 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5113 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5114 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5115 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5116 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5118 /* Unmute Line-out pin widget amp left and right
5119 * (no equiv mixer ctrl)
5121 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5122 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5123 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5124 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5125 * inputs. If the pin mode is changed by the user the pin mode control
5126 * will take care of enabling the pin's input/output buffers as needed.
5127 * Therefore there's no need to enable the input buffer at this
5130 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5131 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5133 /* Mute capture amp left and right */
5134 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5135 /* Set ADC connection select to match default mixer setting - mic
5138 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
5140 /* Do similar with the second ADC: mute capture input amp and
5141 * set ADC connection to mic to match ALSA's default state.
5143 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5144 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
5146 /* Mute all inputs to mixer widget (even unconnected ones) */
5147 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
5148 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
5149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
5150 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
5151 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
5152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
5154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
5159 /* Initialisation sequence for Maxdata Favorit 100XS
5160 * (adapted from Acer init verbs).
5162 static struct hda_verb alc260_favorit100_init_verbs
[] = {
5163 /* GPIO 0 enables the output jack.
5164 * Turn this on and rely on the standard mute
5165 * methods whenever the user wants to turn these outputs off.
5167 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
5168 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
5169 {0x01, AC_VERB_SET_GPIO_DATA
, 0x01},
5170 /* Line/Mic input jack is connected to Mic1 pin */
5171 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
5172 /* Ensure all other unused pins are disabled and muted. */
5173 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5174 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5175 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5176 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5177 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5178 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5179 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5180 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5181 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
5182 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5183 /* Disable digital (SPDIF) pins */
5184 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5185 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5187 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5188 * bus when acting as outputs.
5190 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0},
5191 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
5193 /* Start with output sum widgets muted and their output gains at min */
5194 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5195 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5197 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5198 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5199 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5200 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5201 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5202 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5204 /* Unmute Line-out pin widget amp left and right
5205 * (no equiv mixer ctrl)
5207 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5208 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5209 * inputs. If the pin mode is changed by the user the pin mode control
5210 * will take care of enabling the pin's input/output buffers as needed.
5211 * Therefore there's no need to enable the input buffer at this
5214 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5216 /* Mute capture amp left and right */
5217 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5218 /* Set ADC connection select to match default mixer setting - mic
5221 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
5223 /* Do similar with the second ADC: mute capture input amp and
5224 * set ADC connection to mic to match ALSA's default state.
5226 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5227 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
5229 /* Mute all inputs to mixer widget (even unconnected ones) */
5230 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
5231 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
5232 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
5233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
5234 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
5235 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5236 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
5237 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
5242 static struct hda_verb alc260_will_verbs
[] = {
5243 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5244 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00},
5245 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00},
5246 {0x0f, AC_VERB_SET_EAPD_BTLENABLE
, 0x02},
5247 {0x1a, AC_VERB_SET_COEF_INDEX
, 0x07},
5248 {0x1a, AC_VERB_SET_PROC_COEF
, 0x3040},
5252 static struct hda_verb alc260_replacer_672v_verbs
[] = {
5253 {0x0f, AC_VERB_SET_EAPD_BTLENABLE
, 0x02},
5254 {0x1a, AC_VERB_SET_COEF_INDEX
, 0x07},
5255 {0x1a, AC_VERB_SET_PROC_COEF
, 0x3050},
5257 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
5258 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
5259 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
5261 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
5265 /* toggle speaker-output according to the hp-jack state */
5266 static void alc260_replacer_672v_automute(struct hda_codec
*codec
)
5268 unsigned int present
;
5270 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5271 present
= snd_hda_codec_read(codec
, 0x0f, 0,
5272 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
5274 snd_hda_codec_write_cache(codec
, 0x01, 0,
5275 AC_VERB_SET_GPIO_DATA
, 1);
5276 snd_hda_codec_write_cache(codec
, 0x0f, 0,
5277 AC_VERB_SET_PIN_WIDGET_CONTROL
,
5280 snd_hda_codec_write_cache(codec
, 0x01, 0,
5281 AC_VERB_SET_GPIO_DATA
, 0);
5282 snd_hda_codec_write_cache(codec
, 0x0f, 0,
5283 AC_VERB_SET_PIN_WIDGET_CONTROL
,
5288 static void alc260_replacer_672v_unsol_event(struct hda_codec
*codec
,
5291 if ((res
>> 26) == ALC880_HP_EVENT
)
5292 alc260_replacer_672v_automute(codec
);
5295 static struct hda_verb alc260_hp_dc7600_verbs
[] = {
5296 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x01},
5297 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
5298 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5299 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5300 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5301 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5302 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
5303 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
5304 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
5305 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
5309 /* Test configuration for debugging, modelled after the ALC880 test
5312 #ifdef CONFIG_SND_DEBUG
5313 static hda_nid_t alc260_test_dac_nids
[1] = {
5316 static hda_nid_t alc260_test_adc_nids
[2] = {
5319 /* For testing the ALC260, each input MUX needs its own definition since
5320 * the signal assignments are different. This assumes that the first ADC
5323 static struct hda_input_mux alc260_test_capture_sources
[2] = {
5327 { "MIC1 pin", 0x0 },
5328 { "MIC2 pin", 0x1 },
5329 { "LINE1 pin", 0x2 },
5330 { "LINE2 pin", 0x3 },
5332 { "LINE-OUT pin", 0x5 },
5333 { "HP-OUT pin", 0x6 },
5339 { "MIC1 pin", 0x0 },
5340 { "MIC2 pin", 0x1 },
5341 { "LINE1 pin", 0x2 },
5342 { "LINE2 pin", 0x3 },
5345 { "LINE-OUT pin", 0x6 },
5346 { "HP-OUT pin", 0x7 },
5350 static struct snd_kcontrol_new alc260_test_mixer
[] = {
5351 /* Output driver widgets */
5352 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
5353 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT
),
5354 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
5355 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT
),
5356 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
5357 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT
),
5359 /* Modes for retasking pin widgets
5360 * Note: the ALC260 doesn't seem to act on requests to enable mic
5361 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5362 * mention this restriction. At this stage it's not clear whether
5363 * this behaviour is intentional or is a hardware bug in chip
5364 * revisions available at least up until early 2006. Therefore for
5365 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5366 * choices, but if it turns out that the lack of mic bias for these
5367 * NIDs is intentional we could change their modes from
5368 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5370 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT
),
5371 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT
),
5372 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT
),
5373 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT
),
5374 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT
),
5375 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT
),
5377 /* Loopback mixer controls */
5378 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT
),
5379 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT
),
5380 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT
),
5381 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT
),
5382 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT
),
5383 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT
),
5384 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT
),
5385 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT
),
5386 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
5387 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
5388 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT
),
5389 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT
),
5390 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT
),
5391 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT
),
5393 /* Controls for GPIO pins, assuming they are configured as outputs */
5394 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5395 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5396 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5397 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5399 /* Switches to allow the digital IO pins to be enabled. The datasheet
5400 * is ambigious as to which NID is which; testing on laptops which
5401 * make this output available should provide clarification.
5403 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5404 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5406 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5407 * this output to turn on an external amplifier.
5409 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5410 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5414 static struct hda_verb alc260_test_init_verbs
[] = {
5415 /* Enable all GPIOs as outputs with an initial value of 0 */
5416 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x0f},
5417 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
5418 {0x01, AC_VERB_SET_GPIO_MASK
, 0x0f},
5420 /* Enable retasking pins as output, initially without power amp */
5421 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5422 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5425 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5428 /* Disable digital (SPDIF) pins initially, but users can enable
5429 * them via a mixer switch. In the case of SPDIF-out, this initverb
5430 * payload also sets the generation to 0, output to be in "consumer"
5431 * PCM format, copyright asserted, no pre-emphasis and no validity
5434 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5435 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
5437 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5438 * OUT1 sum bus when acting as an output.
5440 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0},
5441 {0x0c, AC_VERB_SET_CONNECT_SEL
, 0},
5442 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
5443 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0},
5445 /* Start with output sum widgets muted and their output gains at min */
5446 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5447 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5450 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5452 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5453 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5454 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5456 /* Unmute retasking pin widget output buffers since the default
5457 * state appears to be output. As the pin mode is changed by the
5458 * user the pin mode control will take care of enabling the pin's
5459 * input/output buffers as needed.
5461 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5463 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5464 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5465 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5466 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5467 /* Also unmute the mono-out pin widget */
5468 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5470 /* Mute capture amp left and right */
5471 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5472 /* Set ADC connection select to match default mixer setting (mic1
5475 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
5477 /* Do the same for the second ADC: mute capture input amp and
5478 * set ADC connection to mic1 pin
5480 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5481 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
5483 /* Mute all inputs to mixer widget (even unconnected ones) */
5484 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
5485 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
5486 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
5487 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
5488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
5489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
5491 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
5497 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5498 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5500 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5501 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5504 * for BIOS auto-configuration
5507 static int alc260_add_playback_controls(struct alc_spec
*spec
, hda_nid_t nid
,
5508 const char *pfx
, int *vol_bits
)
5511 unsigned long vol_val
, sw_val
;
5515 if (nid
>= 0x0f && nid
< 0x11) {
5516 nid_vol
= nid
- 0x7;
5517 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
);
5518 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
);
5519 } else if (nid
== 0x11) {
5520 nid_vol
= nid
- 0x7;
5521 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 2, 0, HDA_OUTPUT
);
5522 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
);
5523 } else if (nid
>= 0x12 && nid
<= 0x15) {
5525 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
);
5526 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
);
5530 if (!(*vol_bits
& (1 << nid_vol
))) {
5531 /* first control for the volume widget */
5532 snprintf(name
, sizeof(name
), "%s Playback Volume", pfx
);
5533 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
, vol_val
);
5536 *vol_bits
|= (1 << nid_vol
);
5538 snprintf(name
, sizeof(name
), "%s Playback Switch", pfx
);
5539 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
, sw_val
);
5545 /* add playback controls from the parsed DAC table */
5546 static int alc260_auto_create_multi_out_ctls(struct alc_spec
*spec
,
5547 const struct auto_pin_cfg
*cfg
)
5553 spec
->multiout
.num_dacs
= 1;
5554 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
5555 spec
->multiout
.dac_nids
[0] = 0x02;
5557 nid
= cfg
->line_out_pins
[0];
5559 err
= alc260_add_playback_controls(spec
, nid
, "Front", &vols
);
5564 nid
= cfg
->speaker_pins
[0];
5566 err
= alc260_add_playback_controls(spec
, nid
, "Speaker", &vols
);
5571 nid
= cfg
->hp_pins
[0];
5573 err
= alc260_add_playback_controls(spec
, nid
, "Headphone",
5581 /* create playback/capture controls for input pins */
5582 static int alc260_auto_create_analog_input_ctls(struct alc_spec
*spec
,
5583 const struct auto_pin_cfg
*cfg
)
5585 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
5588 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
5589 if (cfg
->input_pins
[i
] >= 0x12) {
5590 idx
= cfg
->input_pins
[i
] - 0x12;
5591 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
5592 auto_pin_cfg_labels
[i
], idx
,
5596 imux
->items
[imux
->num_items
].label
=
5597 auto_pin_cfg_labels
[i
];
5598 imux
->items
[imux
->num_items
].index
= idx
;
5601 if (cfg
->input_pins
[i
] >= 0x0f && cfg
->input_pins
[i
] <= 0x10){
5602 idx
= cfg
->input_pins
[i
] - 0x09;
5603 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
5604 auto_pin_cfg_labels
[i
], idx
,
5608 imux
->items
[imux
->num_items
].label
=
5609 auto_pin_cfg_labels
[i
];
5610 imux
->items
[imux
->num_items
].index
= idx
;
5617 static void alc260_auto_set_output_and_unmute(struct hda_codec
*codec
,
5618 hda_nid_t nid
, int pin_type
,
5621 alc_set_pin_output(codec
, nid
, pin_type
);
5622 /* need the manual connection? */
5624 int idx
= nid
- 0x12;
5625 snd_hda_codec_write(codec
, idx
+ 0x0b, 0,
5626 AC_VERB_SET_CONNECT_SEL
, sel_idx
);
5630 static void alc260_auto_init_multi_out(struct hda_codec
*codec
)
5632 struct alc_spec
*spec
= codec
->spec
;
5635 alc_subsystem_id(codec
, 0x10, 0x15, 0x0f);
5636 nid
= spec
->autocfg
.line_out_pins
[0];
5638 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
5639 alc260_auto_set_output_and_unmute(codec
, nid
, pin_type
, 0);
5642 nid
= spec
->autocfg
.speaker_pins
[0];
5644 alc260_auto_set_output_and_unmute(codec
, nid
, PIN_OUT
, 0);
5646 nid
= spec
->autocfg
.hp_pins
[0];
5648 alc260_auto_set_output_and_unmute(codec
, nid
, PIN_HP
, 0);
5651 #define ALC260_PIN_CD_NID 0x16
5652 static void alc260_auto_init_analog_input(struct hda_codec
*codec
)
5654 struct alc_spec
*spec
= codec
->spec
;
5657 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
5658 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
5660 snd_hda_codec_write(codec
, nid
, 0,
5661 AC_VERB_SET_PIN_WIDGET_CONTROL
,
5662 i
<= AUTO_PIN_FRONT_MIC
?
5663 PIN_VREF80
: PIN_IN
);
5664 if (nid
!= ALC260_PIN_CD_NID
)
5665 snd_hda_codec_write(codec
, nid
, 0,
5666 AC_VERB_SET_AMP_GAIN_MUTE
,
5673 * generic initialization of ADC, input mixers and output mixers
5675 static struct hda_verb alc260_volume_init_verbs
[] = {
5677 * Unmute ADC0-1 and set the default input to mic-in
5679 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
5680 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5681 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
5682 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5684 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5686 * Note: PASD motherboards uses the Line In 2 as the input for
5687 * front panel mic (mic 2)
5689 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5690 /* mute analog inputs */
5691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
5694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
5695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
5698 * Set up output mixers (0x08 - 0x0a)
5700 /* set vol=0 to output mixers */
5701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5703 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5704 /* set up input amps for analog loopback */
5705 /* Amp Indices: DAC = 0, mixer = 1 */
5706 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5709 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5716 static int alc260_parse_auto_config(struct hda_codec
*codec
)
5718 struct alc_spec
*spec
= codec
->spec
;
5720 static hda_nid_t alc260_ignore
[] = { 0x17, 0 };
5722 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
5726 err
= alc260_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
5729 if (!spec
->kctls
.list
)
5730 return 0; /* can't find valid BIOS pin config */
5731 err
= alc260_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
5735 spec
->multiout
.max_channels
= 2;
5737 if (spec
->autocfg
.dig_outs
)
5738 spec
->multiout
.dig_out_nid
= ALC260_DIGOUT_NID
;
5739 if (spec
->kctls
.list
)
5740 add_mixer(spec
, spec
->kctls
.list
);
5742 add_verb(spec
, alc260_volume_init_verbs
);
5744 spec
->num_mux_defs
= 1;
5745 spec
->input_mux
= &spec
->private_imux
[0];
5750 /* additional initialization for auto-configuration model */
5751 static void alc260_auto_init(struct hda_codec
*codec
)
5753 struct alc_spec
*spec
= codec
->spec
;
5754 alc260_auto_init_multi_out(codec
);
5755 alc260_auto_init_analog_input(codec
);
5756 if (spec
->unsol_event
)
5757 alc_inithook(codec
);
5760 #ifdef CONFIG_SND_HDA_POWER_SAVE
5761 static struct hda_amp_list alc260_loopbacks
[] = {
5762 { 0x07, HDA_INPUT
, 0 },
5763 { 0x07, HDA_INPUT
, 1 },
5764 { 0x07, HDA_INPUT
, 2 },
5765 { 0x07, HDA_INPUT
, 3 },
5766 { 0x07, HDA_INPUT
, 4 },
5772 * ALC260 configurations
5774 static const char *alc260_models
[ALC260_MODEL_LAST
] = {
5775 [ALC260_BASIC
] = "basic",
5777 [ALC260_HP_3013
] = "hp-3013",
5778 [ALC260_HP_DC7600
] = "hp-dc7600",
5779 [ALC260_FUJITSU_S702X
] = "fujitsu",
5780 [ALC260_ACER
] = "acer",
5781 [ALC260_WILL
] = "will",
5782 [ALC260_REPLACER_672V
] = "replacer",
5783 [ALC260_FAVORIT100
] = "favorit100",
5784 #ifdef CONFIG_SND_DEBUG
5785 [ALC260_TEST
] = "test",
5787 [ALC260_AUTO
] = "auto",
5790 static struct snd_pci_quirk alc260_cfg_tbl
[] = {
5791 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER
),
5792 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER
),
5793 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100
),
5794 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013
),
5795 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013
),
5796 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013
),
5797 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013
),
5798 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600
),
5799 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013
),
5800 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP
),
5801 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP
),
5802 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP
),
5803 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC
),
5804 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC
),
5805 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC
),
5806 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X
),
5807 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC
),
5808 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V
),
5809 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL
),
5813 static struct alc_config_preset alc260_presets
[] = {
5815 .mixers
= { alc260_base_output_mixer
,
5816 alc260_input_mixer
},
5817 .init_verbs
= { alc260_init_verbs
},
5818 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5819 .dac_nids
= alc260_dac_nids
,
5820 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
5821 .adc_nids
= alc260_adc_nids
,
5822 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5823 .channel_mode
= alc260_modes
,
5824 .input_mux
= &alc260_capture_source
,
5827 .mixers
= { alc260_hp_output_mixer
,
5828 alc260_input_mixer
},
5829 .init_verbs
= { alc260_init_verbs
,
5830 alc260_hp_unsol_verbs
},
5831 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5832 .dac_nids
= alc260_dac_nids
,
5833 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids_alt
),
5834 .adc_nids
= alc260_adc_nids_alt
,
5835 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5836 .channel_mode
= alc260_modes
,
5837 .input_mux
= &alc260_capture_source
,
5838 .unsol_event
= alc260_hp_unsol_event
,
5839 .init_hook
= alc260_hp_automute
,
5841 [ALC260_HP_DC7600
] = {
5842 .mixers
= { alc260_hp_dc7600_mixer
,
5843 alc260_input_mixer
},
5844 .init_verbs
= { alc260_init_verbs
,
5845 alc260_hp_dc7600_verbs
},
5846 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5847 .dac_nids
= alc260_dac_nids
,
5848 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids_alt
),
5849 .adc_nids
= alc260_adc_nids_alt
,
5850 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5851 .channel_mode
= alc260_modes
,
5852 .input_mux
= &alc260_capture_source
,
5853 .unsol_event
= alc260_hp_3012_unsol_event
,
5854 .init_hook
= alc260_hp_3012_automute
,
5856 [ALC260_HP_3013
] = {
5857 .mixers
= { alc260_hp_3013_mixer
,
5858 alc260_input_mixer
},
5859 .init_verbs
= { alc260_hp_3013_init_verbs
,
5860 alc260_hp_3013_unsol_verbs
},
5861 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5862 .dac_nids
= alc260_dac_nids
,
5863 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids_alt
),
5864 .adc_nids
= alc260_adc_nids_alt
,
5865 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5866 .channel_mode
= alc260_modes
,
5867 .input_mux
= &alc260_capture_source
,
5868 .unsol_event
= alc260_hp_3013_unsol_event
,
5869 .init_hook
= alc260_hp_3013_automute
,
5871 [ALC260_FUJITSU_S702X
] = {
5872 .mixers
= { alc260_fujitsu_mixer
},
5873 .init_verbs
= { alc260_fujitsu_init_verbs
},
5874 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5875 .dac_nids
= alc260_dac_nids
,
5876 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
5877 .adc_nids
= alc260_dual_adc_nids
,
5878 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5879 .channel_mode
= alc260_modes
,
5880 .num_mux_defs
= ARRAY_SIZE(alc260_fujitsu_capture_sources
),
5881 .input_mux
= alc260_fujitsu_capture_sources
,
5884 .mixers
= { alc260_acer_mixer
},
5885 .init_verbs
= { alc260_acer_init_verbs
},
5886 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5887 .dac_nids
= alc260_dac_nids
,
5888 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
5889 .adc_nids
= alc260_dual_adc_nids
,
5890 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5891 .channel_mode
= alc260_modes
,
5892 .num_mux_defs
= ARRAY_SIZE(alc260_acer_capture_sources
),
5893 .input_mux
= alc260_acer_capture_sources
,
5895 [ALC260_FAVORIT100
] = {
5896 .mixers
= { alc260_favorit100_mixer
},
5897 .init_verbs
= { alc260_favorit100_init_verbs
},
5898 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5899 .dac_nids
= alc260_dac_nids
,
5900 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
5901 .adc_nids
= alc260_dual_adc_nids
,
5902 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5903 .channel_mode
= alc260_modes
,
5904 .num_mux_defs
= ARRAY_SIZE(alc260_favorit100_capture_sources
),
5905 .input_mux
= alc260_favorit100_capture_sources
,
5908 .mixers
= { alc260_will_mixer
},
5909 .init_verbs
= { alc260_init_verbs
, alc260_will_verbs
},
5910 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5911 .dac_nids
= alc260_dac_nids
,
5912 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
),
5913 .adc_nids
= alc260_adc_nids
,
5914 .dig_out_nid
= ALC260_DIGOUT_NID
,
5915 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5916 .channel_mode
= alc260_modes
,
5917 .input_mux
= &alc260_capture_source
,
5919 [ALC260_REPLACER_672V
] = {
5920 .mixers
= { alc260_replacer_672v_mixer
},
5921 .init_verbs
= { alc260_init_verbs
, alc260_replacer_672v_verbs
},
5922 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
5923 .dac_nids
= alc260_dac_nids
,
5924 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
),
5925 .adc_nids
= alc260_adc_nids
,
5926 .dig_out_nid
= ALC260_DIGOUT_NID
,
5927 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5928 .channel_mode
= alc260_modes
,
5929 .input_mux
= &alc260_capture_source
,
5930 .unsol_event
= alc260_replacer_672v_unsol_event
,
5931 .init_hook
= alc260_replacer_672v_automute
,
5933 #ifdef CONFIG_SND_DEBUG
5935 .mixers
= { alc260_test_mixer
},
5936 .init_verbs
= { alc260_test_init_verbs
},
5937 .num_dacs
= ARRAY_SIZE(alc260_test_dac_nids
),
5938 .dac_nids
= alc260_test_dac_nids
,
5939 .num_adc_nids
= ARRAY_SIZE(alc260_test_adc_nids
),
5940 .adc_nids
= alc260_test_adc_nids
,
5941 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
5942 .channel_mode
= alc260_modes
,
5943 .num_mux_defs
= ARRAY_SIZE(alc260_test_capture_sources
),
5944 .input_mux
= alc260_test_capture_sources
,
5949 static int patch_alc260(struct hda_codec
*codec
)
5951 struct alc_spec
*spec
;
5952 int err
, board_config
;
5954 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
5960 board_config
= snd_hda_check_board_config(codec
, ALC260_MODEL_LAST
,
5963 if (board_config
< 0) {
5964 snd_printd(KERN_INFO
"hda_codec: Unknown model for ALC260, "
5965 "trying auto-probe from BIOS...\n");
5966 board_config
= ALC260_AUTO
;
5969 if (board_config
== ALC260_AUTO
) {
5970 /* automatic parse from the BIOS config */
5971 err
= alc260_parse_auto_config(codec
);
5977 "hda_codec: Cannot set up configuration "
5978 "from BIOS. Using base mode...\n");
5979 board_config
= ALC260_BASIC
;
5983 err
= snd_hda_attach_beep_device(codec
, 0x1);
5989 if (board_config
!= ALC260_AUTO
)
5990 setup_preset(spec
, &alc260_presets
[board_config
]);
5992 spec
->stream_name_analog
= "ALC260 Analog";
5993 spec
->stream_analog_playback
= &alc260_pcm_analog_playback
;
5994 spec
->stream_analog_capture
= &alc260_pcm_analog_capture
;
5996 spec
->stream_name_digital
= "ALC260 Digital";
5997 spec
->stream_digital_playback
= &alc260_pcm_digital_playback
;
5998 spec
->stream_digital_capture
= &alc260_pcm_digital_capture
;
6000 if (!spec
->adc_nids
&& spec
->input_mux
) {
6001 /* check whether NID 0x04 is valid */
6002 unsigned int wcap
= get_wcaps(codec
, 0x04);
6003 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
6005 if (wcap
!= AC_WID_AUD_IN
|| spec
->input_mux
->num_items
== 1) {
6006 spec
->adc_nids
= alc260_adc_nids_alt
;
6007 spec
->num_adc_nids
= ARRAY_SIZE(alc260_adc_nids_alt
);
6009 spec
->adc_nids
= alc260_adc_nids
;
6010 spec
->num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
);
6013 set_capture_mixer(spec
);
6014 set_beep_amp(spec
, 0x07, 0x05, HDA_INPUT
);
6016 spec
->vmaster_nid
= 0x08;
6018 codec
->patch_ops
= alc_patch_ops
;
6019 if (board_config
== ALC260_AUTO
)
6020 spec
->init_hook
= alc260_auto_init
;
6021 #ifdef CONFIG_SND_HDA_POWER_SAVE
6022 if (!spec
->loopback
.amplist
)
6023 spec
->loopback
.amplist
= alc260_loopbacks
;
6025 codec
->proc_widget_hook
= print_realtek_coef
;
6034 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6035 * configuration. Each pin widget can choose any input DACs and a mixer.
6036 * Each ADC is connected from a mixer of all inputs. This makes possible
6037 * 6-channel independent captures.
6039 * In addition, an independent DAC for the multi-playback (not used in this
6042 #define ALC882_DIGOUT_NID 0x06
6043 #define ALC882_DIGIN_NID 0x0a
6045 static struct hda_channel_mode alc882_ch_modes
[1] = {
6049 static hda_nid_t alc882_dac_nids
[4] = {
6050 /* front, rear, clfe, rear_surr */
6051 0x02, 0x03, 0x04, 0x05
6054 /* identical with ALC880 */
6055 #define alc882_adc_nids alc880_adc_nids
6056 #define alc882_adc_nids_alt alc880_adc_nids_alt
6058 static hda_nid_t alc882_capsrc_nids
[3] = { 0x24, 0x23, 0x22 };
6059 static hda_nid_t alc882_capsrc_nids_alt
[2] = { 0x23, 0x22 };
6062 /* FIXME: should be a matrix-type input source selection */
6064 static struct hda_input_mux alc882_capture_source
= {
6068 { "Front Mic", 0x1 },
6076 static struct hda_verb alc882_3ST_ch2_init
[] = {
6077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6079 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6080 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6087 static struct hda_verb alc882_3ST_ch6_init
[] = {
6088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6090 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
6091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6093 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
6097 static struct hda_channel_mode alc882_3ST_6ch_modes
[2] = {
6098 { 2, alc882_3ST_ch2_init
},
6099 { 6, alc882_3ST_ch6_init
},
6105 static struct hda_verb alc882_sixstack_ch6_init
[] = {
6106 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
6107 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6108 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6109 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6116 static struct hda_verb alc882_sixstack_ch8_init
[] = {
6117 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6118 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6119 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6120 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6124 static struct hda_channel_mode alc882_sixstack_modes
[2] = {
6125 { 6, alc882_sixstack_ch6_init
},
6126 { 8, alc882_sixstack_ch8_init
},
6130 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
6136 static struct hda_verb alc885_mbp_ch2_init
[] = {
6137 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6138 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6139 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6146 static struct hda_verb alc885_mbp_ch6_init
[] = {
6147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6149 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
6150 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6151 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6155 static struct hda_channel_mode alc885_mbp_6ch_modes
[2] = {
6156 { 2, alc885_mbp_ch2_init
},
6157 { 6, alc885_mbp_ch6_init
},
6161 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6162 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6164 static struct snd_kcontrol_new alc882_base_mixer
[] = {
6165 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6166 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6167 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
6168 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
6169 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
6170 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
6171 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
6172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
6173 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
6174 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
6175 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6178 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6179 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6180 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6181 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6182 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6183 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6184 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
6185 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6189 static struct snd_kcontrol_new alc885_mbp3_mixer
[] = {
6190 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT
),
6191 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT
),
6192 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT
),
6193 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT
),
6194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6195 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT
),
6197 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT
),
6198 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT
),
6199 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT
),
6202 static struct snd_kcontrol_new alc882_w2jc_mixer
[] = {
6203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6205 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6206 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6207 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6208 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6210 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6215 static struct snd_kcontrol_new alc882_targa_mixer
[] = {
6216 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6217 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6225 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6227 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6228 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
6232 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6233 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6235 static struct snd_kcontrol_new alc882_asus_a7j_mixer
[] = {
6236 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6237 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
6238 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
6239 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT
),
6240 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6241 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6242 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6243 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6244 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT
),
6245 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT
),
6246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6247 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6248 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6252 static struct snd_kcontrol_new alc882_asus_a7m_mixer
[] = {
6253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6254 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
6256 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6257 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6258 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6259 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6261 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6266 static struct snd_kcontrol_new alc882_chmode_mixer
[] = {
6268 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6269 .name
= "Channel Mode",
6270 .info
= alc_ch_mode_info
,
6271 .get
= alc_ch_mode_get
,
6272 .put
= alc_ch_mode_put
,
6277 static struct hda_verb alc882_init_verbs
[] = {
6278 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6279 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6283 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6285 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6287 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6288 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6289 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6291 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6292 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6293 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6295 /* Front Pin: output 0 (0x0c) */
6296 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6297 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6298 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
6299 /* Rear Pin: output 1 (0x0d) */
6300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6301 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6302 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
6303 /* CLFE Pin: output 2 (0x0e) */
6304 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6305 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6306 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
6307 /* Side Pin: output 3 (0x0f) */
6308 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6309 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6310 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
6311 /* Mic (rear) pin: input vref at 80% */
6312 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6313 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6314 /* Front Mic pin: input vref at 80% */
6315 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6316 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6317 /* Line In pin: input */
6318 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6320 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6321 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6322 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6323 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
6324 /* CD pin widget for input */
6325 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6327 /* FIXME: use matrix-type input source selection */
6328 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6329 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6331 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6332 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6333 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6336 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6337 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6344 /* ADC1: mute amp left and right */
6345 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6346 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
6347 /* ADC2: mute amp left and right */
6348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6349 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6350 /* ADC3: mute amp left and right */
6351 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6352 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6357 static struct hda_verb alc882_eapd_verbs
[] = {
6358 /* change to EAPD mode */
6359 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
6360 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
6365 static struct snd_kcontrol_new alc882_macpro_mixer
[] = {
6366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6367 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6368 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT
),
6369 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT
),
6370 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT
),
6371 /* FIXME: this looks suspicious...
6372 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6373 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6378 static struct hda_verb alc882_macpro_init_verbs
[] = {
6379 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6380 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6381 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6383 /* Front Pin: output 0 (0x0c) */
6384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6385 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6386 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
6387 /* Front Mic pin: input vref at 80% */
6388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6389 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6390 /* Speaker: output */
6391 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6393 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x04},
6394 /* Headphone output (output 0 - 0x0c) */
6395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6397 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x00},
6399 /* FIXME: use matrix-type input source selection */
6400 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6401 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6407 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6408 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6409 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6410 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6412 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6413 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6416 /* ADC1: mute amp left and right */
6417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6418 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
6419 /* ADC2: mute amp left and right */
6420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6421 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6422 /* ADC3: mute amp left and right */
6423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6424 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6429 /* Macbook Pro rev3 */
6430 static struct hda_verb alc885_mbp3_init_verbs
[] = {
6431 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6433 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6438 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6439 /* Front Pin: output 0 (0x0c) */
6440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6442 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
6443 /* HP Pin: output 0 (0x0d) */
6444 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc4},
6445 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6446 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
6447 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6448 /* Mic (rear) pin: input vref at 80% */
6449 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6450 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6451 /* Front Mic pin: input vref at 80% */
6452 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6454 /* Line In pin: use output 1 when in LineOut mode */
6455 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6456 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6457 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01},
6459 /* FIXME: use matrix-type input source selection */
6460 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6461 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6463 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6464 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6469 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6470 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6476 /* ADC1: mute amp left and right */
6477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6478 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
6479 /* ADC2: mute amp left and right */
6480 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6481 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6482 /* ADC3: mute amp left and right */
6483 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6484 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6489 /* iMac 24 mixer. */
6490 static struct snd_kcontrol_new alc885_imac24_mixer
[] = {
6491 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT
),
6492 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT
),
6496 /* iMac 24 init verbs. */
6497 static struct hda_verb alc885_imac24_init_verbs
[] = {
6498 /* Internal speakers: output 0 (0x0c) */
6499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6501 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x00},
6502 /* Internal speakers: output 0 (0x0c) */
6503 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6504 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6505 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x00},
6506 /* Headphone: output 0 (0x0c) */
6507 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6508 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6509 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
6510 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6511 /* Front Mic: input vref at 80% */
6512 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6513 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6517 /* Toggle speaker-output according to the hp-jack state */
6518 static void alc885_imac24_automute(struct hda_codec
*codec
)
6520 unsigned int present
;
6522 present
= snd_hda_codec_read(codec
, 0x14, 0,
6523 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6524 snd_hda_codec_amp_stereo(codec
, 0x18, HDA_OUTPUT
, 0,
6525 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6526 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_OUTPUT
, 0,
6527 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6530 /* Processes unsolicited events. */
6531 static void alc885_imac24_unsol_event(struct hda_codec
*codec
,
6534 /* Headphone insertion or removal. */
6535 if ((res
>> 26) == ALC880_HP_EVENT
)
6536 alc885_imac24_automute(codec
);
6539 static void alc885_mbp3_automute(struct hda_codec
*codec
)
6541 unsigned int present
;
6543 present
= snd_hda_codec_read(codec
, 0x15, 0,
6544 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6545 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
6546 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6547 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6548 HDA_AMP_MUTE
, present
? 0 : HDA_AMP_MUTE
);
6551 static void alc885_mbp3_unsol_event(struct hda_codec
*codec
,
6554 /* Headphone insertion or removal. */
6555 if ((res
>> 26) == ALC880_HP_EVENT
)
6556 alc885_mbp3_automute(codec
);
6560 static struct hda_verb alc882_targa_verbs
[] = {
6561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6567 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
6568 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
6569 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6571 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6572 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
6573 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
6574 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
6578 /* toggle speaker-output according to the hp-jack state */
6579 static void alc882_targa_automute(struct hda_codec
*codec
)
6581 unsigned int present
;
6583 present
= snd_hda_codec_read(codec
, 0x14, 0,
6584 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6585 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
6586 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6587 snd_hda_codec_write_cache(codec
, 1, 0, AC_VERB_SET_GPIO_DATA
,
6591 static void alc882_targa_unsol_event(struct hda_codec
*codec
, unsigned int res
)
6593 /* Looks like the unsol event is incompatible with the standard
6594 * definition. 4bit tag is placed at 26 bit!
6596 if (((res
>> 26) == ALC880_HP_EVENT
)) {
6597 alc882_targa_automute(codec
);
6601 static struct hda_verb alc882_asus_a7j_verbs
[] = {
6602 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6603 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6607 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6609 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
6610 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6611 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
6613 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
6614 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
6615 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6619 static struct hda_verb alc882_asus_a7m_verbs
[] = {
6620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6623 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6625 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6627 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
6628 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6629 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
6631 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
6632 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
6633 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6637 static void alc882_gpio_mute(struct hda_codec
*codec
, int pin
, int muted
)
6639 unsigned int gpiostate
, gpiomask
, gpiodir
;
6641 gpiostate
= snd_hda_codec_read(codec
, codec
->afg
, 0,
6642 AC_VERB_GET_GPIO_DATA
, 0);
6645 gpiostate
|= (1 << pin
);
6647 gpiostate
&= ~(1 << pin
);
6649 gpiomask
= snd_hda_codec_read(codec
, codec
->afg
, 0,
6650 AC_VERB_GET_GPIO_MASK
, 0);
6651 gpiomask
|= (1 << pin
);
6653 gpiodir
= snd_hda_codec_read(codec
, codec
->afg
, 0,
6654 AC_VERB_GET_GPIO_DIRECTION
, 0);
6655 gpiodir
|= (1 << pin
);
6658 snd_hda_codec_write(codec
, codec
->afg
, 0,
6659 AC_VERB_SET_GPIO_MASK
, gpiomask
);
6660 snd_hda_codec_write(codec
, codec
->afg
, 0,
6661 AC_VERB_SET_GPIO_DIRECTION
, gpiodir
);
6665 snd_hda_codec_write(codec
, codec
->afg
, 0,
6666 AC_VERB_SET_GPIO_DATA
, gpiostate
);
6669 /* set up GPIO at initialization */
6670 static void alc885_macpro_init_hook(struct hda_codec
*codec
)
6672 alc882_gpio_mute(codec
, 0, 0);
6673 alc882_gpio_mute(codec
, 1, 0);
6676 /* set up GPIO and update auto-muting at initialization */
6677 static void alc885_imac24_init_hook(struct hda_codec
*codec
)
6679 alc885_macpro_init_hook(codec
);
6680 alc885_imac24_automute(codec
);
6684 * generic initialization of ADC, input mixers and output mixers
6686 static struct hda_verb alc882_auto_init_verbs
[] = {
6688 * Unmute ADC0-2 and set the default input to mic-in
6690 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6692 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6693 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6694 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6695 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6697 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6699 * Note: PASD motherboards uses the Line In 2 as the input for
6700 * front panel mic (mic 2)
6702 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6703 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6704 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6705 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
6706 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
6707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
6710 * Set up output mixers (0x0c - 0x0f)
6712 /* set vol=0 to output mixers */
6713 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6714 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6715 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6717 /* set up input amps for analog loopback */
6718 /* Amp Indices: DAC = 0, mixer = 1 */
6719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6721 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6723 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6726 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6727 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6728 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6730 /* FIXME: use matrix-type input source selection */
6731 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6732 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6733 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
6734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
6735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
6736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
6738 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
6739 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
6740 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
6741 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
6743 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
6744 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
6745 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
6746 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
6751 #ifdef CONFIG_SND_HDA_POWER_SAVE
6752 #define alc882_loopbacks alc880_loopbacks
6755 /* pcm configuration: identiacal with ALC880 */
6756 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6757 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6758 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6759 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6762 * configuration and preset
6764 static const char *alc882_models
[ALC882_MODEL_LAST
] = {
6765 [ALC882_3ST_DIG
] = "3stack-dig",
6766 [ALC882_6ST_DIG
] = "6stack-dig",
6767 [ALC882_ARIMA
] = "arima",
6768 [ALC882_W2JC
] = "w2jc",
6769 [ALC882_TARGA
] = "targa",
6770 [ALC882_ASUS_A7J
] = "asus-a7j",
6771 [ALC882_ASUS_A7M
] = "asus-a7m",
6772 [ALC885_MACPRO
] = "macpro",
6773 [ALC885_MBP3
] = "mbp3",
6774 [ALC885_IMAC24
] = "imac24",
6775 [ALC882_AUTO
] = "auto",
6778 static struct snd_pci_quirk alc882_cfg_tbl
[] = {
6779 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG
),
6780 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J
),
6781 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J
),
6782 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M
),
6783 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC
),
6784 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG
),
6785 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG
),
6786 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG
),
6787 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG
),
6788 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA
), /* MSI-1049 T8 */
6789 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG
),
6790 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA
),
6794 static struct alc_config_preset alc882_presets
[] = {
6795 [ALC882_3ST_DIG
] = {
6796 .mixers
= { alc882_base_mixer
},
6797 .init_verbs
= { alc882_init_verbs
},
6798 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6799 .dac_nids
= alc882_dac_nids
,
6800 .dig_out_nid
= ALC882_DIGOUT_NID
,
6801 .dig_in_nid
= ALC882_DIGIN_NID
,
6802 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
6803 .channel_mode
= alc882_ch_modes
,
6805 .input_mux
= &alc882_capture_source
,
6807 [ALC882_6ST_DIG
] = {
6808 .mixers
= { alc882_base_mixer
, alc882_chmode_mixer
},
6809 .init_verbs
= { alc882_init_verbs
},
6810 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6811 .dac_nids
= alc882_dac_nids
,
6812 .dig_out_nid
= ALC882_DIGOUT_NID
,
6813 .dig_in_nid
= ALC882_DIGIN_NID
,
6814 .num_channel_mode
= ARRAY_SIZE(alc882_sixstack_modes
),
6815 .channel_mode
= alc882_sixstack_modes
,
6816 .input_mux
= &alc882_capture_source
,
6819 .mixers
= { alc882_base_mixer
, alc882_chmode_mixer
},
6820 .init_verbs
= { alc882_init_verbs
, alc882_eapd_verbs
},
6821 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6822 .dac_nids
= alc882_dac_nids
,
6823 .num_channel_mode
= ARRAY_SIZE(alc882_sixstack_modes
),
6824 .channel_mode
= alc882_sixstack_modes
,
6825 .input_mux
= &alc882_capture_source
,
6828 .mixers
= { alc882_w2jc_mixer
, alc882_chmode_mixer
},
6829 .init_verbs
= { alc882_init_verbs
, alc882_eapd_verbs
,
6830 alc880_gpio1_init_verbs
},
6831 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6832 .dac_nids
= alc882_dac_nids
,
6833 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
6834 .channel_mode
= alc880_threestack_modes
,
6836 .input_mux
= &alc882_capture_source
,
6837 .dig_out_nid
= ALC882_DIGOUT_NID
,
6840 .mixers
= { alc885_mbp3_mixer
, alc882_chmode_mixer
},
6841 .init_verbs
= { alc885_mbp3_init_verbs
,
6842 alc880_gpio1_init_verbs
},
6843 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6844 .dac_nids
= alc882_dac_nids
,
6845 .channel_mode
= alc885_mbp_6ch_modes
,
6846 .num_channel_mode
= ARRAY_SIZE(alc885_mbp_6ch_modes
),
6847 .input_mux
= &alc882_capture_source
,
6848 .dig_out_nid
= ALC882_DIGOUT_NID
,
6849 .dig_in_nid
= ALC882_DIGIN_NID
,
6850 .unsol_event
= alc885_mbp3_unsol_event
,
6851 .init_hook
= alc885_mbp3_automute
,
6854 .mixers
= { alc882_macpro_mixer
},
6855 .init_verbs
= { alc882_macpro_init_verbs
},
6856 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6857 .dac_nids
= alc882_dac_nids
,
6858 .dig_out_nid
= ALC882_DIGOUT_NID
,
6859 .dig_in_nid
= ALC882_DIGIN_NID
,
6860 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
6861 .channel_mode
= alc882_ch_modes
,
6862 .input_mux
= &alc882_capture_source
,
6863 .init_hook
= alc885_macpro_init_hook
,
6866 .mixers
= { alc885_imac24_mixer
},
6867 .init_verbs
= { alc885_imac24_init_verbs
},
6868 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6869 .dac_nids
= alc882_dac_nids
,
6870 .dig_out_nid
= ALC882_DIGOUT_NID
,
6871 .dig_in_nid
= ALC882_DIGIN_NID
,
6872 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
6873 .channel_mode
= alc882_ch_modes
,
6874 .input_mux
= &alc882_capture_source
,
6875 .unsol_event
= alc885_imac24_unsol_event
,
6876 .init_hook
= alc885_imac24_init_hook
,
6879 .mixers
= { alc882_targa_mixer
, alc882_chmode_mixer
},
6880 .init_verbs
= { alc882_init_verbs
, alc882_targa_verbs
},
6881 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6882 .dac_nids
= alc882_dac_nids
,
6883 .dig_out_nid
= ALC882_DIGOUT_NID
,
6884 .num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
),
6885 .adc_nids
= alc882_adc_nids
,
6886 .capsrc_nids
= alc882_capsrc_nids
,
6887 .num_channel_mode
= ARRAY_SIZE(alc882_3ST_6ch_modes
),
6888 .channel_mode
= alc882_3ST_6ch_modes
,
6890 .input_mux
= &alc882_capture_source
,
6891 .unsol_event
= alc882_targa_unsol_event
,
6892 .init_hook
= alc882_targa_automute
,
6894 [ALC882_ASUS_A7J
] = {
6895 .mixers
= { alc882_asus_a7j_mixer
, alc882_chmode_mixer
},
6896 .init_verbs
= { alc882_init_verbs
, alc882_asus_a7j_verbs
},
6897 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6898 .dac_nids
= alc882_dac_nids
,
6899 .dig_out_nid
= ALC882_DIGOUT_NID
,
6900 .num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
),
6901 .adc_nids
= alc882_adc_nids
,
6902 .capsrc_nids
= alc882_capsrc_nids
,
6903 .num_channel_mode
= ARRAY_SIZE(alc882_3ST_6ch_modes
),
6904 .channel_mode
= alc882_3ST_6ch_modes
,
6906 .input_mux
= &alc882_capture_source
,
6908 [ALC882_ASUS_A7M
] = {
6909 .mixers
= { alc882_asus_a7m_mixer
, alc882_chmode_mixer
},
6910 .init_verbs
= { alc882_init_verbs
, alc882_eapd_verbs
,
6911 alc880_gpio1_init_verbs
,
6912 alc882_asus_a7m_verbs
},
6913 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
6914 .dac_nids
= alc882_dac_nids
,
6915 .dig_out_nid
= ALC882_DIGOUT_NID
,
6916 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
6917 .channel_mode
= alc880_threestack_modes
,
6919 .input_mux
= &alc882_capture_source
,
6928 PINFIX_ABIT_AW9D_MAX
6931 static struct alc_pincfg alc882_abit_aw9d_pinfix
[] = {
6932 { 0x15, 0x01080104 }, /* side */
6933 { 0x16, 0x01011012 }, /* rear */
6934 { 0x17, 0x01016011 }, /* clfe */
6938 static const struct alc_pincfg
*alc882_pin_fixes
[] = {
6939 [PINFIX_ABIT_AW9D_MAX
] = alc882_abit_aw9d_pinfix
,
6942 static struct snd_pci_quirk alc882_pinfix_tbl
[] = {
6943 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX
),
6948 * BIOS auto configuration
6950 static void alc882_auto_set_output_and_unmute(struct hda_codec
*codec
,
6951 hda_nid_t nid
, int pin_type
,
6955 struct alc_spec
*spec
= codec
->spec
;
6958 alc_set_pin_output(codec
, nid
, pin_type
);
6959 if (spec
->multiout
.dac_nids
[dac_idx
] == 0x25)
6962 idx
= spec
->multiout
.dac_nids
[dac_idx
] - 2;
6963 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_CONNECT_SEL
, idx
);
6967 static void alc882_auto_init_multi_out(struct hda_codec
*codec
)
6969 struct alc_spec
*spec
= codec
->spec
;
6972 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
6973 for (i
= 0; i
<= HDA_SIDE
; i
++) {
6974 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
6975 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
6977 alc882_auto_set_output_and_unmute(codec
, nid
, pin_type
,
6982 static void alc882_auto_init_hp_out(struct hda_codec
*codec
)
6984 struct alc_spec
*spec
= codec
->spec
;
6987 pin
= spec
->autocfg
.hp_pins
[0];
6988 if (pin
) /* connect to front */
6990 alc882_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
6991 pin
= spec
->autocfg
.speaker_pins
[0];
6993 alc882_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
6996 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6997 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6999 static void alc882_auto_init_analog_input(struct hda_codec
*codec
)
7001 struct alc_spec
*spec
= codec
->spec
;
7004 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
7005 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
7010 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
7011 unsigned int pincap
;
7012 pincap
= snd_hda_param_read(codec
, nid
, AC_PAR_PIN_CAP
);
7013 if ((pincap
>> AC_PINCAP_VREF_SHIFT
) &
7017 snd_hda_codec_write(codec
, nid
, 0,
7018 AC_VERB_SET_PIN_WIDGET_CONTROL
, vref
);
7019 if (get_wcaps(codec
, nid
) & AC_WCAP_OUT_AMP
)
7020 snd_hda_codec_write(codec
, nid
, 0,
7021 AC_VERB_SET_AMP_GAIN_MUTE
,
7026 static void alc882_auto_init_input_src(struct hda_codec
*codec
)
7028 struct alc_spec
*spec
= codec
->spec
;
7031 for (c
= 0; c
< spec
->num_adc_nids
; c
++) {
7032 hda_nid_t conn_list
[HDA_MAX_NUM_INPUTS
];
7033 hda_nid_t nid
= spec
->capsrc_nids
[c
];
7034 unsigned int mux_idx
;
7035 const struct hda_input_mux
*imux
;
7036 int conns
, mute
, idx
, item
;
7038 conns
= snd_hda_get_connections(codec
, nid
, conn_list
,
7039 ARRAY_SIZE(conn_list
));
7042 mux_idx
= c
>= spec
->num_mux_defs
? 0 : c
;
7043 imux
= &spec
->input_mux
[mux_idx
];
7044 for (idx
= 0; idx
< conns
; idx
++) {
7045 /* if the current connection is the selected one,
7046 * unmute it as default - otherwise mute it
7048 mute
= AMP_IN_MUTE(idx
);
7049 for (item
= 0; item
< imux
->num_items
; item
++) {
7050 if (imux
->items
[item
].index
== idx
) {
7051 if (spec
->cur_mux
[c
] == item
)
7052 mute
= AMP_IN_UNMUTE(idx
);
7056 /* check if we have a selector or mixer
7057 * we could check for the widget type instead, but
7058 * just check for Amp-In presence (in case of mixer
7059 * without amp-in there is something wrong, this
7060 * function shouldn't be used or capsrc nid is wrong)
7062 if (get_wcaps(codec
, nid
) & AC_WCAP_IN_AMP
)
7063 snd_hda_codec_write(codec
, nid
, 0,
7064 AC_VERB_SET_AMP_GAIN_MUTE
,
7066 else if (mute
!= AMP_IN_MUTE(idx
))
7067 snd_hda_codec_write(codec
, nid
, 0,
7068 AC_VERB_SET_CONNECT_SEL
,
7074 /* add mic boosts if needed */
7075 static int alc_auto_add_mic_boost(struct hda_codec
*codec
)
7077 struct alc_spec
*spec
= codec
->spec
;
7081 nid
= spec
->autocfg
.input_pins
[AUTO_PIN_MIC
];
7082 if (nid
&& (get_wcaps(codec
, nid
) & AC_WCAP_IN_AMP
)) {
7083 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
7085 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_INPUT
));
7089 nid
= spec
->autocfg
.input_pins
[AUTO_PIN_FRONT_MIC
];
7090 if (nid
&& (get_wcaps(codec
, nid
) & AC_WCAP_IN_AMP
)) {
7091 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
7093 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_INPUT
));
7100 /* almost identical with ALC880 parser... */
7101 static int alc882_parse_auto_config(struct hda_codec
*codec
)
7103 struct alc_spec
*spec
= codec
->spec
;
7104 int err
= alc880_parse_auto_config(codec
);
7109 return 0; /* no config found */
7111 err
= alc_auto_add_mic_boost(codec
);
7115 /* hack - override the init verbs */
7116 spec
->init_verbs
[0] = alc882_auto_init_verbs
;
7118 return 1; /* config found */
7121 /* additional initialization for auto-configuration model */
7122 static void alc882_auto_init(struct hda_codec
*codec
)
7124 struct alc_spec
*spec
= codec
->spec
;
7125 alc882_auto_init_multi_out(codec
);
7126 alc882_auto_init_hp_out(codec
);
7127 alc882_auto_init_analog_input(codec
);
7128 alc882_auto_init_input_src(codec
);
7129 if (spec
->unsol_event
)
7130 alc_inithook(codec
);
7133 static int patch_alc883(struct hda_codec
*codec
); /* called in patch_alc882() */
7135 static int patch_alc882(struct hda_codec
*codec
)
7137 struct alc_spec
*spec
;
7138 int err
, board_config
;
7140 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
7146 board_config
= snd_hda_check_board_config(codec
, ALC882_MODEL_LAST
,
7150 if (board_config
< 0 || board_config
>= ALC882_MODEL_LAST
) {
7151 /* Pick up systems that don't supply PCI SSID */
7152 switch (codec
->subsystem_id
) {
7153 case 0x106b0c00: /* Mac Pro */
7154 board_config
= ALC885_MACPRO
;
7156 case 0x106b1000: /* iMac 24 */
7157 case 0x106b2800: /* AppleTV */
7158 case 0x106b3e00: /* iMac 24 Aluminium */
7159 board_config
= ALC885_IMAC24
;
7161 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7162 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7163 case 0x106b00a4: /* MacbookPro4,1 */
7164 case 0x106b2c00: /* Macbook Pro rev3 */
7165 case 0x106b3600: /* Macbook 3.1 */
7166 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7167 board_config
= ALC885_MBP3
;
7170 /* ALC889A is handled better as ALC888-compatible */
7171 if (codec
->revision_id
== 0x100101 ||
7172 codec
->revision_id
== 0x100103) {
7174 return patch_alc883(codec
);
7176 printk(KERN_INFO
"hda_codec: Unknown model for ALC882, "
7177 "trying auto-probe from BIOS...\n");
7178 board_config
= ALC882_AUTO
;
7182 alc_fix_pincfg(codec
, alc882_pinfix_tbl
, alc882_pin_fixes
);
7184 if (board_config
== ALC882_AUTO
) {
7185 /* automatic parse from the BIOS config */
7186 err
= alc882_parse_auto_config(codec
);
7192 "hda_codec: Cannot set up configuration "
7193 "from BIOS. Using base mode...\n");
7194 board_config
= ALC882_3ST_DIG
;
7198 err
= snd_hda_attach_beep_device(codec
, 0x1);
7204 if (board_config
!= ALC882_AUTO
)
7205 setup_preset(spec
, &alc882_presets
[board_config
]);
7207 if (codec
->vendor_id
== 0x10ec0885) {
7208 spec
->stream_name_analog
= "ALC885 Analog";
7209 spec
->stream_name_digital
= "ALC885 Digital";
7211 spec
->stream_name_analog
= "ALC882 Analog";
7212 spec
->stream_name_digital
= "ALC882 Digital";
7215 spec
->stream_analog_playback
= &alc882_pcm_analog_playback
;
7216 spec
->stream_analog_capture
= &alc882_pcm_analog_capture
;
7217 /* FIXME: setup DAC5 */
7218 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7219 spec
->stream_analog_alt_capture
= &alc880_pcm_analog_alt_capture
;
7221 spec
->stream_digital_playback
= &alc882_pcm_digital_playback
;
7222 spec
->stream_digital_capture
= &alc882_pcm_digital_capture
;
7224 spec
->capture_style
= CAPT_MIX
; /* matrix-style capture */
7225 if (!spec
->adc_nids
&& spec
->input_mux
) {
7226 /* check whether NID 0x07 is valid */
7227 unsigned int wcap
= get_wcaps(codec
, 0x07);
7229 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
7230 if (wcap
!= AC_WID_AUD_IN
) {
7231 spec
->adc_nids
= alc882_adc_nids_alt
;
7232 spec
->num_adc_nids
= ARRAY_SIZE(alc882_adc_nids_alt
);
7233 spec
->capsrc_nids
= alc882_capsrc_nids_alt
;
7235 spec
->adc_nids
= alc882_adc_nids
;
7236 spec
->num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
);
7237 spec
->capsrc_nids
= alc882_capsrc_nids
;
7240 set_capture_mixer(spec
);
7241 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
7243 spec
->vmaster_nid
= 0x0c;
7245 codec
->patch_ops
= alc_patch_ops
;
7246 if (board_config
== ALC882_AUTO
)
7247 spec
->init_hook
= alc882_auto_init
;
7248 #ifdef CONFIG_SND_HDA_POWER_SAVE
7249 if (!spec
->loopback
.amplist
)
7250 spec
->loopback
.amplist
= alc882_loopbacks
;
7252 codec
->proc_widget_hook
= print_realtek_coef
;
7260 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7261 * configuration. Each pin widget can choose any input DACs and a mixer.
7262 * Each ADC is connected from a mixer of all inputs. This makes possible
7263 * 6-channel independent captures.
7265 * In addition, an independent DAC for the multi-playback (not used in this
7268 #define ALC883_DIGOUT_NID 0x06
7269 #define ALC883_DIGIN_NID 0x0a
7271 #define ALC1200_DIGOUT_NID 0x10
7273 static hda_nid_t alc883_dac_nids
[4] = {
7274 /* front, rear, clfe, rear_surr */
7275 0x02, 0x03, 0x04, 0x05
7278 static hda_nid_t alc883_adc_nids
[2] = {
7283 static hda_nid_t alc883_adc_nids_alt
[1] = {
7288 static hda_nid_t alc883_adc_nids_rev
[2] = {
7293 #define alc889_adc_nids alc880_adc_nids
7295 static hda_nid_t alc883_capsrc_nids
[2] = { 0x23, 0x22 };
7297 static hda_nid_t alc883_capsrc_nids_rev
[2] = { 0x22, 0x23 };
7299 #define alc889_capsrc_nids alc882_capsrc_nids
7302 /* FIXME: should be a matrix-type input source selection */
7304 static struct hda_input_mux alc883_capture_source
= {
7308 { "Front Mic", 0x1 },
7314 static struct hda_input_mux alc883_3stack_6ch_intel
= {
7318 { "Front Mic", 0x0 },
7324 static struct hda_input_mux alc883_lenovo_101e_capture_source
= {
7332 static struct hda_input_mux alc883_lenovo_nb0763_capture_source
= {
7342 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source
= {
7350 static struct hda_input_mux alc883_lenovo_sky_capture_source
= {
7354 { "Front Mic", 0x1 },
7359 static struct hda_input_mux alc883_asus_eee1601_capture_source
= {
7370 static struct hda_channel_mode alc883_3ST_2ch_modes
[1] = {
7377 static struct hda_verb alc883_3ST_ch2_init
[] = {
7378 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7379 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7380 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
7381 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7388 static struct hda_verb alc883_3ST_ch4_init
[] = {
7389 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7390 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7391 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7392 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7393 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
7400 static struct hda_verb alc883_3ST_ch6_init
[] = {
7401 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7402 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7403 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
7404 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7405 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7406 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
7410 static struct hda_channel_mode alc883_3ST_6ch_modes
[3] = {
7411 { 2, alc883_3ST_ch2_init
},
7412 { 4, alc883_3ST_ch4_init
},
7413 { 6, alc883_3ST_ch6_init
},
7419 static struct hda_verb alc883_3ST_ch2_intel_init
[] = {
7420 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7421 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7422 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
7423 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7430 static struct hda_verb alc883_3ST_ch4_intel_init
[] = {
7431 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7432 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7433 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7434 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7435 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
7442 static struct hda_verb alc883_3ST_ch6_intel_init
[] = {
7443 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7444 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7445 { 0x19, AC_VERB_SET_CONNECT_SEL
, 0x02 },
7446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7448 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
7452 static struct hda_channel_mode alc883_3ST_6ch_intel_modes
[3] = {
7453 { 2, alc883_3ST_ch2_intel_init
},
7454 { 4, alc883_3ST_ch4_intel_init
},
7455 { 6, alc883_3ST_ch6_intel_init
},
7461 static struct hda_verb alc883_sixstack_ch6_init
[] = {
7462 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
7463 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7464 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7465 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7472 static struct hda_verb alc883_sixstack_ch8_init
[] = {
7473 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7474 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7475 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7476 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7480 static struct hda_channel_mode alc883_sixstack_modes
[2] = {
7481 { 6, alc883_sixstack_ch6_init
},
7482 { 8, alc883_sixstack_ch8_init
},
7485 static struct hda_verb alc883_medion_eapd_verbs
[] = {
7486 /* eanable EAPD on medion laptop */
7487 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
7488 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
7492 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7493 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7496 static struct snd_kcontrol_new alc883_base_mixer
[] = {
7497 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7498 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7499 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7500 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
7501 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
7502 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7503 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7504 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7505 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
7506 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
7507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7510 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7511 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7512 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7513 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7516 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7517 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7521 static struct snd_kcontrol_new alc883_mitac_mixer
[] = {
7522 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7524 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
7525 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7526 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7527 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7528 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7530 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7531 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7532 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7533 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7534 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7538 static struct snd_kcontrol_new alc883_clevo_m720_mixer
[] = {
7539 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7540 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
7541 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7542 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
7543 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7544 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7546 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7547 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
7548 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7552 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer
[] = {
7553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7554 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
7555 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7556 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
7557 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7558 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7560 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7561 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
7562 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7566 static struct snd_kcontrol_new alc883_3ST_2ch_mixer
[] = {
7567 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7568 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7570 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7571 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7575 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7577 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7578 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7579 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7583 static struct snd_kcontrol_new alc883_3ST_6ch_mixer
[] = {
7584 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7585 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7586 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7587 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
7588 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
7589 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7590 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7591 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7592 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7593 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7594 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7595 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7596 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7598 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7600 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7601 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7606 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer
[] = {
7607 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7608 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7609 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7610 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
7611 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7613 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7614 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7615 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7617 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7618 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7622 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT
),
7623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7624 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7625 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT
),
7626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7630 static struct snd_kcontrol_new alc883_fivestack_mixer
[] = {
7631 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7633 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7634 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
7635 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
7636 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7637 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7638 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7639 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7640 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7641 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7645 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7648 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7649 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7653 static struct snd_kcontrol_new alc883_tagra_mixer
[] = {
7654 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7655 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7656 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7658 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
7659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
7660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
7662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
7663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7668 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7673 static struct snd_kcontrol_new alc883_tagra_2ch_mixer
[] = {
7674 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7675 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7676 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7680 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7682 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7683 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
7684 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7688 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer
[] = {
7689 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7690 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7691 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7692 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
7693 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7694 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7700 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer
[] = {
7701 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7702 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT
),
7703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7704 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7705 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7708 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7709 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7713 static struct snd_kcontrol_new alc883_medion_md2_mixer
[] = {
7714 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7715 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7716 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7726 static struct snd_kcontrol_new alc883_acer_aspire_mixer
[] = {
7727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7728 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7729 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7730 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7731 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7733 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7738 static struct snd_kcontrol_new alc888_lenovo_sky_mixer
[] = {
7739 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7740 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7741 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
7742 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT
),
7743 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7744 0x0d, 1, 0x0, HDA_OUTPUT
),
7745 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT
),
7746 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT
),
7747 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT
),
7748 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
7749 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
7750 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7751 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT
),
7752 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7753 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7754 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7755 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7757 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7758 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7759 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
7760 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7761 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
7765 static struct hda_bind_ctls alc883_bind_cap_vol
= {
7766 .ops
= &snd_hda_bind_vol
,
7768 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT
),
7769 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT
),
7774 static struct hda_bind_ctls alc883_bind_cap_switch
= {
7775 .ops
= &snd_hda_bind_sw
,
7777 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT
),
7778 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT
),
7783 static struct snd_kcontrol_new alc883_asus_eee1601_mixer
[] = {
7784 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7785 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
7786 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7787 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7788 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7795 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer
[] = {
7796 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol
),
7797 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch
),
7799 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
7800 /* .name = "Capture Source", */
7801 .name
= "Input Source",
7803 .info
= alc_mux_enum_info
,
7804 .get
= alc_mux_enum_get
,
7805 .put
= alc_mux_enum_put
,
7810 static struct snd_kcontrol_new alc883_chmode_mixer
[] = {
7812 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
7813 .name
= "Channel Mode",
7814 .info
= alc_ch_mode_info
,
7815 .get
= alc_ch_mode_get
,
7816 .put
= alc_ch_mode_put
,
7821 static struct hda_verb alc883_init_verbs
[] = {
7822 /* ADC1: mute amp left and right */
7823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7824 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
7825 /* ADC2: mute amp left and right */
7826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7827 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
7828 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7831 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7833 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7834 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7835 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7837 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7843 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7845 /* mute analog input loopbacks */
7846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
7847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
7849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
7850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
7852 /* Front Pin: output 0 (0x0c) */
7853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7854 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7855 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
7856 /* Rear Pin: output 1 (0x0d) */
7857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7859 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
7860 /* CLFE Pin: output 2 (0x0e) */
7861 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7862 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7863 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
7864 /* Side Pin: output 3 (0x0f) */
7865 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7866 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7867 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
7868 /* Mic (rear) pin: input vref at 80% */
7869 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7871 /* Front Mic pin: input vref at 80% */
7872 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
7873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7874 /* Line In pin: input */
7875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
7876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
7877 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7878 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7879 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7880 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
7881 /* CD pin widget for input */
7882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
7884 /* FIXME: use matrix-type input source selection */
7885 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7889 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
7890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
7892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
7894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
7895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
7899 /* toggle speaker-output according to the hp-jack state */
7900 static void alc883_mitac_hp_automute(struct hda_codec
*codec
)
7902 unsigned int present
;
7904 present
= snd_hda_codec_read(codec
, 0x15, 0,
7905 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
7906 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
7907 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
7908 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
7909 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
7912 /* auto-toggle front mic */
7914 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7916 unsigned int present;
7919 present = snd_hda_codec_read(codec, 0x18, 0,
7920 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7921 bits = present ? HDA_AMP_MUTE : 0;
7922 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7926 static void alc883_mitac_automute(struct hda_codec
*codec
)
7928 alc883_mitac_hp_automute(codec
);
7929 /* alc883_mitac_mic_automute(codec); */
7932 static void alc883_mitac_unsol_event(struct hda_codec
*codec
,
7935 switch (res
>> 26) {
7936 case ALC880_HP_EVENT
:
7937 alc883_mitac_hp_automute(codec
);
7939 case ALC880_MIC_EVENT
:
7940 /* alc883_mitac_mic_automute(codec); */
7945 static struct hda_verb alc883_mitac_verbs
[] = {
7947 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
7948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7950 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x02},
7951 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7953 /* enable unsolicited event */
7954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
7955 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7960 static struct hda_verb alc883_clevo_m720_verbs
[] = {
7962 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
7963 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7965 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x01},
7966 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7968 /* enable unsolicited event */
7969 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
7970 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_MIC_EVENT
| AC_USRSP_EN
},
7975 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs
[] = {
7977 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
7978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7980 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
7981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7983 /* enable unsolicited event */
7984 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
7989 static struct hda_verb alc883_tagra_verbs
[] = {
7990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7994 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7996 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
7997 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
7998 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
8000 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8001 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
8002 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
8003 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
8008 static struct hda_verb alc883_lenovo_101e_verbs
[] = {
8009 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
8010 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_FRONT_EVENT
|AC_USRSP_EN
},
8011 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
|AC_USRSP_EN
},
8015 static struct hda_verb alc883_lenovo_nb0763_verbs
[] = {
8016 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
8017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8018 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8019 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8023 static struct hda_verb alc888_lenovo_ms7195_verbs
[] = {
8024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8026 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
8027 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_FRONT_EVENT
| AC_USRSP_EN
},
8028 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8032 static struct hda_verb alc883_haier_w66_verbs
[] = {
8033 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8034 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8038 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
8039 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8040 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8041 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8045 static struct hda_verb alc888_lenovo_sky_verbs
[] = {
8046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8049 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8050 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8051 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8052 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x00},
8053 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8057 static struct hda_verb alc888_3st_hp_verbs
[] = {
8058 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front: output 0 (0x0c) */
8059 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Rear : output 1 (0x0d) */
8060 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* CLFE : output 2 (0x0e) */
8064 static struct hda_verb alc888_6st_dell_verbs
[] = {
8065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8069 static struct hda_verb alc888_3st_hp_2ch_init
[] = {
8070 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
8071 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8072 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
8073 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8077 static struct hda_verb alc888_3st_hp_6ch_init
[] = {
8078 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8079 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8080 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8081 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8085 static struct hda_channel_mode alc888_3st_hp_modes
[2] = {
8086 { 2, alc888_3st_hp_2ch_init
},
8087 { 6, alc888_3st_hp_6ch_init
},
8090 /* toggle front-jack and RCA according to the hp-jack state */
8091 static void alc888_lenovo_ms7195_front_automute(struct hda_codec
*codec
)
8093 unsigned int present
;
8095 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8096 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8097 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8098 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8099 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8100 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8103 /* toggle RCA according to the front-jack state */
8104 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec
*codec
)
8106 unsigned int present
;
8108 present
= snd_hda_codec_read(codec
, 0x14, 0,
8109 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8110 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8111 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8114 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec
*codec
,
8117 if ((res
>> 26) == ALC880_HP_EVENT
)
8118 alc888_lenovo_ms7195_front_automute(codec
);
8119 if ((res
>> 26) == ALC880_FRONT_EVENT
)
8120 alc888_lenovo_ms7195_rca_automute(codec
);
8123 static struct hda_verb alc883_medion_md2_verbs
[] = {
8124 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8125 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8127 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8129 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8133 /* toggle speaker-output according to the hp-jack state */
8134 static void alc883_medion_md2_automute(struct hda_codec
*codec
)
8136 unsigned int present
;
8138 present
= snd_hda_codec_read(codec
, 0x14, 0,
8139 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8140 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8141 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8144 static void alc883_medion_md2_unsol_event(struct hda_codec
*codec
,
8147 if ((res
>> 26) == ALC880_HP_EVENT
)
8148 alc883_medion_md2_automute(codec
);
8151 /* toggle speaker-output according to the hp-jack state */
8152 static void alc883_tagra_automute(struct hda_codec
*codec
)
8154 unsigned int present
;
8157 present
= snd_hda_codec_read(codec
, 0x14, 0,
8158 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8159 bits
= present
? HDA_AMP_MUTE
: 0;
8160 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
8161 HDA_AMP_MUTE
, bits
);
8162 snd_hda_codec_write_cache(codec
, 1, 0, AC_VERB_SET_GPIO_DATA
,
8166 static void alc883_tagra_unsol_event(struct hda_codec
*codec
, unsigned int res
)
8168 if ((res
>> 26) == ALC880_HP_EVENT
)
8169 alc883_tagra_automute(codec
);
8172 /* toggle speaker-output according to the hp-jack state */
8173 static void alc883_clevo_m720_hp_automute(struct hda_codec
*codec
)
8175 unsigned int present
;
8178 present
= snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_GET_PIN_SENSE
, 0)
8179 & AC_PINSENSE_PRESENCE
;
8180 bits
= present
? HDA_AMP_MUTE
: 0;
8181 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8182 HDA_AMP_MUTE
, bits
);
8185 static void alc883_clevo_m720_mic_automute(struct hda_codec
*codec
)
8187 unsigned int present
;
8189 present
= snd_hda_codec_read(codec
, 0x18, 0,
8190 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8191 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, 1,
8192 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8195 static void alc883_clevo_m720_automute(struct hda_codec
*codec
)
8197 alc883_clevo_m720_hp_automute(codec
);
8198 alc883_clevo_m720_mic_automute(codec
);
8201 static void alc883_clevo_m720_unsol_event(struct hda_codec
*codec
,
8204 switch (res
>> 26) {
8205 case ALC880_HP_EVENT
:
8206 alc883_clevo_m720_hp_automute(codec
);
8208 case ALC880_MIC_EVENT
:
8209 alc883_clevo_m720_mic_automute(codec
);
8214 /* toggle speaker-output according to the hp-jack state */
8215 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec
*codec
)
8217 unsigned int present
;
8220 present
= snd_hda_codec_read(codec
, 0x14, 0, AC_VERB_GET_PIN_SENSE
, 0)
8221 & AC_PINSENSE_PRESENCE
;
8222 bits
= present
? HDA_AMP_MUTE
: 0;
8223 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8224 HDA_AMP_MUTE
, bits
);
8227 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec
*codec
,
8230 if ((res
>> 26) == ALC880_HP_EVENT
)
8231 alc883_2ch_fujitsu_pi2515_automute(codec
);
8234 static void alc883_haier_w66_automute(struct hda_codec
*codec
)
8236 unsigned int present
;
8239 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8240 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8241 bits
= present
? 0x80 : 0;
8242 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8246 static void alc883_haier_w66_unsol_event(struct hda_codec
*codec
,
8249 if ((res
>> 26) == ALC880_HP_EVENT
)
8250 alc883_haier_w66_automute(codec
);
8253 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec
*codec
)
8255 unsigned int present
;
8258 present
= snd_hda_codec_read(codec
, 0x14, 0,
8259 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8260 bits
= present
? HDA_AMP_MUTE
: 0;
8261 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8262 HDA_AMP_MUTE
, bits
);
8265 static void alc883_lenovo_101e_all_automute(struct hda_codec
*codec
)
8267 unsigned int present
;
8270 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8271 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8272 bits
= present
? HDA_AMP_MUTE
: 0;
8273 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8274 HDA_AMP_MUTE
, bits
);
8275 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8276 HDA_AMP_MUTE
, bits
);
8279 static void alc883_lenovo_101e_unsol_event(struct hda_codec
*codec
,
8282 if ((res
>> 26) == ALC880_HP_EVENT
)
8283 alc883_lenovo_101e_all_automute(codec
);
8284 if ((res
>> 26) == ALC880_FRONT_EVENT
)
8285 alc883_lenovo_101e_ispeaker_automute(codec
);
8288 /* toggle speaker-output according to the hp-jack state */
8289 static void alc883_acer_aspire_automute(struct hda_codec
*codec
)
8291 unsigned int present
;
8293 present
= snd_hda_codec_read(codec
, 0x14, 0,
8294 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8295 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8296 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8297 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
8298 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8301 static void alc883_acer_aspire_unsol_event(struct hda_codec
*codec
,
8304 if ((res
>> 26) == ALC880_HP_EVENT
)
8305 alc883_acer_aspire_automute(codec
);
8308 static struct hda_verb alc883_acer_eapd_verbs
[] = {
8309 /* HP Pin: output 0 (0x0c) */
8310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8312 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
8313 /* Front Pin: output 0 (0x0c) */
8314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8315 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
8316 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8317 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x00},
8318 /* eanable EAPD on medion laptop */
8319 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
8320 {0x20, AC_VERB_SET_PROC_COEF
, 0x3050},
8321 /* enable unsolicited event */
8322 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8326 static void alc888_6st_dell_front_automute(struct hda_codec
*codec
)
8328 unsigned int present
;
8330 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8331 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8332 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8333 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8334 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8335 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8336 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
8337 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8338 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
8339 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
8342 static void alc888_6st_dell_unsol_event(struct hda_codec
*codec
,
8345 switch (res
>> 26) {
8346 case ALC880_HP_EVENT
:
8347 /* printk(KERN_DEBUG "hp_event\n"); */
8348 alc888_6st_dell_front_automute(codec
);
8353 static void alc888_lenovo_sky_front_automute(struct hda_codec
*codec
)
8356 unsigned int present
;
8358 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
8359 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8360 AC_VERB_GET_PIN_SENSE
, 0);
8361 present
= (present
& 0x80000000) != 0;
8363 /* mute internal speaker */
8364 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8365 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
8366 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8367 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
8368 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
8369 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
8370 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
8371 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
8372 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_OUTPUT
, 0,
8373 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
8375 /* unmute internal speaker if necessary */
8376 mute
= snd_hda_codec_amp_read(codec
, 0x1b, 0, HDA_OUTPUT
, 0);
8377 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
8378 HDA_AMP_MUTE
, mute
);
8379 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
8380 HDA_AMP_MUTE
, mute
);
8381 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
8382 HDA_AMP_MUTE
, mute
);
8383 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
8384 HDA_AMP_MUTE
, mute
);
8385 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_OUTPUT
, 0,
8386 HDA_AMP_MUTE
, mute
);
8390 static void alc883_lenovo_sky_unsol_event(struct hda_codec
*codec
,
8393 if ((res
>> 26) == ALC880_HP_EVENT
)
8394 alc888_lenovo_sky_front_automute(codec
);
8398 * generic initialization of ADC, input mixers and output mixers
8400 static struct hda_verb alc883_auto_init_verbs
[] = {
8402 * Unmute ADC0-2 and set the default input to mic-in
8404 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
8405 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8406 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
8407 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8409 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8411 * Note: PASD motherboards uses the Line In 2 as the input for
8412 * front panel mic (mic 2)
8414 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8415 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
8416 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
8417 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
8418 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
8419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
8422 * Set up output mixers (0x0c - 0x0f)
8424 /* set vol=0 to output mixers */
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8426 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8429 /* set up input amps for analog loopback */
8430 /* Amp Indices: DAC = 0, mixer = 1 */
8431 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8432 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8433 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8434 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8435 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8436 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8437 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8439 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8440 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8442 /* FIXME: use matrix-type input source selection */
8443 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8445 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8446 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8447 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
8448 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
8451 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8452 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
8454 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8455 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
8460 static struct hda_verb alc888_asus_m90v_verbs
[] = {
8461 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
8462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
8463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8464 /* enable unsolicited event */
8465 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_MIC_EVENT
| AC_USRSP_EN
},
8470 static void alc883_nb_mic_automute(struct hda_codec
*codec
)
8472 unsigned int present
;
8474 present
= snd_hda_codec_read(codec
, 0x18, 0,
8475 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
8476 snd_hda_codec_write(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
8477 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
8478 snd_hda_codec_write(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
8479 0x7000 | (0x01 << 8) | (present
? 0x80 : 0));
8482 static void alc883_M90V_speaker_automute(struct hda_codec
*codec
)
8484 unsigned int present
;
8487 present
= snd_hda_codec_read(codec
, 0x1b, 0,
8488 AC_VERB_GET_PIN_SENSE
, 0)
8489 & AC_PINSENSE_PRESENCE
;
8490 bits
= present
? 0 : PIN_OUT
;
8491 snd_hda_codec_write(codec
, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
8493 snd_hda_codec_write(codec
, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
8495 snd_hda_codec_write(codec
, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
8499 static void alc883_mode2_unsol_event(struct hda_codec
*codec
,
8502 switch (res
>> 26) {
8503 case ALC880_HP_EVENT
:
8504 alc883_M90V_speaker_automute(codec
);
8506 case ALC880_MIC_EVENT
:
8507 alc883_nb_mic_automute(codec
);
8512 static void alc883_mode2_inithook(struct hda_codec
*codec
)
8514 alc883_M90V_speaker_automute(codec
);
8515 alc883_nb_mic_automute(codec
);
8518 static struct hda_verb alc888_asus_eee1601_verbs
[] = {
8519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
8520 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
8521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
8524 {0x20, AC_VERB_SET_COEF_INDEX
, 0x0b},
8525 {0x20, AC_VERB_SET_PROC_COEF
, 0x0838},
8526 /* enable unsolicited event */
8527 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
8531 static void alc883_eee1601_speaker_automute(struct hda_codec
*codec
)
8533 unsigned int present
;
8536 present
= snd_hda_codec_read(codec
, 0x14, 0,
8537 AC_VERB_GET_PIN_SENSE
, 0)
8538 & AC_PINSENSE_PRESENCE
;
8539 bits
= present
? 0 : PIN_OUT
;
8540 snd_hda_codec_write(codec
, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
8544 static void alc883_eee1601_unsol_event(struct hda_codec
*codec
,
8547 switch (res
>> 26) {
8548 case ALC880_HP_EVENT
:
8549 alc883_eee1601_speaker_automute(codec
);
8554 static void alc883_eee1601_inithook(struct hda_codec
*codec
)
8556 alc883_eee1601_speaker_automute(codec
);
8559 #ifdef CONFIG_SND_HDA_POWER_SAVE
8560 #define alc883_loopbacks alc880_loopbacks
8563 /* pcm configuration: identiacal with ALC880 */
8564 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8565 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8566 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8567 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8568 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8571 * configuration and preset
8573 static const char *alc883_models
[ALC883_MODEL_LAST
] = {
8574 [ALC883_3ST_2ch_DIG
] = "3stack-dig",
8575 [ALC883_3ST_6ch_DIG
] = "3stack-6ch-dig",
8576 [ALC883_3ST_6ch
] = "3stack-6ch",
8577 [ALC883_6ST_DIG
] = "6stack-dig",
8578 [ALC883_TARGA_DIG
] = "targa-dig",
8579 [ALC883_TARGA_2ch_DIG
] = "targa-2ch-dig",
8580 [ALC883_ACER
] = "acer",
8581 [ALC883_ACER_ASPIRE
] = "acer-aspire",
8582 [ALC888_ACER_ASPIRE_4930G
] = "acer-aspire-4930g",
8583 [ALC883_MEDION
] = "medion",
8584 [ALC883_MEDION_MD2
] = "medion-md2",
8585 [ALC883_LAPTOP_EAPD
] = "laptop-eapd",
8586 [ALC883_LENOVO_101E_2ch
] = "lenovo-101e",
8587 [ALC883_LENOVO_NB0763
] = "lenovo-nb0763",
8588 [ALC888_LENOVO_MS7195_DIG
] = "lenovo-ms7195-dig",
8589 [ALC888_LENOVO_SKY
] = "lenovo-sky",
8590 [ALC883_HAIER_W66
] = "haier-w66",
8591 [ALC888_3ST_HP
] = "3stack-hp",
8592 [ALC888_6ST_DELL
] = "6stack-dell",
8593 [ALC883_MITAC
] = "mitac",
8594 [ALC883_CLEVO_M720
] = "clevo-m720",
8595 [ALC883_FUJITSU_PI2515
] = "fujitsu-pi2515",
8596 [ALC888_FUJITSU_XA3530
] = "fujitsu-xa3530",
8597 [ALC883_3ST_6ch_INTEL
] = "3stack-6ch-intel",
8598 [ALC1200_ASUS_P5Q
] = "asus-p5q",
8599 [ALC883_AUTO
] = "auto",
8602 static struct snd_pci_quirk alc883_cfg_tbl
[] = {
8603 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG
),
8604 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE
),
8605 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE
),
8606 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE
),
8607 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE
),
8608 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE
),
8609 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8610 ALC888_ACER_ASPIRE_4930G
),
8611 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8612 ALC888_ACER_ASPIRE_4930G
),
8613 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO
),
8614 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO
),
8615 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8616 ALC888_ACER_ASPIRE_4930G
),
8617 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8618 ALC888_ACER_ASPIRE_4930G
),
8620 SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER
),
8621 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL
),
8622 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG
),
8623 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP
),
8624 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP
),
8625 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG
),
8626 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP
),
8627 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V
),
8628 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG
),
8629 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG
),
8630 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q
),
8631 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601
),
8632 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG
),
8633 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG
),
8634 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC
),
8635 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC
),
8636 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD
),
8637 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL
),
8638 SND_PCI_QUIRK(0x108e, 0x534d, NULL
, ALC883_3ST_6ch
),
8639 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG
),
8640 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG
),
8641 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG
),
8642 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG
),
8643 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG
),
8644 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG
),
8645 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG
),
8646 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG
),
8647 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG
),
8648 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG
),
8649 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG
),
8650 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG
),
8651 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG
),
8652 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG
),
8653 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG
),
8654 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG
),
8655 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG
),
8656 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG
),
8657 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG
),
8658 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG
),
8659 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG
),
8660 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG
),
8661 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG
),
8662 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG
),
8663 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG
),
8664 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720
),
8665 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720
),
8666 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD
),
8667 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch
),
8668 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION
),
8669 SND_PCI_QUIRK(0x1734, 0x1107, "FSC AMILO Xi2550",
8670 ALC883_FUJITSU_PI2515
),
8671 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515
),
8672 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8673 ALC888_FUJITSU_XA3530
),
8674 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch
),
8675 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763
),
8676 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763
),
8677 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763
),
8678 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY
),
8679 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2
),
8680 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG
),
8681 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG
),
8682 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66
),
8683 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL
),
8684 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL
),
8685 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC
),
8686 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL
),
8687 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch
),
8691 static hda_nid_t alc1200_slave_dig_outs
[] = {
8692 ALC883_DIGOUT_NID
, 0,
8695 static struct alc_config_preset alc883_presets
[] = {
8696 [ALC883_3ST_2ch_DIG
] = {
8697 .mixers
= { alc883_3ST_2ch_mixer
},
8698 .init_verbs
= { alc883_init_verbs
},
8699 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8700 .dac_nids
= alc883_dac_nids
,
8701 .dig_out_nid
= ALC883_DIGOUT_NID
,
8702 .dig_in_nid
= ALC883_DIGIN_NID
,
8703 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8704 .channel_mode
= alc883_3ST_2ch_modes
,
8705 .input_mux
= &alc883_capture_source
,
8707 [ALC883_3ST_6ch_DIG
] = {
8708 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
8709 .init_verbs
= { alc883_init_verbs
},
8710 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8711 .dac_nids
= alc883_dac_nids
,
8712 .dig_out_nid
= ALC883_DIGOUT_NID
,
8713 .dig_in_nid
= ALC883_DIGIN_NID
,
8714 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
8715 .channel_mode
= alc883_3ST_6ch_modes
,
8717 .input_mux
= &alc883_capture_source
,
8719 [ALC883_3ST_6ch
] = {
8720 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
8721 .init_verbs
= { alc883_init_verbs
},
8722 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8723 .dac_nids
= alc883_dac_nids
,
8724 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
8725 .channel_mode
= alc883_3ST_6ch_modes
,
8727 .input_mux
= &alc883_capture_source
,
8729 [ALC883_3ST_6ch_INTEL
] = {
8730 .mixers
= { alc883_3ST_6ch_intel_mixer
, alc883_chmode_mixer
},
8731 .init_verbs
= { alc883_init_verbs
},
8732 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8733 .dac_nids
= alc883_dac_nids
,
8734 .dig_out_nid
= ALC883_DIGOUT_NID
,
8735 .dig_in_nid
= ALC883_DIGIN_NID
,
8736 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_intel_modes
),
8737 .channel_mode
= alc883_3ST_6ch_intel_modes
,
8739 .input_mux
= &alc883_3stack_6ch_intel
,
8741 [ALC883_6ST_DIG
] = {
8742 .mixers
= { alc883_base_mixer
, alc883_chmode_mixer
},
8743 .init_verbs
= { alc883_init_verbs
},
8744 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8745 .dac_nids
= alc883_dac_nids
,
8746 .dig_out_nid
= ALC883_DIGOUT_NID
,
8747 .dig_in_nid
= ALC883_DIGIN_NID
,
8748 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
8749 .channel_mode
= alc883_sixstack_modes
,
8750 .input_mux
= &alc883_capture_source
,
8752 [ALC883_TARGA_DIG
] = {
8753 .mixers
= { alc883_tagra_mixer
, alc883_chmode_mixer
},
8754 .init_verbs
= { alc883_init_verbs
, alc883_tagra_verbs
},
8755 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8756 .dac_nids
= alc883_dac_nids
,
8757 .dig_out_nid
= ALC883_DIGOUT_NID
,
8758 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
8759 .channel_mode
= alc883_3ST_6ch_modes
,
8761 .input_mux
= &alc883_capture_source
,
8762 .unsol_event
= alc883_tagra_unsol_event
,
8763 .init_hook
= alc883_tagra_automute
,
8765 [ALC883_TARGA_2ch_DIG
] = {
8766 .mixers
= { alc883_tagra_2ch_mixer
},
8767 .init_verbs
= { alc883_init_verbs
, alc883_tagra_verbs
},
8768 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8769 .dac_nids
= alc883_dac_nids
,
8770 .adc_nids
= alc883_adc_nids_alt
,
8771 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids_alt
),
8772 .dig_out_nid
= ALC883_DIGOUT_NID
,
8773 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8774 .channel_mode
= alc883_3ST_2ch_modes
,
8775 .input_mux
= &alc883_capture_source
,
8776 .unsol_event
= alc883_tagra_unsol_event
,
8777 .init_hook
= alc883_tagra_automute
,
8780 .mixers
= { alc883_base_mixer
},
8781 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8782 * and the headphone jack. Turn this on and rely on the
8783 * standard mute methods whenever the user wants to turn
8784 * these outputs off.
8786 .init_verbs
= { alc883_init_verbs
, alc880_gpio1_init_verbs
},
8787 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8788 .dac_nids
= alc883_dac_nids
,
8789 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8790 .channel_mode
= alc883_3ST_2ch_modes
,
8791 .input_mux
= &alc883_capture_source
,
8793 [ALC883_ACER_ASPIRE
] = {
8794 .mixers
= { alc883_acer_aspire_mixer
},
8795 .init_verbs
= { alc883_init_verbs
, alc883_acer_eapd_verbs
},
8796 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8797 .dac_nids
= alc883_dac_nids
,
8798 .dig_out_nid
= ALC883_DIGOUT_NID
,
8799 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8800 .channel_mode
= alc883_3ST_2ch_modes
,
8801 .input_mux
= &alc883_capture_source
,
8802 .unsol_event
= alc883_acer_aspire_unsol_event
,
8803 .init_hook
= alc883_acer_aspire_automute
,
8805 [ALC888_ACER_ASPIRE_4930G
] = {
8806 .mixers
= { alc888_base_mixer
,
8807 alc883_chmode_mixer
},
8808 .init_verbs
= { alc883_init_verbs
, alc880_gpio1_init_verbs
,
8809 alc888_acer_aspire_4930g_verbs
},
8810 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8811 .dac_nids
= alc883_dac_nids
,
8812 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids_rev
),
8813 .adc_nids
= alc883_adc_nids_rev
,
8814 .capsrc_nids
= alc883_capsrc_nids_rev
,
8815 .dig_out_nid
= ALC883_DIGOUT_NID
,
8816 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
8817 .channel_mode
= alc883_3ST_6ch_modes
,
8820 ARRAY_SIZE(alc888_2_capture_sources
),
8821 .input_mux
= alc888_2_capture_sources
,
8822 .unsol_event
= alc888_acer_aspire_4930g_unsol_event
,
8823 .init_hook
= alc888_acer_aspire_4930g_automute
,
8826 .mixers
= { alc883_fivestack_mixer
,
8827 alc883_chmode_mixer
},
8828 .init_verbs
= { alc883_init_verbs
,
8829 alc883_medion_eapd_verbs
},
8830 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8831 .dac_nids
= alc883_dac_nids
,
8832 .adc_nids
= alc883_adc_nids_alt
,
8833 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids_alt
),
8834 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
8835 .channel_mode
= alc883_sixstack_modes
,
8836 .input_mux
= &alc883_capture_source
,
8838 [ALC883_MEDION_MD2
] = {
8839 .mixers
= { alc883_medion_md2_mixer
},
8840 .init_verbs
= { alc883_init_verbs
, alc883_medion_md2_verbs
},
8841 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8842 .dac_nids
= alc883_dac_nids
,
8843 .dig_out_nid
= ALC883_DIGOUT_NID
,
8844 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8845 .channel_mode
= alc883_3ST_2ch_modes
,
8846 .input_mux
= &alc883_capture_source
,
8847 .unsol_event
= alc883_medion_md2_unsol_event
,
8848 .init_hook
= alc883_medion_md2_automute
,
8850 [ALC883_LAPTOP_EAPD
] = {
8851 .mixers
= { alc883_base_mixer
},
8852 .init_verbs
= { alc883_init_verbs
, alc882_eapd_verbs
},
8853 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8854 .dac_nids
= alc883_dac_nids
,
8855 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8856 .channel_mode
= alc883_3ST_2ch_modes
,
8857 .input_mux
= &alc883_capture_source
,
8859 [ALC883_CLEVO_M720
] = {
8860 .mixers
= { alc883_clevo_m720_mixer
},
8861 .init_verbs
= { alc883_init_verbs
, alc883_clevo_m720_verbs
},
8862 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8863 .dac_nids
= alc883_dac_nids
,
8864 .dig_out_nid
= ALC883_DIGOUT_NID
,
8865 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8866 .channel_mode
= alc883_3ST_2ch_modes
,
8867 .input_mux
= &alc883_capture_source
,
8868 .unsol_event
= alc883_clevo_m720_unsol_event
,
8869 .init_hook
= alc883_clevo_m720_automute
,
8871 [ALC883_LENOVO_101E_2ch
] = {
8872 .mixers
= { alc883_lenovo_101e_2ch_mixer
},
8873 .init_verbs
= { alc883_init_verbs
, alc883_lenovo_101e_verbs
},
8874 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8875 .dac_nids
= alc883_dac_nids
,
8876 .adc_nids
= alc883_adc_nids_alt
,
8877 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids_alt
),
8878 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8879 .channel_mode
= alc883_3ST_2ch_modes
,
8880 .input_mux
= &alc883_lenovo_101e_capture_source
,
8881 .unsol_event
= alc883_lenovo_101e_unsol_event
,
8882 .init_hook
= alc883_lenovo_101e_all_automute
,
8884 [ALC883_LENOVO_NB0763
] = {
8885 .mixers
= { alc883_lenovo_nb0763_mixer
},
8886 .init_verbs
= { alc883_init_verbs
, alc883_lenovo_nb0763_verbs
},
8887 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8888 .dac_nids
= alc883_dac_nids
,
8889 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8890 .channel_mode
= alc883_3ST_2ch_modes
,
8892 .input_mux
= &alc883_lenovo_nb0763_capture_source
,
8893 .unsol_event
= alc883_medion_md2_unsol_event
,
8894 .init_hook
= alc883_medion_md2_automute
,
8896 [ALC888_LENOVO_MS7195_DIG
] = {
8897 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
8898 .init_verbs
= { alc883_init_verbs
, alc888_lenovo_ms7195_verbs
},
8899 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8900 .dac_nids
= alc883_dac_nids
,
8901 .dig_out_nid
= ALC883_DIGOUT_NID
,
8902 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
8903 .channel_mode
= alc883_3ST_6ch_modes
,
8905 .input_mux
= &alc883_capture_source
,
8906 .unsol_event
= alc883_lenovo_ms7195_unsol_event
,
8907 .init_hook
= alc888_lenovo_ms7195_front_automute
,
8909 [ALC883_HAIER_W66
] = {
8910 .mixers
= { alc883_tagra_2ch_mixer
},
8911 .init_verbs
= { alc883_init_verbs
, alc883_haier_w66_verbs
},
8912 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8913 .dac_nids
= alc883_dac_nids
,
8914 .dig_out_nid
= ALC883_DIGOUT_NID
,
8915 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8916 .channel_mode
= alc883_3ST_2ch_modes
,
8917 .input_mux
= &alc883_capture_source
,
8918 .unsol_event
= alc883_haier_w66_unsol_event
,
8919 .init_hook
= alc883_haier_w66_automute
,
8922 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
8923 .init_verbs
= { alc883_init_verbs
, alc888_3st_hp_verbs
},
8924 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8925 .dac_nids
= alc883_dac_nids
,
8926 .num_channel_mode
= ARRAY_SIZE(alc888_3st_hp_modes
),
8927 .channel_mode
= alc888_3st_hp_modes
,
8929 .input_mux
= &alc883_capture_source
,
8931 [ALC888_6ST_DELL
] = {
8932 .mixers
= { alc883_base_mixer
, alc883_chmode_mixer
},
8933 .init_verbs
= { alc883_init_verbs
, alc888_6st_dell_verbs
},
8934 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8935 .dac_nids
= alc883_dac_nids
,
8936 .dig_out_nid
= ALC883_DIGOUT_NID
,
8937 .dig_in_nid
= ALC883_DIGIN_NID
,
8938 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
8939 .channel_mode
= alc883_sixstack_modes
,
8940 .input_mux
= &alc883_capture_source
,
8941 .unsol_event
= alc888_6st_dell_unsol_event
,
8942 .init_hook
= alc888_6st_dell_front_automute
,
8945 .mixers
= { alc883_mitac_mixer
},
8946 .init_verbs
= { alc883_init_verbs
, alc883_mitac_verbs
},
8947 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8948 .dac_nids
= alc883_dac_nids
,
8949 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8950 .channel_mode
= alc883_3ST_2ch_modes
,
8951 .input_mux
= &alc883_capture_source
,
8952 .unsol_event
= alc883_mitac_unsol_event
,
8953 .init_hook
= alc883_mitac_automute
,
8955 [ALC883_FUJITSU_PI2515
] = {
8956 .mixers
= { alc883_2ch_fujitsu_pi2515_mixer
},
8957 .init_verbs
= { alc883_init_verbs
,
8958 alc883_2ch_fujitsu_pi2515_verbs
},
8959 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8960 .dac_nids
= alc883_dac_nids
,
8961 .dig_out_nid
= ALC883_DIGOUT_NID
,
8962 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
8963 .channel_mode
= alc883_3ST_2ch_modes
,
8964 .input_mux
= &alc883_fujitsu_pi2515_capture_source
,
8965 .unsol_event
= alc883_2ch_fujitsu_pi2515_unsol_event
,
8966 .init_hook
= alc883_2ch_fujitsu_pi2515_automute
,
8968 [ALC888_FUJITSU_XA3530
] = {
8969 .mixers
= { alc888_base_mixer
, alc883_chmode_mixer
},
8970 .init_verbs
= { alc883_init_verbs
,
8971 alc888_fujitsu_xa3530_verbs
},
8972 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8973 .dac_nids
= alc883_dac_nids
,
8974 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids_rev
),
8975 .adc_nids
= alc883_adc_nids_rev
,
8976 .capsrc_nids
= alc883_capsrc_nids_rev
,
8977 .dig_out_nid
= ALC883_DIGOUT_NID
,
8978 .num_channel_mode
= ARRAY_SIZE(alc888_4ST_8ch_intel_modes
),
8979 .channel_mode
= alc888_4ST_8ch_intel_modes
,
8981 ARRAY_SIZE(alc888_2_capture_sources
),
8982 .input_mux
= alc888_2_capture_sources
,
8983 .unsol_event
= alc888_fujitsu_xa3530_unsol_event
,
8984 .init_hook
= alc888_fujitsu_xa3530_automute
,
8986 [ALC888_LENOVO_SKY
] = {
8987 .mixers
= { alc888_lenovo_sky_mixer
, alc883_chmode_mixer
},
8988 .init_verbs
= { alc883_init_verbs
, alc888_lenovo_sky_verbs
},
8989 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
8990 .dac_nids
= alc883_dac_nids
,
8991 .dig_out_nid
= ALC883_DIGOUT_NID
,
8992 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
8993 .channel_mode
= alc883_sixstack_modes
,
8995 .input_mux
= &alc883_lenovo_sky_capture_source
,
8996 .unsol_event
= alc883_lenovo_sky_unsol_event
,
8997 .init_hook
= alc888_lenovo_sky_front_automute
,
8999 [ALC888_ASUS_M90V
] = {
9000 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
9001 .init_verbs
= { alc883_init_verbs
, alc888_asus_m90v_verbs
},
9002 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
9003 .dac_nids
= alc883_dac_nids
,
9004 .dig_out_nid
= ALC883_DIGOUT_NID
,
9005 .dig_in_nid
= ALC883_DIGIN_NID
,
9006 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
9007 .channel_mode
= alc883_3ST_6ch_modes
,
9009 .input_mux
= &alc883_fujitsu_pi2515_capture_source
,
9010 .unsol_event
= alc883_mode2_unsol_event
,
9011 .init_hook
= alc883_mode2_inithook
,
9013 [ALC888_ASUS_EEE1601
] = {
9014 .mixers
= { alc883_asus_eee1601_mixer
},
9015 .cap_mixer
= alc883_asus_eee1601_cap_mixer
,
9016 .init_verbs
= { alc883_init_verbs
, alc888_asus_eee1601_verbs
},
9017 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
9018 .dac_nids
= alc883_dac_nids
,
9019 .dig_out_nid
= ALC883_DIGOUT_NID
,
9020 .dig_in_nid
= ALC883_DIGIN_NID
,
9021 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
9022 .channel_mode
= alc883_3ST_2ch_modes
,
9024 .input_mux
= &alc883_asus_eee1601_capture_source
,
9025 .unsol_event
= alc883_eee1601_unsol_event
,
9026 .init_hook
= alc883_eee1601_inithook
,
9028 [ALC1200_ASUS_P5Q
] = {
9029 .mixers
= { alc883_base_mixer
, alc883_chmode_mixer
},
9030 .init_verbs
= { alc883_init_verbs
},
9031 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
9032 .dac_nids
= alc883_dac_nids
,
9033 .dig_out_nid
= ALC1200_DIGOUT_NID
,
9034 .dig_in_nid
= ALC883_DIGIN_NID
,
9035 .slave_dig_outs
= alc1200_slave_dig_outs
,
9036 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
9037 .channel_mode
= alc883_sixstack_modes
,
9038 .input_mux
= &alc883_capture_source
,
9044 * BIOS auto configuration
9046 static void alc883_auto_set_output_and_unmute(struct hda_codec
*codec
,
9047 hda_nid_t nid
, int pin_type
,
9051 struct alc_spec
*spec
= codec
->spec
;
9054 alc_set_pin_output(codec
, nid
, pin_type
);
9055 if (spec
->multiout
.dac_nids
[dac_idx
] == 0x25)
9058 idx
= spec
->multiout
.dac_nids
[dac_idx
] - 2;
9059 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_CONNECT_SEL
, idx
);
9063 static void alc883_auto_init_multi_out(struct hda_codec
*codec
)
9065 struct alc_spec
*spec
= codec
->spec
;
9068 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
9069 for (i
= 0; i
<= HDA_SIDE
; i
++) {
9070 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
9071 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
9073 alc883_auto_set_output_and_unmute(codec
, nid
, pin_type
,
9078 static void alc883_auto_init_hp_out(struct hda_codec
*codec
)
9080 struct alc_spec
*spec
= codec
->spec
;
9083 pin
= spec
->autocfg
.hp_pins
[0];
9084 if (pin
) /* connect to front */
9086 alc883_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
9087 pin
= spec
->autocfg
.speaker_pins
[0];
9089 alc883_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
9092 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9093 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9095 static void alc883_auto_init_analog_input(struct hda_codec
*codec
)
9097 struct alc_spec
*spec
= codec
->spec
;
9100 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
9101 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
9102 if (alc883_is_input_pin(nid
)) {
9103 snd_hda_codec_write(codec
, nid
, 0,
9104 AC_VERB_SET_PIN_WIDGET_CONTROL
,
9105 (i
<= AUTO_PIN_FRONT_MIC
?
9106 PIN_VREF80
: PIN_IN
));
9107 if (nid
!= ALC883_PIN_CD_NID
)
9108 snd_hda_codec_write(codec
, nid
, 0,
9109 AC_VERB_SET_AMP_GAIN_MUTE
,
9115 #define alc883_auto_init_input_src alc882_auto_init_input_src
9117 /* almost identical with ALC880 parser... */
9118 static int alc883_parse_auto_config(struct hda_codec
*codec
)
9120 struct alc_spec
*spec
= codec
->spec
;
9121 int err
= alc880_parse_auto_config(codec
);
9122 struct auto_pin_cfg
*cfg
= &spec
->autocfg
;
9128 return 0; /* no config found */
9130 err
= alc_auto_add_mic_boost(codec
);
9134 /* hack - override the init verbs */
9135 spec
->init_verbs
[0] = alc883_auto_init_verbs
;
9137 /* setup input_mux for ALC889 */
9138 if (codec
->vendor_id
== 0x10ec0889) {
9139 /* digital-mic input pin is excluded in alc880_auto_create..()
9140 * because it's under 0x18
9142 if (cfg
->input_pins
[AUTO_PIN_MIC
] == 0x12 ||
9143 cfg
->input_pins
[AUTO_PIN_FRONT_MIC
] == 0x12) {
9144 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
9145 for (i
= 1; i
< 3; i
++)
9146 memcpy(&spec
->private_imux
[i
],
9147 &spec
->private_imux
[0],
9148 sizeof(spec
->private_imux
[0]));
9149 imux
->items
[imux
->num_items
].label
= "Int DMic";
9150 imux
->items
[imux
->num_items
].index
= 0x0b;
9152 spec
->num_mux_defs
= 3;
9153 spec
->input_mux
= spec
->private_imux
;
9157 return 1; /* config found */
9160 /* additional initialization for auto-configuration model */
9161 static void alc883_auto_init(struct hda_codec
*codec
)
9163 struct alc_spec
*spec
= codec
->spec
;
9164 alc883_auto_init_multi_out(codec
);
9165 alc883_auto_init_hp_out(codec
);
9166 alc883_auto_init_analog_input(codec
);
9167 alc883_auto_init_input_src(codec
);
9168 if (spec
->unsol_event
)
9169 alc_inithook(codec
);
9172 static int patch_alc883(struct hda_codec
*codec
)
9174 struct alc_spec
*spec
;
9175 int err
, board_config
;
9177 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
9183 alc_fix_pll_init(codec
, 0x20, 0x0a, 10);
9185 board_config
= snd_hda_check_board_config(codec
, ALC883_MODEL_LAST
,
9188 if (board_config
< 0) {
9189 printk(KERN_INFO
"hda_codec: Unknown model for ALC883, "
9190 "trying auto-probe from BIOS...\n");
9191 board_config
= ALC883_AUTO
;
9194 if (board_config
== ALC883_AUTO
) {
9195 /* automatic parse from the BIOS config */
9196 err
= alc883_parse_auto_config(codec
);
9202 "hda_codec: Cannot set up configuration "
9203 "from BIOS. Using base mode...\n");
9204 board_config
= ALC883_3ST_2ch_DIG
;
9208 err
= snd_hda_attach_beep_device(codec
, 0x1);
9214 if (board_config
!= ALC883_AUTO
)
9215 setup_preset(spec
, &alc883_presets
[board_config
]);
9217 switch (codec
->vendor_id
) {
9219 if (codec
->revision_id
== 0x100101) {
9220 spec
->stream_name_analog
= "ALC1200 Analog";
9221 spec
->stream_name_digital
= "ALC1200 Digital";
9223 spec
->stream_name_analog
= "ALC888 Analog";
9224 spec
->stream_name_digital
= "ALC888 Digital";
9226 if (!spec
->num_adc_nids
) {
9227 spec
->num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
);
9228 spec
->adc_nids
= alc883_adc_nids
;
9230 if (!spec
->capsrc_nids
)
9231 spec
->capsrc_nids
= alc883_capsrc_nids
;
9232 spec
->capture_style
= CAPT_MIX
; /* matrix-style capture */
9235 spec
->stream_name_analog
= "ALC889 Analog";
9236 spec
->stream_name_digital
= "ALC889 Digital";
9237 if (!spec
->num_adc_nids
) {
9238 spec
->num_adc_nids
= ARRAY_SIZE(alc889_adc_nids
);
9239 spec
->adc_nids
= alc889_adc_nids
;
9241 if (!spec
->capsrc_nids
)
9242 spec
->capsrc_nids
= alc889_capsrc_nids
;
9243 spec
->capture_style
= CAPT_1MUX_MIX
; /* 1mux/Nmix-style
9247 spec
->stream_name_analog
= "ALC883 Analog";
9248 spec
->stream_name_digital
= "ALC883 Digital";
9249 if (!spec
->num_adc_nids
) {
9250 spec
->num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
);
9251 spec
->adc_nids
= alc883_adc_nids
;
9253 if (!spec
->capsrc_nids
)
9254 spec
->capsrc_nids
= alc883_capsrc_nids
;
9255 spec
->capture_style
= CAPT_MIX
; /* matrix-style capture */
9259 spec
->stream_analog_playback
= &alc883_pcm_analog_playback
;
9260 spec
->stream_analog_capture
= &alc883_pcm_analog_capture
;
9261 spec
->stream_analog_alt_capture
= &alc883_pcm_analog_alt_capture
;
9263 spec
->stream_digital_playback
= &alc883_pcm_digital_playback
;
9264 spec
->stream_digital_capture
= &alc883_pcm_digital_capture
;
9266 if (!spec
->cap_mixer
)
9267 set_capture_mixer(spec
);
9268 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
9270 spec
->vmaster_nid
= 0x0c;
9272 codec
->patch_ops
= alc_patch_ops
;
9273 if (board_config
== ALC883_AUTO
)
9274 spec
->init_hook
= alc883_auto_init
;
9276 #ifdef CONFIG_SND_HDA_POWER_SAVE
9277 if (!spec
->loopback
.amplist
)
9278 spec
->loopback
.amplist
= alc883_loopbacks
;
9280 codec
->proc_widget_hook
= print_realtek_coef
;
9289 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9290 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9292 #define alc262_dac_nids alc260_dac_nids
9293 #define alc262_adc_nids alc882_adc_nids
9294 #define alc262_adc_nids_alt alc882_adc_nids_alt
9295 #define alc262_capsrc_nids alc882_capsrc_nids
9296 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9298 #define alc262_modes alc260_modes
9299 #define alc262_capture_source alc882_capture_source
9301 static hda_nid_t alc262_dmic_adc_nids
[1] = {
9306 static hda_nid_t alc262_dmic_capsrc_nids
[1] = { 0x22 };
9308 static struct snd_kcontrol_new alc262_base_mixer
[] = {
9309 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9310 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9311 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9312 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9313 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9314 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9317 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9318 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9319 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9320 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9321 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT
),
9322 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9323 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
9324 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
9328 static struct snd_kcontrol_new alc262_hippo1_mixer
[] = {
9329 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9330 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9337 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9338 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9339 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9340 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9341 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9346 /* update HP, line and mono-out pins according to the master switch */
9347 static void alc262_hp_master_update(struct hda_codec
*codec
)
9349 struct alc_spec
*spec
= codec
->spec
;
9350 int val
= spec
->master_sw
;
9353 snd_hda_codec_write_cache(codec
, 0x1b, 0,
9354 AC_VERB_SET_PIN_WIDGET_CONTROL
,
9356 snd_hda_codec_write_cache(codec
, 0x15, 0,
9357 AC_VERB_SET_PIN_WIDGET_CONTROL
,
9359 /* mono (speaker) depending on the HP jack sense */
9360 val
= val
&& !spec
->jack_present
;
9361 snd_hda_codec_write_cache(codec
, 0x16, 0,
9362 AC_VERB_SET_PIN_WIDGET_CONTROL
,
9366 static void alc262_hp_bpc_automute(struct hda_codec
*codec
)
9368 struct alc_spec
*spec
= codec
->spec
;
9369 unsigned int presence
;
9370 presence
= snd_hda_codec_read(codec
, 0x1b, 0,
9371 AC_VERB_GET_PIN_SENSE
, 0);
9372 spec
->jack_present
= !!(presence
& AC_PINSENSE_PRESENCE
);
9373 alc262_hp_master_update(codec
);
9376 static void alc262_hp_bpc_unsol_event(struct hda_codec
*codec
, unsigned int res
)
9378 if ((res
>> 26) != ALC880_HP_EVENT
)
9380 alc262_hp_bpc_automute(codec
);
9383 static void alc262_hp_wildwest_automute(struct hda_codec
*codec
)
9385 struct alc_spec
*spec
= codec
->spec
;
9386 unsigned int presence
;
9387 presence
= snd_hda_codec_read(codec
, 0x15, 0,
9388 AC_VERB_GET_PIN_SENSE
, 0);
9389 spec
->jack_present
= !!(presence
& AC_PINSENSE_PRESENCE
);
9390 alc262_hp_master_update(codec
);
9393 static void alc262_hp_wildwest_unsol_event(struct hda_codec
*codec
,
9396 if ((res
>> 26) != ALC880_HP_EVENT
)
9398 alc262_hp_wildwest_automute(codec
);
9401 static int alc262_hp_master_sw_get(struct snd_kcontrol
*kcontrol
,
9402 struct snd_ctl_elem_value
*ucontrol
)
9404 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
9405 struct alc_spec
*spec
= codec
->spec
;
9406 *ucontrol
->value
.integer
.value
= spec
->master_sw
;
9410 static int alc262_hp_master_sw_put(struct snd_kcontrol
*kcontrol
,
9411 struct snd_ctl_elem_value
*ucontrol
)
9413 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
9414 struct alc_spec
*spec
= codec
->spec
;
9415 int val
= !!*ucontrol
->value
.integer
.value
;
9417 if (val
== spec
->master_sw
)
9419 spec
->master_sw
= val
;
9420 alc262_hp_master_update(codec
);
9424 static struct snd_kcontrol_new alc262_HP_BPC_mixer
[] = {
9426 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9427 .name
= "Master Playback Switch",
9428 .info
= snd_ctl_boolean_mono_info
,
9429 .get
= alc262_hp_master_sw_get
,
9430 .put
= alc262_hp_master_sw_put
,
9432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9433 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9434 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9435 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9437 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9441 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9442 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9443 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9444 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9449 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT
),
9450 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT
),
9454 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer
[] = {
9456 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9457 .name
= "Master Playback Switch",
9458 .info
= snd_ctl_boolean_mono_info
,
9459 .get
= alc262_hp_master_sw_get
,
9460 .put
= alc262_hp_master_sw_put
,
9462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9463 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9464 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
9465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9466 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9468 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9470 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9471 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9472 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT
),
9473 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9474 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9475 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9476 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9480 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer
[] = {
9481 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9482 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9483 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT
),
9487 /* mute/unmute internal speaker according to the hp jack and mute state */
9488 static void alc262_hp_t5735_automute(struct hda_codec
*codec
, int force
)
9490 struct alc_spec
*spec
= codec
->spec
;
9492 if (force
|| !spec
->sense_updated
) {
9493 unsigned int present
;
9494 present
= snd_hda_codec_read(codec
, 0x15, 0,
9495 AC_VERB_GET_PIN_SENSE
, 0);
9496 spec
->jack_present
= (present
& AC_PINSENSE_PRESENCE
) != 0;
9497 spec
->sense_updated
= 1;
9499 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_OUTPUT
, 0, HDA_AMP_MUTE
,
9500 spec
->jack_present
? HDA_AMP_MUTE
: 0);
9503 static void alc262_hp_t5735_unsol_event(struct hda_codec
*codec
,
9506 if ((res
>> 26) != ALC880_HP_EVENT
)
9508 alc262_hp_t5735_automute(codec
, 1);
9511 static void alc262_hp_t5735_init_hook(struct hda_codec
*codec
)
9513 alc262_hp_t5735_automute(codec
, 1);
9516 static struct snd_kcontrol_new alc262_hp_t5735_mixer
[] = {
9517 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
9520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9523 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9527 static struct hda_verb alc262_hp_t5735_verbs
[] = {
9528 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
9535 static struct snd_kcontrol_new alc262_hp_rp5700_mixer
[] = {
9536 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9538 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
9539 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT
),
9540 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9541 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9545 static struct hda_verb alc262_hp_rp5700_verbs
[] = {
9546 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9547 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9549 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
9551 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
9552 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
9553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
9554 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x00 << 8))},
9555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x00 << 8))},
9559 static struct hda_input_mux alc262_hp_rp5700_capture_source
= {
9566 /* bind hp and internal speaker mute (with plug check) */
9567 static int alc262_sony_master_sw_put(struct snd_kcontrol
*kcontrol
,
9568 struct snd_ctl_elem_value
*ucontrol
)
9570 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
9571 long *valp
= ucontrol
->value
.integer
.value
;
9574 /* change hp mute */
9575 change
= snd_hda_codec_amp_update(codec
, 0x15, 0, HDA_OUTPUT
, 0,
9577 valp
[0] ? 0 : HDA_AMP_MUTE
);
9578 change
|= snd_hda_codec_amp_update(codec
, 0x15, 1, HDA_OUTPUT
, 0,
9580 valp
[1] ? 0 : HDA_AMP_MUTE
);
9582 /* change speaker according to HP jack state */
9583 struct alc_spec
*spec
= codec
->spec
;
9585 if (spec
->jack_present
)
9586 mute
= HDA_AMP_MUTE
;
9588 mute
= snd_hda_codec_amp_read(codec
, 0x15, 0,
9590 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
9591 HDA_AMP_MUTE
, mute
);
9596 static struct snd_kcontrol_new alc262_sony_mixer
[] = {
9597 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9599 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9600 .name
= "Master Playback Switch",
9601 .info
= snd_hda_mixer_amp_switch_info
,
9602 .get
= snd_hda_mixer_amp_switch_get
,
9603 .put
= alc262_sony_master_sw_put
,
9604 .private_value
= HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
9606 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9607 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9608 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9609 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9613 static struct snd_kcontrol_new alc262_benq_t31_mixer
[] = {
9614 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9615 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9616 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9617 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9618 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9619 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9620 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9624 static struct snd_kcontrol_new alc262_tyan_mixer
[] = {
9625 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9626 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT
),
9627 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT
),
9628 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT
),
9629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9633 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
9635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
9636 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9640 static struct hda_verb alc262_tyan_verbs
[] = {
9641 /* Headphone automute */
9642 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9643 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9644 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
9646 /* P11 AUX_IN, white 4-pin connector */
9647 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
9648 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1
, 0xe1},
9649 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2
, 0x93},
9650 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3
, 0x19},
9655 /* unsolicited event for HP jack sensing */
9656 static void alc262_tyan_automute(struct hda_codec
*codec
)
9659 unsigned int present
;
9661 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
9662 present
= snd_hda_codec_read(codec
, 0x1b, 0,
9663 AC_VERB_GET_PIN_SENSE
, 0);
9664 present
= (present
& 0x80000000) != 0;
9666 /* mute line output on ATX panel */
9667 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
9668 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
9670 /* unmute line output if necessary */
9671 mute
= snd_hda_codec_amp_read(codec
, 0x1b, 0, HDA_OUTPUT
, 0);
9672 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
9673 HDA_AMP_MUTE
, mute
);
9677 static void alc262_tyan_unsol_event(struct hda_codec
*codec
,
9680 if ((res
>> 26) != ALC880_HP_EVENT
)
9682 alc262_tyan_automute(codec
);
9685 #define alc262_capture_mixer alc882_capture_mixer
9686 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9689 * generic initialization of ADC, input mixers and output mixers
9691 static struct hda_verb alc262_init_verbs
[] = {
9693 * Unmute ADC0-2 and set the default input to mic-in
9695 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
9696 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9697 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
9698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9699 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
9700 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9702 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9704 * Note: PASD motherboards uses the Line In 2 as the input for
9705 * front panel mic (mic 2)
9707 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
9709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
9710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
9711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
9712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
9715 * Set up output mixers (0x0c - 0x0e)
9717 /* set vol=0 to output mixers */
9718 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
9719 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
9720 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
9721 /* set up input amps for analog loopback */
9722 /* Amp Indices: DAC = 0, mixer = 1 */
9723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9725 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9726 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9727 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9728 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
9731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
9732 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
9733 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
9734 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
9735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
9737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9740 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9741 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9743 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
9744 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
9746 /* FIXME: use matrix-type input source selection */
9747 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9748 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
9750 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
9751 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
9752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
9754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
9755 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
9756 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
9757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
9759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
9760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
9761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
9762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
9767 static struct hda_verb alc262_eapd_verbs
[] = {
9768 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
9769 {0x15, AC_VERB_SET_EAPD_BTLENABLE
, 2},
9773 static struct hda_verb alc262_hippo_unsol_verbs
[] = {
9774 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9775 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9779 static struct hda_verb alc262_hippo1_unsol_verbs
[] = {
9780 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
9781 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
9782 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
9784 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9785 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9789 static struct hda_verb alc262_sony_unsol_verbs
[] = {
9790 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
9791 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
9792 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24}, // Front Mic
9794 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9799 static struct hda_input_mux alc262_dmic_capture_source
= {
9802 { "Int DMic", 0x9 },
9807 static struct snd_kcontrol_new alc262_toshiba_s06_mixer
[] = {
9808 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
9809 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9810 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9811 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9816 static struct hda_verb alc262_toshiba_s06_verbs
[] = {
9817 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
9818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9820 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
9821 {0x22, AC_VERB_SET_CONNECT_SEL
, 0x09},
9822 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
9823 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
9824 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9828 static void alc262_dmic_automute(struct hda_codec
*codec
)
9830 unsigned int present
;
9832 present
= snd_hda_codec_read(codec
, 0x18, 0,
9833 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
9834 snd_hda_codec_write(codec
, 0x22, 0,
9835 AC_VERB_SET_CONNECT_SEL
, present
? 0x0 : 0x09);
9838 /* toggle speaker-output according to the hp-jack state */
9839 static void alc262_toshiba_s06_speaker_automute(struct hda_codec
*codec
)
9841 unsigned int present
;
9844 present
= snd_hda_codec_read(codec
, 0x15, 0,
9845 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
9846 bits
= present
? 0 : PIN_OUT
;
9847 snd_hda_codec_write(codec
, 0x14, 0,
9848 AC_VERB_SET_PIN_WIDGET_CONTROL
, bits
);
9853 /* unsolicited event for HP jack sensing */
9854 static void alc262_toshiba_s06_unsol_event(struct hda_codec
*codec
,
9857 if ((res
>> 26) == ALC880_HP_EVENT
)
9858 alc262_toshiba_s06_speaker_automute(codec
);
9859 if ((res
>> 26) == ALC880_MIC_EVENT
)
9860 alc262_dmic_automute(codec
);
9864 static void alc262_toshiba_s06_init_hook(struct hda_codec
*codec
)
9866 alc262_toshiba_s06_speaker_automute(codec
);
9867 alc262_dmic_automute(codec
);
9870 /* mute/unmute internal speaker according to the hp jack and mute state */
9871 static void alc262_hippo_automute(struct hda_codec
*codec
)
9873 struct alc_spec
*spec
= codec
->spec
;
9875 unsigned int present
;
9877 /* need to execute and sync at first */
9878 snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_SET_PIN_SENSE
, 0);
9879 present
= snd_hda_codec_read(codec
, 0x15, 0,
9880 AC_VERB_GET_PIN_SENSE
, 0);
9881 spec
->jack_present
= (present
& 0x80000000) != 0;
9882 if (spec
->jack_present
) {
9883 /* mute internal speaker */
9884 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
9885 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
9887 /* unmute internal speaker if necessary */
9888 mute
= snd_hda_codec_amp_read(codec
, 0x15, 0, HDA_OUTPUT
, 0);
9889 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
9890 HDA_AMP_MUTE
, mute
);
9894 /* unsolicited event for HP jack sensing */
9895 static void alc262_hippo_unsol_event(struct hda_codec
*codec
,
9898 if ((res
>> 26) != ALC880_HP_EVENT
)
9900 alc262_hippo_automute(codec
);
9903 static void alc262_hippo1_automute(struct hda_codec
*codec
)
9906 unsigned int present
;
9908 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
9909 present
= snd_hda_codec_read(codec
, 0x1b, 0,
9910 AC_VERB_GET_PIN_SENSE
, 0);
9911 present
= (present
& 0x80000000) != 0;
9913 /* mute internal speaker */
9914 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
9915 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
9917 /* unmute internal speaker if necessary */
9918 mute
= snd_hda_codec_amp_read(codec
, 0x1b, 0, HDA_OUTPUT
, 0);
9919 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
9920 HDA_AMP_MUTE
, mute
);
9924 /* unsolicited event for HP jack sensing */
9925 static void alc262_hippo1_unsol_event(struct hda_codec
*codec
,
9928 if ((res
>> 26) != ALC880_HP_EVENT
)
9930 alc262_hippo1_automute(codec
);
9936 * 0x16 = internal speaker
9937 * 0x18 = external mic
9940 static struct snd_kcontrol_new alc262_nec_mixer
[] = {
9941 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
9942 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT
),
9944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9946 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9948 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
9949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
9953 static struct hda_verb alc262_nec_verbs
[] = {
9954 /* Unmute Speaker */
9955 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9958 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9959 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9961 /* External mic to headphone */
9962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9963 /* External mic to speaker */
9964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9970 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9971 * 0x1b = port replicator headphone out
9974 #define ALC_HP_EVENT 0x37
9976 static struct hda_verb alc262_fujitsu_unsol_verbs
[] = {
9977 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC_HP_EVENT
},
9978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9979 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC_HP_EVENT
},
9980 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9984 static struct hda_verb alc262_lenovo_3000_unsol_verbs
[] = {
9985 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC_HP_EVENT
},
9986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
9990 static struct hda_input_mux alc262_fujitsu_capture_source
= {
9999 static struct hda_input_mux alc262_HP_capture_source
= {
10003 { "Front Mic", 0x1 },
10010 static struct hda_input_mux alc262_HP_D7000_capture_source
= {
10014 { "Front Mic", 0x2 },
10020 /* mute/unmute internal speaker according to the hp jacks and mute state */
10021 static void alc262_fujitsu_automute(struct hda_codec
*codec
, int force
)
10023 struct alc_spec
*spec
= codec
->spec
;
10026 if (force
|| !spec
->sense_updated
) {
10027 unsigned int present
;
10028 /* need to execute and sync at first */
10029 snd_hda_codec_read(codec
, 0x14, 0, AC_VERB_SET_PIN_SENSE
, 0);
10030 /* check laptop HP jack */
10031 present
= snd_hda_codec_read(codec
, 0x14, 0,
10032 AC_VERB_GET_PIN_SENSE
, 0);
10033 /* need to execute and sync at first */
10034 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
10035 /* check docking HP jack */
10036 present
|= snd_hda_codec_read(codec
, 0x1b, 0,
10037 AC_VERB_GET_PIN_SENSE
, 0);
10038 if (present
& AC_PINSENSE_PRESENCE
)
10039 spec
->jack_present
= 1;
10041 spec
->jack_present
= 0;
10042 spec
->sense_updated
= 1;
10044 /* unmute internal speaker only if both HPs are unplugged and
10045 * master switch is on
10047 if (spec
->jack_present
)
10048 mute
= HDA_AMP_MUTE
;
10050 mute
= snd_hda_codec_amp_read(codec
, 0x14, 0, HDA_OUTPUT
, 0);
10051 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
10052 HDA_AMP_MUTE
, mute
);
10055 /* unsolicited event for HP jack sensing */
10056 static void alc262_fujitsu_unsol_event(struct hda_codec
*codec
,
10059 if ((res
>> 26) != ALC_HP_EVENT
)
10061 alc262_fujitsu_automute(codec
, 1);
10064 static void alc262_fujitsu_init_hook(struct hda_codec
*codec
)
10066 alc262_fujitsu_automute(codec
, 1);
10069 /* bind volumes of both NID 0x0c and 0x0d */
10070 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol
= {
10071 .ops
= &snd_hda_bind_vol
,
10073 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT
),
10074 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT
),
10079 /* mute/unmute internal speaker according to the hp jack and mute state */
10080 static void alc262_lenovo_3000_automute(struct hda_codec
*codec
, int force
)
10082 struct alc_spec
*spec
= codec
->spec
;
10085 if (force
|| !spec
->sense_updated
) {
10086 unsigned int present_int_hp
;
10087 /* need to execute and sync at first */
10088 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
10089 present_int_hp
= snd_hda_codec_read(codec
, 0x1b, 0,
10090 AC_VERB_GET_PIN_SENSE
, 0);
10091 spec
->jack_present
= (present_int_hp
& 0x80000000) != 0;
10092 spec
->sense_updated
= 1;
10094 if (spec
->jack_present
) {
10095 /* mute internal speaker */
10096 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10097 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
10098 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
10099 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
10101 /* unmute internal speaker if necessary */
10102 mute
= snd_hda_codec_amp_read(codec
, 0x1b, 0, HDA_OUTPUT
, 0);
10103 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10104 HDA_AMP_MUTE
, mute
);
10105 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
10106 HDA_AMP_MUTE
, mute
);
10110 /* unsolicited event for HP jack sensing */
10111 static void alc262_lenovo_3000_unsol_event(struct hda_codec
*codec
,
10114 if ((res
>> 26) != ALC_HP_EVENT
)
10116 alc262_lenovo_3000_automute(codec
, 1);
10119 /* bind hp and internal speaker mute (with plug check) */
10120 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol
*kcontrol
,
10121 struct snd_ctl_elem_value
*ucontrol
)
10123 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
10124 long *valp
= ucontrol
->value
.integer
.value
;
10127 change
= snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10129 valp
? 0 : HDA_AMP_MUTE
);
10130 change
|= snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
10132 valp
? 0 : HDA_AMP_MUTE
);
10135 alc262_fujitsu_automute(codec
, 0);
10139 static struct snd_kcontrol_new alc262_fujitsu_mixer
[] = {
10140 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol
),
10142 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10143 .name
= "Master Playback Switch",
10144 .info
= snd_hda_mixer_amp_switch_info
,
10145 .get
= snd_hda_mixer_amp_switch_get
,
10146 .put
= alc262_fujitsu_master_sw_put
,
10147 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
10149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
10150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
10151 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
10152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10154 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
10155 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10156 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10160 /* bind hp and internal speaker mute (with plug check) */
10161 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol
*kcontrol
,
10162 struct snd_ctl_elem_value
*ucontrol
)
10164 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
10165 long *valp
= ucontrol
->value
.integer
.value
;
10168 change
= snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
10170 valp
? 0 : HDA_AMP_MUTE
);
10173 alc262_lenovo_3000_automute(codec
, 0);
10177 static struct snd_kcontrol_new alc262_lenovo_3000_mixer
[] = {
10178 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol
),
10180 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10181 .name
= "Master Playback Switch",
10182 .info
= snd_hda_mixer_amp_switch_info
,
10183 .get
= snd_hda_mixer_amp_switch_get
,
10184 .put
= alc262_lenovo_3000_master_sw_put
,
10185 .private_value
= HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT
),
10187 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
10188 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
10189 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
10190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10192 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
10193 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10194 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10198 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer
[] = {
10199 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol
),
10201 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10202 .name
= "Master Playback Switch",
10203 .info
= snd_hda_mixer_amp_switch_info
,
10204 .get
= snd_hda_mixer_amp_switch_get
,
10205 .put
= alc262_sony_master_sw_put
,
10206 .private_value
= HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
10208 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10209 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10210 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
10211 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
10212 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
10213 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
10217 /* additional init verbs for Benq laptops */
10218 static struct hda_verb alc262_EAPD_verbs
[] = {
10219 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
10220 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
10224 static struct hda_verb alc262_benq_t31_EAPD_verbs
[] = {
10225 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
10226 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
10228 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
10229 {0x20, AC_VERB_SET_PROC_COEF
, 0x3050},
10233 /* Samsung Q1 Ultra Vista model setup */
10234 static struct snd_kcontrol_new alc262_ultra_mixer
[] = {
10235 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
10236 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT
),
10237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
10238 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
10239 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT
),
10240 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT
),
10244 static struct hda_verb alc262_ultra_verbs
[] = {
10246 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10247 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10248 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10252 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10253 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
10255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
10256 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10258 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
10259 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
10261 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10262 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10263 /* ADC, choose mic */
10264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
10268 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
10269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
10270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)},
10271 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)},
10272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)},
10273 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(8)},
10277 /* mute/unmute internal speaker according to the hp jack and mute state */
10278 static void alc262_ultra_automute(struct hda_codec
*codec
)
10280 struct alc_spec
*spec
= codec
->spec
;
10284 /* auto-mute only when HP is used as HP */
10285 if (!spec
->cur_mux
[0]) {
10286 unsigned int present
;
10287 /* need to execute and sync at first */
10288 snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_SET_PIN_SENSE
, 0);
10289 present
= snd_hda_codec_read(codec
, 0x15, 0,
10290 AC_VERB_GET_PIN_SENSE
, 0);
10291 spec
->jack_present
= (present
& AC_PINSENSE_PRESENCE
) != 0;
10292 if (spec
->jack_present
)
10293 mute
= HDA_AMP_MUTE
;
10295 /* mute/unmute internal speaker */
10296 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10297 HDA_AMP_MUTE
, mute
);
10298 /* mute/unmute HP */
10299 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
10300 HDA_AMP_MUTE
, mute
? 0 : HDA_AMP_MUTE
);
10303 /* unsolicited event for HP jack sensing */
10304 static void alc262_ultra_unsol_event(struct hda_codec
*codec
,
10307 if ((res
>> 26) != ALC880_HP_EVENT
)
10309 alc262_ultra_automute(codec
);
10312 static struct hda_input_mux alc262_ultra_capture_source
= {
10316 { "Headphone", 0x7 },
10320 static int alc262_ultra_mux_enum_put(struct snd_kcontrol
*kcontrol
,
10321 struct snd_ctl_elem_value
*ucontrol
)
10323 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
10324 struct alc_spec
*spec
= codec
->spec
;
10327 ret
= alc_mux_enum_put(kcontrol
, ucontrol
);
10330 /* reprogram the HP pin as mic or HP according to the input source */
10331 snd_hda_codec_write_cache(codec
, 0x15, 0,
10332 AC_VERB_SET_PIN_WIDGET_CONTROL
,
10333 spec
->cur_mux
[0] ? PIN_VREF80
: PIN_HP
);
10334 alc262_ultra_automute(codec
); /* mute/unmute HP */
10338 static struct snd_kcontrol_new alc262_ultra_capture_mixer
[] = {
10339 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT
),
10340 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT
),
10342 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10343 .name
= "Capture Source",
10344 .info
= alc_mux_enum_info
,
10345 .get
= alc_mux_enum_get
,
10346 .put
= alc262_ultra_mux_enum_put
,
10351 /* add playback controls from the parsed DAC table */
10352 static int alc262_auto_create_multi_out_ctls(struct alc_spec
*spec
,
10353 const struct auto_pin_cfg
*cfg
)
10358 spec
->multiout
.num_dacs
= 1; /* only use one dac */
10359 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
10360 spec
->multiout
.dac_nids
[0] = 2;
10362 nid
= cfg
->line_out_pins
[0];
10364 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
10365 "Front Playback Volume",
10366 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT
));
10369 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
10370 "Front Playback Switch",
10371 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
10376 nid
= cfg
->speaker_pins
[0];
10379 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
10380 "Speaker Playback Volume",
10381 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10385 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
10386 "Speaker Playback Switch",
10387 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
10392 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
10393 "Speaker Playback Switch",
10394 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
10400 nid
= cfg
->hp_pins
[0];
10402 /* spec->multiout.hp_nid = 2; */
10404 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
10405 "Headphone Playback Volume",
10406 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10410 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
10411 "Headphone Playback Switch",
10412 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
10417 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
10418 "Headphone Playback Switch",
10419 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
10428 /* identical with ALC880 */
10429 #define alc262_auto_create_analog_input_ctls \
10430 alc880_auto_create_analog_input_ctls
10433 * generic initialization of ADC, input mixers and output mixers
10435 static struct hda_verb alc262_volume_init_verbs
[] = {
10437 * Unmute ADC0-2 and set the default input to mic-in
10439 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
10440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10441 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
10442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10443 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10444 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10446 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10448 * Note: PASD motherboards uses the Line In 2 as the input for
10449 * front panel mic (mic 2)
10451 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
10455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
10456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
10459 * Set up output mixers (0x0c - 0x0f)
10461 /* set vol=0 to output mixers */
10462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10466 /* set up input amps for analog loopback */
10467 /* Amp Indices: DAC = 0, mixer = 1 */
10468 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10470 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10472 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10475 /* FIXME: use matrix-type input source selection */
10476 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10478 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10479 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
10480 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
10481 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
10483 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10484 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
10485 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
10486 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
10488 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
10490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
10491 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
10496 static struct hda_verb alc262_HP_BPC_init_verbs
[] = {
10498 * Unmute ADC0-2 and set the default input to mic-in
10500 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
10501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10502 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
10503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10504 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10507 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10509 * Note: PASD motherboards uses the Line In 2 as the input for
10510 * front panel mic (mic 2)
10512 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10513 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
10516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
10517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
10518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)},
10519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)},
10522 * Set up output mixers (0x0c - 0x0e)
10524 /* set vol=0 to output mixers */
10525 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10526 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10527 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10529 /* set up input amps for analog loopback */
10530 /* Amp Indices: DAC = 0, mixer = 1 */
10531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
10539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10542 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10545 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
10546 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
10548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
10549 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
10550 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
10551 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
10552 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
10554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
10555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
10558 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10559 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10562 /* FIXME: use matrix-type input source selection */
10563 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10564 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
10567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
10568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
10570 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10571 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
10572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
10573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
10575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10576 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
10577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
10578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
10580 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
10585 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs
[] = {
10587 * Unmute ADC0-2 and set the default input to mic-in
10589 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
10590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10591 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
10592 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10593 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10596 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10598 * Note: PASD motherboards uses the Line In 2 as the input for front
10599 * panel mic (mic 2)
10601 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10602 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10603 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
10605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
10606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
10607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)},
10608 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)},
10609 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)},
10611 * Set up output mixers (0x0c - 0x0e)
10613 /* set vol=0 to output mixers */
10614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10616 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10618 /* set up input amps for analog loopback */
10619 /* Amp Indices: DAC = 0, mixer = 1 */
10620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10623 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10624 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10625 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10628 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP */
10629 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Mono */
10630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* rear MIC */
10631 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* Line in */
10632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Front MIC */
10633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Line out */
10634 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD in */
10636 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10639 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
10640 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
10642 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10643 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
10646 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10647 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
10649 /* FIXME: use matrix-type input source selection */
10650 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10651 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))}, /*Line in*/
10654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))}, /*F MIC*/
10655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))}, /*Front*/
10656 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))}, /*CD*/
10657 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10658 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))}, /*HP*/
10660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10661 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
10662 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
10663 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
10664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
10665 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10666 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))},
10668 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
10669 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
10670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
10671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
10672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
10673 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))},
10676 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
10681 static struct hda_verb alc262_toshiba_rx1_unsol_verbs
[] = {
10683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Front Speaker */
10684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10685 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x01},
10687 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* MIC jack */
10688 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Front MIC */
10689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0) },
10690 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0) },
10692 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP jack */
10693 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
10694 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
10699 #ifdef CONFIG_SND_HDA_POWER_SAVE
10700 #define alc262_loopbacks alc880_loopbacks
10703 /* pcm configuration: identiacal with ALC880 */
10704 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10705 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10706 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10707 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10710 * BIOS auto configuration
10712 static int alc262_parse_auto_config(struct hda_codec
*codec
)
10714 struct alc_spec
*spec
= codec
->spec
;
10716 static hda_nid_t alc262_ignore
[] = { 0x1d, 0 };
10718 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
10722 if (!spec
->autocfg
.line_outs
) {
10723 if (spec
->autocfg
.dig_outs
|| spec
->autocfg
.dig_in_pin
) {
10724 spec
->multiout
.max_channels
= 2;
10725 spec
->no_analog
= 1;
10728 return 0; /* can't find valid BIOS pin config */
10730 err
= alc262_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
10733 err
= alc262_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
10737 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
10740 if (spec
->autocfg
.dig_outs
) {
10741 spec
->multiout
.dig_out_nid
= ALC262_DIGOUT_NID
;
10742 spec
->dig_out_type
= spec
->autocfg
.dig_out_type
[0];
10744 if (spec
->autocfg
.dig_in_pin
)
10745 spec
->dig_in_nid
= ALC262_DIGIN_NID
;
10747 if (spec
->kctls
.list
)
10748 add_mixer(spec
, spec
->kctls
.list
);
10750 add_verb(spec
, alc262_volume_init_verbs
);
10751 spec
->num_mux_defs
= 1;
10752 spec
->input_mux
= &spec
->private_imux
[0];
10754 err
= alc_auto_add_mic_boost(codec
);
10761 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10762 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10763 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10764 #define alc262_auto_init_input_src alc882_auto_init_input_src
10767 /* init callback for auto-configuration model -- overriding the default init */
10768 static void alc262_auto_init(struct hda_codec
*codec
)
10770 struct alc_spec
*spec
= codec
->spec
;
10771 alc262_auto_init_multi_out(codec
);
10772 alc262_auto_init_hp_out(codec
);
10773 alc262_auto_init_analog_input(codec
);
10774 alc262_auto_init_input_src(codec
);
10775 if (spec
->unsol_event
)
10776 alc_inithook(codec
);
10780 * configuration and preset
10782 static const char *alc262_models
[ALC262_MODEL_LAST
] = {
10783 [ALC262_BASIC
] = "basic",
10784 [ALC262_HIPPO
] = "hippo",
10785 [ALC262_HIPPO_1
] = "hippo_1",
10786 [ALC262_FUJITSU
] = "fujitsu",
10787 [ALC262_HP_BPC
] = "hp-bpc",
10788 [ALC262_HP_BPC_D7000_WL
]= "hp-bpc-d7000",
10789 [ALC262_HP_TC_T5735
] = "hp-tc-t5735",
10790 [ALC262_HP_RP5700
] = "hp-rp5700",
10791 [ALC262_BENQ_ED8
] = "benq",
10792 [ALC262_BENQ_T31
] = "benq-t31",
10793 [ALC262_SONY_ASSAMD
] = "sony-assamd",
10794 [ALC262_TOSHIBA_S06
] = "toshiba-s06",
10795 [ALC262_TOSHIBA_RX1
] = "toshiba-rx1",
10796 [ALC262_ULTRA
] = "ultra",
10797 [ALC262_LENOVO_3000
] = "lenovo-3000",
10798 [ALC262_NEC
] = "nec",
10799 [ALC262_TYAN
] = "tyan",
10800 [ALC262_AUTO
] = "auto",
10803 static struct snd_pci_quirk alc262_cfg_tbl
[] = {
10804 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO
),
10805 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC
),
10806 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
10808 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
10810 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL
),
10811 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF
),
10812 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL
),
10813 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF
),
10814 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL
),
10815 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF
),
10816 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL
),
10817 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF
),
10818 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC
),
10819 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC
),
10820 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC
),
10821 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10822 ALC262_HP_TC_T5735
),
10823 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700
),
10824 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
10825 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO
),
10826 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
10827 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
10828 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD
),
10829 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10830 ALC262_SONY_ASSAMD
),
10831 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10832 ALC262_TOSHIBA_RX1
),
10833 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06
),
10834 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU
),
10835 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU
),
10836 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN
),
10837 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
10839 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO
),
10840 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000
),
10841 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8
),
10842 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31
),
10843 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1
),
10847 static struct alc_config_preset alc262_presets
[] = {
10849 .mixers
= { alc262_base_mixer
},
10850 .init_verbs
= { alc262_init_verbs
},
10851 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10852 .dac_nids
= alc262_dac_nids
,
10854 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10855 .channel_mode
= alc262_modes
,
10856 .input_mux
= &alc262_capture_source
,
10859 .mixers
= { alc262_base_mixer
},
10860 .init_verbs
= { alc262_init_verbs
, alc262_hippo_unsol_verbs
},
10861 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10862 .dac_nids
= alc262_dac_nids
,
10864 .dig_out_nid
= ALC262_DIGOUT_NID
,
10865 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10866 .channel_mode
= alc262_modes
,
10867 .input_mux
= &alc262_capture_source
,
10868 .unsol_event
= alc262_hippo_unsol_event
,
10869 .init_hook
= alc262_hippo_automute
,
10871 [ALC262_HIPPO_1
] = {
10872 .mixers
= { alc262_hippo1_mixer
},
10873 .init_verbs
= { alc262_init_verbs
, alc262_hippo1_unsol_verbs
},
10874 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10875 .dac_nids
= alc262_dac_nids
,
10877 .dig_out_nid
= ALC262_DIGOUT_NID
,
10878 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10879 .channel_mode
= alc262_modes
,
10880 .input_mux
= &alc262_capture_source
,
10881 .unsol_event
= alc262_hippo1_unsol_event
,
10882 .init_hook
= alc262_hippo1_automute
,
10884 [ALC262_FUJITSU
] = {
10885 .mixers
= { alc262_fujitsu_mixer
},
10886 .init_verbs
= { alc262_init_verbs
, alc262_EAPD_verbs
,
10887 alc262_fujitsu_unsol_verbs
},
10888 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10889 .dac_nids
= alc262_dac_nids
,
10891 .dig_out_nid
= ALC262_DIGOUT_NID
,
10892 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10893 .channel_mode
= alc262_modes
,
10894 .input_mux
= &alc262_fujitsu_capture_source
,
10895 .unsol_event
= alc262_fujitsu_unsol_event
,
10896 .init_hook
= alc262_fujitsu_init_hook
,
10898 [ALC262_HP_BPC
] = {
10899 .mixers
= { alc262_HP_BPC_mixer
},
10900 .init_verbs
= { alc262_HP_BPC_init_verbs
},
10901 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10902 .dac_nids
= alc262_dac_nids
,
10904 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10905 .channel_mode
= alc262_modes
,
10906 .input_mux
= &alc262_HP_capture_source
,
10907 .unsol_event
= alc262_hp_bpc_unsol_event
,
10908 .init_hook
= alc262_hp_bpc_automute
,
10910 [ALC262_HP_BPC_D7000_WF
] = {
10911 .mixers
= { alc262_HP_BPC_WildWest_mixer
},
10912 .init_verbs
= { alc262_HP_BPC_WildWest_init_verbs
},
10913 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10914 .dac_nids
= alc262_dac_nids
,
10916 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10917 .channel_mode
= alc262_modes
,
10918 .input_mux
= &alc262_HP_D7000_capture_source
,
10919 .unsol_event
= alc262_hp_wildwest_unsol_event
,
10920 .init_hook
= alc262_hp_wildwest_automute
,
10922 [ALC262_HP_BPC_D7000_WL
] = {
10923 .mixers
= { alc262_HP_BPC_WildWest_mixer
,
10924 alc262_HP_BPC_WildWest_option_mixer
},
10925 .init_verbs
= { alc262_HP_BPC_WildWest_init_verbs
},
10926 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10927 .dac_nids
= alc262_dac_nids
,
10929 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10930 .channel_mode
= alc262_modes
,
10931 .input_mux
= &alc262_HP_D7000_capture_source
,
10932 .unsol_event
= alc262_hp_wildwest_unsol_event
,
10933 .init_hook
= alc262_hp_wildwest_automute
,
10935 [ALC262_HP_TC_T5735
] = {
10936 .mixers
= { alc262_hp_t5735_mixer
},
10937 .init_verbs
= { alc262_init_verbs
, alc262_hp_t5735_verbs
},
10938 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10939 .dac_nids
= alc262_dac_nids
,
10941 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10942 .channel_mode
= alc262_modes
,
10943 .input_mux
= &alc262_capture_source
,
10944 .unsol_event
= alc262_hp_t5735_unsol_event
,
10945 .init_hook
= alc262_hp_t5735_init_hook
,
10947 [ALC262_HP_RP5700
] = {
10948 .mixers
= { alc262_hp_rp5700_mixer
},
10949 .init_verbs
= { alc262_init_verbs
, alc262_hp_rp5700_verbs
},
10950 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10951 .dac_nids
= alc262_dac_nids
,
10952 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10953 .channel_mode
= alc262_modes
,
10954 .input_mux
= &alc262_hp_rp5700_capture_source
,
10956 [ALC262_BENQ_ED8
] = {
10957 .mixers
= { alc262_base_mixer
},
10958 .init_verbs
= { alc262_init_verbs
, alc262_EAPD_verbs
},
10959 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10960 .dac_nids
= alc262_dac_nids
,
10962 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10963 .channel_mode
= alc262_modes
,
10964 .input_mux
= &alc262_capture_source
,
10966 [ALC262_SONY_ASSAMD
] = {
10967 .mixers
= { alc262_sony_mixer
},
10968 .init_verbs
= { alc262_init_verbs
, alc262_sony_unsol_verbs
},
10969 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10970 .dac_nids
= alc262_dac_nids
,
10972 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10973 .channel_mode
= alc262_modes
,
10974 .input_mux
= &alc262_capture_source
,
10975 .unsol_event
= alc262_hippo_unsol_event
,
10976 .init_hook
= alc262_hippo_automute
,
10978 [ALC262_BENQ_T31
] = {
10979 .mixers
= { alc262_benq_t31_mixer
},
10980 .init_verbs
= { alc262_init_verbs
, alc262_benq_t31_EAPD_verbs
, alc262_hippo_unsol_verbs
},
10981 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10982 .dac_nids
= alc262_dac_nids
,
10984 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10985 .channel_mode
= alc262_modes
,
10986 .input_mux
= &alc262_capture_source
,
10987 .unsol_event
= alc262_hippo_unsol_event
,
10988 .init_hook
= alc262_hippo_automute
,
10991 .mixers
= { alc262_ultra_mixer
},
10992 .cap_mixer
= alc262_ultra_capture_mixer
,
10993 .init_verbs
= { alc262_ultra_verbs
},
10994 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
10995 .dac_nids
= alc262_dac_nids
,
10996 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
10997 .channel_mode
= alc262_modes
,
10998 .input_mux
= &alc262_ultra_capture_source
,
10999 .adc_nids
= alc262_adc_nids
, /* ADC0 */
11000 .capsrc_nids
= alc262_capsrc_nids
,
11001 .num_adc_nids
= 1, /* single ADC */
11002 .unsol_event
= alc262_ultra_unsol_event
,
11003 .init_hook
= alc262_ultra_automute
,
11005 [ALC262_LENOVO_3000
] = {
11006 .mixers
= { alc262_lenovo_3000_mixer
},
11007 .init_verbs
= { alc262_init_verbs
, alc262_EAPD_verbs
,
11008 alc262_lenovo_3000_unsol_verbs
},
11009 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
11010 .dac_nids
= alc262_dac_nids
,
11012 .dig_out_nid
= ALC262_DIGOUT_NID
,
11013 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
11014 .channel_mode
= alc262_modes
,
11015 .input_mux
= &alc262_fujitsu_capture_source
,
11016 .unsol_event
= alc262_lenovo_3000_unsol_event
,
11019 .mixers
= { alc262_nec_mixer
},
11020 .init_verbs
= { alc262_nec_verbs
},
11021 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
11022 .dac_nids
= alc262_dac_nids
,
11024 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
11025 .channel_mode
= alc262_modes
,
11026 .input_mux
= &alc262_capture_source
,
11028 [ALC262_TOSHIBA_S06
] = {
11029 .mixers
= { alc262_toshiba_s06_mixer
},
11030 .init_verbs
= { alc262_init_verbs
, alc262_toshiba_s06_verbs
,
11031 alc262_eapd_verbs
},
11032 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
11033 .capsrc_nids
= alc262_dmic_capsrc_nids
,
11034 .dac_nids
= alc262_dac_nids
,
11035 .adc_nids
= alc262_dmic_adc_nids
, /* ADC0 */
11036 .dig_out_nid
= ALC262_DIGOUT_NID
,
11037 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
11038 .channel_mode
= alc262_modes
,
11039 .input_mux
= &alc262_dmic_capture_source
,
11040 .unsol_event
= alc262_toshiba_s06_unsol_event
,
11041 .init_hook
= alc262_toshiba_s06_init_hook
,
11043 [ALC262_TOSHIBA_RX1
] = {
11044 .mixers
= { alc262_toshiba_rx1_mixer
},
11045 .init_verbs
= { alc262_init_verbs
, alc262_toshiba_rx1_unsol_verbs
},
11046 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
11047 .dac_nids
= alc262_dac_nids
,
11049 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
11050 .channel_mode
= alc262_modes
,
11051 .input_mux
= &alc262_capture_source
,
11052 .unsol_event
= alc262_hippo_unsol_event
,
11053 .init_hook
= alc262_hippo_automute
,
11056 .mixers
= { alc262_tyan_mixer
},
11057 .init_verbs
= { alc262_init_verbs
, alc262_tyan_verbs
},
11058 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
11059 .dac_nids
= alc262_dac_nids
,
11061 .dig_out_nid
= ALC262_DIGOUT_NID
,
11062 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
11063 .channel_mode
= alc262_modes
,
11064 .input_mux
= &alc262_capture_source
,
11065 .unsol_event
= alc262_tyan_unsol_event
,
11066 .init_hook
= alc262_tyan_automute
,
11070 static int patch_alc262(struct hda_codec
*codec
)
11072 struct alc_spec
*spec
;
11076 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
11080 codec
->spec
= spec
;
11082 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11087 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_COEF_INDEX
, 7);
11088 tmp
= snd_hda_codec_read(codec
, 0x20, 0, AC_VERB_GET_PROC_COEF
, 0);
11089 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_COEF_INDEX
, 7);
11090 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_PROC_COEF
, tmp
| 0x80);
11094 alc_fix_pll_init(codec
, 0x20, 0x0a, 10);
11096 board_config
= snd_hda_check_board_config(codec
, ALC262_MODEL_LAST
,
11100 if (board_config
< 0) {
11101 printk(KERN_INFO
"hda_codec: Unknown model for ALC262, "
11102 "trying auto-probe from BIOS...\n");
11103 board_config
= ALC262_AUTO
;
11106 if (board_config
== ALC262_AUTO
) {
11107 /* automatic parse from the BIOS config */
11108 err
= alc262_parse_auto_config(codec
);
11114 "hda_codec: Cannot set up configuration "
11115 "from BIOS. Using base mode...\n");
11116 board_config
= ALC262_BASIC
;
11120 if (!spec
->no_analog
) {
11121 err
= snd_hda_attach_beep_device(codec
, 0x1);
11128 if (board_config
!= ALC262_AUTO
)
11129 setup_preset(spec
, &alc262_presets
[board_config
]);
11131 spec
->stream_name_analog
= "ALC262 Analog";
11132 spec
->stream_analog_playback
= &alc262_pcm_analog_playback
;
11133 spec
->stream_analog_capture
= &alc262_pcm_analog_capture
;
11135 spec
->stream_name_digital
= "ALC262 Digital";
11136 spec
->stream_digital_playback
= &alc262_pcm_digital_playback
;
11137 spec
->stream_digital_capture
= &alc262_pcm_digital_capture
;
11139 spec
->capture_style
= CAPT_MIX
;
11140 if (!spec
->adc_nids
&& spec
->input_mux
) {
11141 /* check whether NID 0x07 is valid */
11142 unsigned int wcap
= get_wcaps(codec
, 0x07);
11145 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
11146 if (wcap
!= AC_WID_AUD_IN
) {
11147 spec
->adc_nids
= alc262_adc_nids_alt
;
11148 spec
->num_adc_nids
= ARRAY_SIZE(alc262_adc_nids_alt
);
11149 spec
->capsrc_nids
= alc262_capsrc_nids_alt
;
11151 spec
->adc_nids
= alc262_adc_nids
;
11152 spec
->num_adc_nids
= ARRAY_SIZE(alc262_adc_nids
);
11153 spec
->capsrc_nids
= alc262_capsrc_nids
;
11156 if (!spec
->cap_mixer
&& !spec
->no_analog
)
11157 set_capture_mixer(spec
);
11158 if (!spec
->no_analog
)
11159 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
11161 spec
->vmaster_nid
= 0x0c;
11163 codec
->patch_ops
= alc_patch_ops
;
11164 if (board_config
== ALC262_AUTO
)
11165 spec
->init_hook
= alc262_auto_init
;
11166 #ifdef CONFIG_SND_HDA_POWER_SAVE
11167 if (!spec
->loopback
.amplist
)
11168 spec
->loopback
.amplist
= alc262_loopbacks
;
11170 codec
->proc_widget_hook
= print_realtek_coef
;
11176 * ALC268 channel source setting (2 channel)
11178 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11179 #define alc268_modes alc260_modes
11181 static hda_nid_t alc268_dac_nids
[2] = {
11186 static hda_nid_t alc268_adc_nids
[2] = {
11191 static hda_nid_t alc268_adc_nids_alt
[1] = {
11196 static hda_nid_t alc268_capsrc_nids
[2] = { 0x23, 0x24 };
11198 static struct snd_kcontrol_new alc268_base_mixer
[] = {
11199 /* output mixer control */
11200 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT
),
11201 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
11202 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT
),
11203 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
11204 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
11205 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
11206 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT
),
11210 /* bind Beep switches of both NID 0x0f and 0x10 */
11211 static struct hda_bind_ctls alc268_bind_beep_sw
= {
11212 .ops
= &snd_hda_bind_sw
,
11214 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT
),
11215 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT
),
11220 static struct snd_kcontrol_new alc268_beep_mixer
[] = {
11221 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT
),
11222 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw
),
11226 static struct hda_verb alc268_eapd_verbs
[] = {
11227 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
11228 {0x15, AC_VERB_SET_EAPD_BTLENABLE
, 2},
11232 /* Toshiba specific */
11233 #define alc268_toshiba_automute alc262_hippo_automute
11235 static struct hda_verb alc268_toshiba_verbs
[] = {
11236 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
11240 static struct hda_input_mux alc268_acer_lc_capture_source
= {
11248 /* Acer specific */
11249 /* bind volumes of both NID 0x02 and 0x03 */
11250 static struct hda_bind_ctls alc268_acer_bind_master_vol
= {
11251 .ops
= &snd_hda_bind_vol
,
11253 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
11254 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT
),
11259 /* mute/unmute internal speaker according to the hp jack and mute state */
11260 static void alc268_acer_automute(struct hda_codec
*codec
, int force
)
11262 struct alc_spec
*spec
= codec
->spec
;
11265 if (force
|| !spec
->sense_updated
) {
11266 unsigned int present
;
11267 present
= snd_hda_codec_read(codec
, 0x14, 0,
11268 AC_VERB_GET_PIN_SENSE
, 0);
11269 spec
->jack_present
= (present
& 0x80000000) != 0;
11270 spec
->sense_updated
= 1;
11272 if (spec
->jack_present
)
11273 mute
= HDA_AMP_MUTE
; /* mute internal speaker */
11274 else /* unmute internal speaker if necessary */
11275 mute
= snd_hda_codec_amp_read(codec
, 0x14, 0, HDA_OUTPUT
, 0);
11276 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
11277 HDA_AMP_MUTE
, mute
);
11281 /* bind hp and internal speaker mute (with plug check) */
11282 static int alc268_acer_master_sw_put(struct snd_kcontrol
*kcontrol
,
11283 struct snd_ctl_elem_value
*ucontrol
)
11285 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
11286 long *valp
= ucontrol
->value
.integer
.value
;
11289 change
= snd_hda_codec_amp_update(codec
, 0x14, 0, HDA_OUTPUT
, 0,
11291 valp
[0] ? 0 : HDA_AMP_MUTE
);
11292 change
|= snd_hda_codec_amp_update(codec
, 0x14, 1, HDA_OUTPUT
, 0,
11294 valp
[1] ? 0 : HDA_AMP_MUTE
);
11296 alc268_acer_automute(codec
, 0);
11300 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer
[] = {
11301 /* output mixer control */
11302 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol
),
11304 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11305 .name
= "Master Playback Switch",
11306 .info
= snd_hda_mixer_amp_switch_info
,
11307 .get
= snd_hda_mixer_amp_switch_get
,
11308 .put
= alc268_acer_master_sw_put
,
11309 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
11311 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT
),
11315 static struct snd_kcontrol_new alc268_acer_mixer
[] = {
11316 /* output mixer control */
11317 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol
),
11319 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11320 .name
= "Master Playback Switch",
11321 .info
= snd_hda_mixer_amp_switch_info
,
11322 .get
= snd_hda_mixer_amp_switch_get
,
11323 .put
= alc268_acer_master_sw_put
,
11324 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
11326 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
11327 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT
),
11328 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT
),
11332 static struct snd_kcontrol_new alc268_acer_dmic_mixer
[] = {
11333 /* output mixer control */
11334 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol
),
11336 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11337 .name
= "Master Playback Switch",
11338 .info
= snd_hda_mixer_amp_switch_info
,
11339 .get
= snd_hda_mixer_amp_switch_get
,
11340 .put
= alc268_acer_master_sw_put
,
11341 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
11343 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
11344 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT
),
11348 static struct hda_verb alc268_acer_aspire_one_verbs
[] = {
11349 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
11350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
11351 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
11352 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
11353 {0x23, AC_VERB_SET_CONNECT_SEL
, 0x06},
11354 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, 0xa017},
11358 static struct hda_verb alc268_acer_verbs
[] = {
11359 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* internal dmic? */
11360 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
11361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
11362 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
11363 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
11364 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
11365 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
11369 /* unsolicited event for HP jack sensing */
11370 static void alc268_toshiba_unsol_event(struct hda_codec
*codec
,
11373 if ((res
>> 26) != ALC880_HP_EVENT
)
11375 alc268_toshiba_automute(codec
);
11378 static void alc268_acer_unsol_event(struct hda_codec
*codec
,
11381 if ((res
>> 26) != ALC880_HP_EVENT
)
11383 alc268_acer_automute(codec
, 1);
11386 static void alc268_acer_init_hook(struct hda_codec
*codec
)
11388 alc268_acer_automute(codec
, 1);
11391 /* toggle speaker-output according to the hp-jack state */
11392 static void alc268_aspire_one_speaker_automute(struct hda_codec
*codec
)
11394 unsigned int present
;
11395 unsigned char bits
;
11397 present
= snd_hda_codec_read(codec
, 0x15, 0,
11398 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
11399 bits
= present
? AMP_IN_MUTE(0) : 0;
11400 snd_hda_codec_amp_stereo(codec
, 0x0f, HDA_INPUT
, 0,
11401 AMP_IN_MUTE(0), bits
);
11402 snd_hda_codec_amp_stereo(codec
, 0x0f, HDA_INPUT
, 1,
11403 AMP_IN_MUTE(0), bits
);
11407 static void alc268_acer_mic_automute(struct hda_codec
*codec
)
11409 unsigned int present
;
11411 present
= snd_hda_codec_read(codec
, 0x18, 0,
11412 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
11413 snd_hda_codec_write(codec
, 0x23, 0, AC_VERB_SET_CONNECT_SEL
,
11414 present
? 0x0 : 0x6);
11417 static void alc268_acer_lc_unsol_event(struct hda_codec
*codec
,
11420 if ((res
>> 26) == ALC880_HP_EVENT
)
11421 alc268_aspire_one_speaker_automute(codec
);
11422 if ((res
>> 26) == ALC880_MIC_EVENT
)
11423 alc268_acer_mic_automute(codec
);
11426 static void alc268_acer_lc_init_hook(struct hda_codec
*codec
)
11428 alc268_aspire_one_speaker_automute(codec
);
11429 alc268_acer_mic_automute(codec
);
11432 static struct snd_kcontrol_new alc268_dell_mixer
[] = {
11433 /* output mixer control */
11434 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
11435 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
11436 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
11437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
11438 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
11439 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT
),
11443 static struct hda_verb alc268_dell_verbs
[] = {
11444 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
11445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
11446 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
11450 /* mute/unmute internal speaker according to the hp jack and mute state */
11451 static void alc268_dell_automute(struct hda_codec
*codec
)
11453 unsigned int present
;
11456 present
= snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_GET_PIN_SENSE
, 0);
11457 if (present
& 0x80000000)
11458 mute
= HDA_AMP_MUTE
;
11460 mute
= snd_hda_codec_amp_read(codec
, 0x15, 0, HDA_OUTPUT
, 0);
11461 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
11462 HDA_AMP_MUTE
, mute
);
11465 static void alc268_dell_unsol_event(struct hda_codec
*codec
,
11468 if ((res
>> 26) != ALC880_HP_EVENT
)
11470 alc268_dell_automute(codec
);
11473 #define alc268_dell_init_hook alc268_dell_automute
11475 static struct snd_kcontrol_new alc267_quanta_il1_mixer
[] = {
11476 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT
),
11477 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
11478 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT
),
11479 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
11480 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
11481 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT
),
11482 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT
),
11483 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
11487 static struct hda_verb alc267_quanta_il1_verbs
[] = {
11488 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
11489 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_MIC_EVENT
| AC_USRSP_EN
},
11493 static void alc267_quanta_il1_hp_automute(struct hda_codec
*codec
)
11495 unsigned int present
;
11497 present
= snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_GET_PIN_SENSE
, 0)
11498 & AC_PINSENSE_PRESENCE
;
11499 snd_hda_codec_write(codec
, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
11500 present
? 0 : PIN_OUT
);
11503 static void alc267_quanta_il1_mic_automute(struct hda_codec
*codec
)
11505 unsigned int present
;
11507 present
= snd_hda_codec_read(codec
, 0x18, 0,
11508 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
11509 snd_hda_codec_write(codec
, 0x23, 0,
11510 AC_VERB_SET_CONNECT_SEL
,
11511 present
? 0x00 : 0x01);
11514 static void alc267_quanta_il1_automute(struct hda_codec
*codec
)
11516 alc267_quanta_il1_hp_automute(codec
);
11517 alc267_quanta_il1_mic_automute(codec
);
11520 static void alc267_quanta_il1_unsol_event(struct hda_codec
*codec
,
11523 switch (res
>> 26) {
11524 case ALC880_HP_EVENT
:
11525 alc267_quanta_il1_hp_automute(codec
);
11527 case ALC880_MIC_EVENT
:
11528 alc267_quanta_il1_mic_automute(codec
);
11534 * generic initialization of ADC, input mixers and output mixers
11536 static struct hda_verb alc268_base_init_verbs
[] = {
11537 /* Unmute DAC0-1 and set vol = 0 */
11538 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11539 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11542 * Set up output mixers (0x0c - 0x0e)
11544 /* set vol=0 to output mixers */
11545 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11546 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00},
11548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11549 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
11552 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
11553 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
11554 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
11555 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
11556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11558 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11561 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11562 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11563 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11564 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11566 /* set PCBEEP vol = 0, mute connections */
11567 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11568 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
11569 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
11571 /* Unmute Selector 23h,24h and set the default input to mic-in */
11573 {0x23, AC_VERB_SET_CONNECT_SEL
, 0x00},
11574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
11575 {0x24, AC_VERB_SET_CONNECT_SEL
, 0x00},
11576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
11582 * generic initialization of ADC, input mixers and output mixers
11584 static struct hda_verb alc268_volume_init_verbs
[] = {
11585 /* set output DAC */
11586 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11587 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11589 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
11590 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
11591 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11592 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11593 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
11595 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11597 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11602 /* set PCBEEP vol = 0, mute connections */
11603 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11604 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
11605 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
11610 static struct snd_kcontrol_new alc268_capture_alt_mixer
[] = {
11611 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
11612 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT
),
11614 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11615 /* The multiple "Capture Source" controls confuse alsamixer
11616 * So call somewhat different..
11618 /* .name = "Capture Source", */
11619 .name
= "Input Source",
11621 .info
= alc_mux_enum_info
,
11622 .get
= alc_mux_enum_get
,
11623 .put
= alc_mux_enum_put
,
11628 static struct snd_kcontrol_new alc268_capture_mixer
[] = {
11629 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
11630 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT
),
11631 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT
),
11632 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT
),
11634 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11635 /* The multiple "Capture Source" controls confuse alsamixer
11636 * So call somewhat different..
11638 /* .name = "Capture Source", */
11639 .name
= "Input Source",
11641 .info
= alc_mux_enum_info
,
11642 .get
= alc_mux_enum_get
,
11643 .put
= alc_mux_enum_put
,
11648 static struct hda_input_mux alc268_capture_source
= {
11652 { "Front Mic", 0x1 },
11658 static struct hda_input_mux alc268_acer_capture_source
= {
11662 { "Internal Mic", 0x1 },
11667 static struct hda_input_mux alc268_acer_dmic_capture_source
= {
11671 { "Internal Mic", 0x6 },
11676 #ifdef CONFIG_SND_DEBUG
11677 static struct snd_kcontrol_new alc268_test_mixer
[] = {
11678 /* Volume widgets */
11679 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
11680 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
11681 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
11682 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT
),
11683 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT
),
11684 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT
),
11685 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT
),
11686 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT
),
11687 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT
),
11688 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT
),
11689 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT
),
11690 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT
),
11691 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT
),
11692 /* The below appears problematic on some hardwares */
11693 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11694 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
11695 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT
),
11696 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT
),
11697 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT
),
11699 /* Modes for retasking pin widgets */
11700 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT
),
11701 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT
),
11702 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT
),
11703 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT
),
11705 /* Controls for GPIO pins, assuming they are configured as outputs */
11706 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11707 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11708 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11709 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11711 /* Switches to allow the digital SPDIF output pin to be enabled.
11712 * The ALC268 does not have an SPDIF input.
11714 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11716 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11717 * this output to turn on an external amplifier.
11719 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11720 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11726 /* create input playback/capture controls for the given pin */
11727 static int alc268_new_analog_output(struct alc_spec
*spec
, hda_nid_t nid
,
11728 const char *ctlname
, int idx
)
11733 sprintf(name
, "%s Playback Volume", ctlname
);
11735 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
11736 HDA_COMPOSE_AMP_VAL(0x02, 3, idx
,
11740 } else if (nid
== 0x15) {
11741 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
11742 HDA_COMPOSE_AMP_VAL(0x03, 3, idx
,
11748 sprintf(name
, "%s Playback Switch", ctlname
);
11749 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
11750 HDA_COMPOSE_AMP_VAL(nid
, 3, idx
, HDA_OUTPUT
));
11756 /* add playback controls from the parsed DAC table */
11757 static int alc268_auto_create_multi_out_ctls(struct alc_spec
*spec
,
11758 const struct auto_pin_cfg
*cfg
)
11763 spec
->multiout
.num_dacs
= 2; /* only use one dac */
11764 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
11765 spec
->multiout
.dac_nids
[0] = 2;
11766 spec
->multiout
.dac_nids
[1] = 3;
11768 nid
= cfg
->line_out_pins
[0];
11770 alc268_new_analog_output(spec
, nid
, "Front", 0);
11772 nid
= cfg
->speaker_pins
[0];
11774 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
11775 "Speaker Playback Volume",
11776 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_INPUT
));
11780 nid
= cfg
->hp_pins
[0];
11782 alc268_new_analog_output(spec
, nid
, "Headphone", 0);
11784 nid
= cfg
->line_out_pins
[1] | cfg
->line_out_pins
[2];
11786 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
11787 "Mono Playback Switch",
11788 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_INPUT
));
11795 /* create playback/capture controls for input pins */
11796 static int alc268_auto_create_analog_input_ctls(struct alc_spec
*spec
,
11797 const struct auto_pin_cfg
*cfg
)
11799 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
11802 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
11803 switch(cfg
->input_pins
[i
]) {
11805 idx1
= 0; /* Mic 1 */
11808 idx1
= 1; /* Mic 2 */
11811 idx1
= 2; /* Line In */
11818 idx1
= 6; /* digital mics */
11823 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
11824 imux
->items
[imux
->num_items
].index
= idx1
;
11830 static void alc268_auto_init_mono_speaker_out(struct hda_codec
*codec
)
11832 struct alc_spec
*spec
= codec
->spec
;
11833 hda_nid_t speaker_nid
= spec
->autocfg
.speaker_pins
[0];
11834 hda_nid_t hp_nid
= spec
->autocfg
.hp_pins
[0];
11835 hda_nid_t line_nid
= spec
->autocfg
.line_out_pins
[0];
11836 unsigned int dac_vol1
, dac_vol2
;
11839 snd_hda_codec_write(codec
, speaker_nid
, 0,
11840 AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
);
11841 snd_hda_codec_write(codec
, 0x0f, 0,
11842 AC_VERB_SET_AMP_GAIN_MUTE
,
11844 snd_hda_codec_write(codec
, 0x10, 0,
11845 AC_VERB_SET_AMP_GAIN_MUTE
,
11848 snd_hda_codec_write(codec
, 0x0f, 0,
11849 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1));
11850 snd_hda_codec_write(codec
, 0x10, 0,
11851 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1));
11854 dac_vol1
= dac_vol2
= 0xb000 | 0x40; /* set max volume */
11855 if (line_nid
== 0x14)
11856 dac_vol2
= AMP_OUT_ZERO
;
11857 else if (line_nid
== 0x15)
11858 dac_vol1
= AMP_OUT_ZERO
;
11859 if (hp_nid
== 0x14)
11860 dac_vol2
= AMP_OUT_ZERO
;
11861 else if (hp_nid
== 0x15)
11862 dac_vol1
= AMP_OUT_ZERO
;
11863 if (line_nid
!= 0x16 || hp_nid
!= 0x16 ||
11864 spec
->autocfg
.line_out_pins
[1] != 0x16 ||
11865 spec
->autocfg
.line_out_pins
[2] != 0x16)
11866 dac_vol1
= dac_vol2
= AMP_OUT_ZERO
;
11868 snd_hda_codec_write(codec
, 0x02, 0,
11869 AC_VERB_SET_AMP_GAIN_MUTE
, dac_vol1
);
11870 snd_hda_codec_write(codec
, 0x03, 0,
11871 AC_VERB_SET_AMP_GAIN_MUTE
, dac_vol2
);
11874 /* pcm configuration: identiacal with ALC880 */
11875 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11876 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11877 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11878 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11881 * BIOS auto configuration
11883 static int alc268_parse_auto_config(struct hda_codec
*codec
)
11885 struct alc_spec
*spec
= codec
->spec
;
11887 static hda_nid_t alc268_ignore
[] = { 0 };
11889 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
11893 if (!spec
->autocfg
.line_outs
) {
11894 if (spec
->autocfg
.dig_outs
|| spec
->autocfg
.dig_in_pin
) {
11895 spec
->multiout
.max_channels
= 2;
11896 spec
->no_analog
= 1;
11899 return 0; /* can't find valid BIOS pin config */
11901 err
= alc268_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
11904 err
= alc268_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
11908 spec
->multiout
.max_channels
= 2;
11911 /* digital only support output */
11912 if (spec
->autocfg
.dig_outs
) {
11913 spec
->multiout
.dig_out_nid
= ALC268_DIGOUT_NID
;
11914 spec
->dig_out_type
= spec
->autocfg
.dig_out_type
[0];
11916 if (spec
->kctls
.list
)
11917 add_mixer(spec
, spec
->kctls
.list
);
11919 if (spec
->autocfg
.speaker_pins
[0] != 0x1d)
11920 add_mixer(spec
, alc268_beep_mixer
);
11922 add_verb(spec
, alc268_volume_init_verbs
);
11923 spec
->num_mux_defs
= 1;
11924 spec
->input_mux
= &spec
->private_imux
[0];
11926 err
= alc_auto_add_mic_boost(codec
);
11933 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11934 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11935 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11937 /* init callback for auto-configuration model -- overriding the default init */
11938 static void alc268_auto_init(struct hda_codec
*codec
)
11940 struct alc_spec
*spec
= codec
->spec
;
11941 alc268_auto_init_multi_out(codec
);
11942 alc268_auto_init_hp_out(codec
);
11943 alc268_auto_init_mono_speaker_out(codec
);
11944 alc268_auto_init_analog_input(codec
);
11945 if (spec
->unsol_event
)
11946 alc_inithook(codec
);
11950 * configuration and preset
11952 static const char *alc268_models
[ALC268_MODEL_LAST
] = {
11953 [ALC267_QUANTA_IL1
] = "quanta-il1",
11954 [ALC268_3ST
] = "3stack",
11955 [ALC268_TOSHIBA
] = "toshiba",
11956 [ALC268_ACER
] = "acer",
11957 [ALC268_ACER_DMIC
] = "acer-dmic",
11958 [ALC268_ACER_ASPIRE_ONE
] = "acer-aspire",
11959 [ALC268_DELL
] = "dell",
11960 [ALC268_ZEPTO
] = "zepto",
11961 #ifdef CONFIG_SND_DEBUG
11962 [ALC268_TEST
] = "test",
11964 [ALC268_AUTO
] = "auto",
11967 static struct snd_pci_quirk alc268_cfg_tbl
[] = {
11968 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER
),
11969 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER
),
11970 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER
),
11971 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER
),
11972 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER
),
11973 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11974 ALC268_ACER_ASPIRE_ONE
),
11975 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL
),
11976 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL
),
11977 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA
),
11978 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST
),
11979 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA
),
11980 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA
),
11981 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA
),
11982 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA
),
11983 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER
),
11984 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1
),
11985 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO
),
11989 static struct alc_config_preset alc268_presets
[] = {
11990 [ALC267_QUANTA_IL1
] = {
11991 .mixers
= { alc267_quanta_il1_mixer
, alc268_beep_mixer
},
11992 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
11993 alc267_quanta_il1_verbs
},
11994 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
11995 .dac_nids
= alc268_dac_nids
,
11996 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
11997 .adc_nids
= alc268_adc_nids_alt
,
11999 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12000 .channel_mode
= alc268_modes
,
12001 .input_mux
= &alc268_capture_source
,
12002 .unsol_event
= alc267_quanta_il1_unsol_event
,
12003 .init_hook
= alc267_quanta_il1_automute
,
12006 .mixers
= { alc268_base_mixer
, alc268_capture_alt_mixer
,
12007 alc268_beep_mixer
},
12008 .init_verbs
= { alc268_base_init_verbs
},
12009 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12010 .dac_nids
= alc268_dac_nids
,
12011 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12012 .adc_nids
= alc268_adc_nids_alt
,
12013 .capsrc_nids
= alc268_capsrc_nids
,
12015 .dig_out_nid
= ALC268_DIGOUT_NID
,
12016 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12017 .channel_mode
= alc268_modes
,
12018 .input_mux
= &alc268_capture_source
,
12020 [ALC268_TOSHIBA
] = {
12021 .mixers
= { alc268_base_mixer
, alc268_capture_alt_mixer
,
12022 alc268_beep_mixer
},
12023 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12024 alc268_toshiba_verbs
},
12025 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12026 .dac_nids
= alc268_dac_nids
,
12027 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12028 .adc_nids
= alc268_adc_nids_alt
,
12029 .capsrc_nids
= alc268_capsrc_nids
,
12031 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12032 .channel_mode
= alc268_modes
,
12033 .input_mux
= &alc268_capture_source
,
12034 .unsol_event
= alc268_toshiba_unsol_event
,
12035 .init_hook
= alc268_toshiba_automute
,
12038 .mixers
= { alc268_acer_mixer
, alc268_capture_alt_mixer
,
12039 alc268_beep_mixer
},
12040 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12041 alc268_acer_verbs
},
12042 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12043 .dac_nids
= alc268_dac_nids
,
12044 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12045 .adc_nids
= alc268_adc_nids_alt
,
12046 .capsrc_nids
= alc268_capsrc_nids
,
12048 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12049 .channel_mode
= alc268_modes
,
12050 .input_mux
= &alc268_acer_capture_source
,
12051 .unsol_event
= alc268_acer_unsol_event
,
12052 .init_hook
= alc268_acer_init_hook
,
12054 [ALC268_ACER_DMIC
] = {
12055 .mixers
= { alc268_acer_dmic_mixer
, alc268_capture_alt_mixer
,
12056 alc268_beep_mixer
},
12057 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12058 alc268_acer_verbs
},
12059 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12060 .dac_nids
= alc268_dac_nids
,
12061 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12062 .adc_nids
= alc268_adc_nids_alt
,
12063 .capsrc_nids
= alc268_capsrc_nids
,
12065 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12066 .channel_mode
= alc268_modes
,
12067 .input_mux
= &alc268_acer_dmic_capture_source
,
12068 .unsol_event
= alc268_acer_unsol_event
,
12069 .init_hook
= alc268_acer_init_hook
,
12071 [ALC268_ACER_ASPIRE_ONE
] = {
12072 .mixers
= { alc268_acer_aspire_one_mixer
,
12074 alc268_capture_alt_mixer
},
12075 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12076 alc268_acer_aspire_one_verbs
},
12077 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12078 .dac_nids
= alc268_dac_nids
,
12079 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12080 .adc_nids
= alc268_adc_nids_alt
,
12081 .capsrc_nids
= alc268_capsrc_nids
,
12083 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12084 .channel_mode
= alc268_modes
,
12085 .input_mux
= &alc268_acer_lc_capture_source
,
12086 .unsol_event
= alc268_acer_lc_unsol_event
,
12087 .init_hook
= alc268_acer_lc_init_hook
,
12090 .mixers
= { alc268_dell_mixer
, alc268_beep_mixer
},
12091 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12092 alc268_dell_verbs
},
12093 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12094 .dac_nids
= alc268_dac_nids
,
12096 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12097 .channel_mode
= alc268_modes
,
12098 .unsol_event
= alc268_dell_unsol_event
,
12099 .init_hook
= alc268_dell_init_hook
,
12100 .input_mux
= &alc268_capture_source
,
12103 .mixers
= { alc268_base_mixer
, alc268_capture_alt_mixer
,
12104 alc268_beep_mixer
},
12105 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12106 alc268_toshiba_verbs
},
12107 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12108 .dac_nids
= alc268_dac_nids
,
12109 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12110 .adc_nids
= alc268_adc_nids_alt
,
12111 .capsrc_nids
= alc268_capsrc_nids
,
12113 .dig_out_nid
= ALC268_DIGOUT_NID
,
12114 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12115 .channel_mode
= alc268_modes
,
12116 .input_mux
= &alc268_capture_source
,
12117 .unsol_event
= alc268_toshiba_unsol_event
,
12118 .init_hook
= alc268_toshiba_automute
12120 #ifdef CONFIG_SND_DEBUG
12122 .mixers
= { alc268_test_mixer
, alc268_capture_mixer
},
12123 .init_verbs
= { alc268_base_init_verbs
, alc268_eapd_verbs
,
12124 alc268_volume_init_verbs
},
12125 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
12126 .dac_nids
= alc268_dac_nids
,
12127 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
12128 .adc_nids
= alc268_adc_nids_alt
,
12129 .capsrc_nids
= alc268_capsrc_nids
,
12131 .dig_out_nid
= ALC268_DIGOUT_NID
,
12132 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
12133 .channel_mode
= alc268_modes
,
12134 .input_mux
= &alc268_capture_source
,
12139 static int patch_alc268(struct hda_codec
*codec
)
12141 struct alc_spec
*spec
;
12143 int i
, has_beep
, err
;
12145 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
12149 codec
->spec
= spec
;
12151 board_config
= snd_hda_check_board_config(codec
, ALC268_MODEL_LAST
,
12155 if (board_config
< 0 || board_config
>= ALC268_MODEL_LAST
) {
12156 printk(KERN_INFO
"hda_codec: Unknown model for ALC268, "
12157 "trying auto-probe from BIOS...\n");
12158 board_config
= ALC268_AUTO
;
12161 if (board_config
== ALC268_AUTO
) {
12162 /* automatic parse from the BIOS config */
12163 err
= alc268_parse_auto_config(codec
);
12169 "hda_codec: Cannot set up configuration "
12170 "from BIOS. Using base mode...\n");
12171 board_config
= ALC268_3ST
;
12175 if (board_config
!= ALC268_AUTO
)
12176 setup_preset(spec
, &alc268_presets
[board_config
]);
12178 if (codec
->vendor_id
== 0x10ec0267) {
12179 spec
->stream_name_analog
= "ALC267 Analog";
12180 spec
->stream_name_digital
= "ALC267 Digital";
12182 spec
->stream_name_analog
= "ALC268 Analog";
12183 spec
->stream_name_digital
= "ALC268 Digital";
12186 spec
->stream_analog_playback
= &alc268_pcm_analog_playback
;
12187 spec
->stream_analog_capture
= &alc268_pcm_analog_capture
;
12188 spec
->stream_analog_alt_capture
= &alc268_pcm_analog_alt_capture
;
12190 spec
->stream_digital_playback
= &alc268_pcm_digital_playback
;
12193 for (i
= 0; i
< spec
->num_mixers
; i
++) {
12194 if (spec
->mixers
[i
] == alc268_beep_mixer
) {
12201 err
= snd_hda_attach_beep_device(codec
, 0x1);
12206 if (!query_amp_caps(codec
, 0x1d, HDA_INPUT
))
12207 /* override the amp caps for beep generator */
12208 snd_hda_override_amp_caps(codec
, 0x1d, HDA_INPUT
,
12209 (0x0c << AC_AMPCAP_OFFSET_SHIFT
) |
12210 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT
) |
12211 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT
) |
12212 (0 << AC_AMPCAP_MUTE_SHIFT
));
12215 if (!spec
->no_analog
&& !spec
->adc_nids
&& spec
->input_mux
) {
12216 /* check whether NID 0x07 is valid */
12217 unsigned int wcap
= get_wcaps(codec
, 0x07);
12221 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
12222 if (wcap
!= AC_WID_AUD_IN
|| spec
->input_mux
->num_items
== 1) {
12223 spec
->adc_nids
= alc268_adc_nids_alt
;
12224 spec
->num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
);
12225 add_mixer(spec
, alc268_capture_alt_mixer
);
12227 spec
->adc_nids
= alc268_adc_nids
;
12228 spec
->num_adc_nids
= ARRAY_SIZE(alc268_adc_nids
);
12229 add_mixer(spec
, alc268_capture_mixer
);
12231 spec
->capsrc_nids
= alc268_capsrc_nids
;
12232 /* set default input source */
12233 for (i
= 0; i
< spec
->num_adc_nids
; i
++)
12234 snd_hda_codec_write_cache(codec
, alc268_capsrc_nids
[i
],
12235 0, AC_VERB_SET_CONNECT_SEL
,
12236 spec
->input_mux
->items
[0].index
);
12239 spec
->vmaster_nid
= 0x02;
12241 codec
->patch_ops
= alc_patch_ops
;
12242 if (board_config
== ALC268_AUTO
)
12243 spec
->init_hook
= alc268_auto_init
;
12245 codec
->proc_widget_hook
= print_realtek_coef
;
12251 * ALC269 channel source setting (2 channel)
12253 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12255 #define alc269_dac_nids alc260_dac_nids
12257 static hda_nid_t alc269_adc_nids
[1] = {
12262 static hda_nid_t alc269_capsrc_nids
[1] = {
12266 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12270 static struct hda_input_mux alc269_eeepc_dmic_capture_source
= {
12278 static struct hda_input_mux alc269_eeepc_amic_capture_source
= {
12286 #define alc269_modes alc260_modes
12287 #define alc269_capture_source alc880_lg_lw_capture_source
12289 static struct snd_kcontrol_new alc269_base_mixer
[] = {
12290 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
12291 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
12292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
12293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
12294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
12295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
12296 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
12297 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
12298 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
12299 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
12300 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
12301 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
12305 static struct snd_kcontrol_new alc269_quanta_fl1_mixer
[] = {
12306 /* output mixer control */
12307 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol
),
12309 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
12310 .name
= "Master Playback Switch",
12311 .info
= snd_hda_mixer_amp_switch_info
,
12312 .get
= snd_hda_mixer_amp_switch_get
,
12313 .put
= alc268_acer_master_sw_put
,
12314 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
12316 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
12317 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
12318 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
12319 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
12320 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
12321 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT
),
12325 static struct snd_kcontrol_new alc269_lifebook_mixer
[] = {
12326 /* output mixer control */
12327 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol
),
12329 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
12330 .name
= "Master Playback Switch",
12331 .info
= snd_hda_mixer_amp_switch_info
,
12332 .get
= snd_hda_mixer_amp_switch_get
,
12333 .put
= alc268_acer_master_sw_put
,
12334 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
12336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
12337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
12338 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
12339 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
12340 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
12341 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT
),
12342 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT
),
12343 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT
),
12344 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT
),
12348 /* bind volumes of both NID 0x0c and 0x0d */
12349 static struct hda_bind_ctls alc269_epc_bind_vol
= {
12350 .ops
= &snd_hda_bind_vol
,
12352 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
12353 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT
),
12358 static struct snd_kcontrol_new alc269_eeepc_mixer
[] = {
12359 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
12360 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol
),
12361 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
12365 /* capture mixer elements */
12366 static struct snd_kcontrol_new alc269_epc_capture_mixer
[] = {
12367 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
12368 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
12369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
12374 static struct snd_kcontrol_new alc269_fujitsu_mixer
[] = {
12375 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
12376 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
12377 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol
),
12381 static struct hda_verb alc269_quanta_fl1_verbs
[] = {
12382 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
12383 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
12385 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
12386 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
12387 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12391 static struct hda_verb alc269_lifebook_verbs
[] = {
12392 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
12393 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01},
12394 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
12396 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
12397 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
12398 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
12399 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
12400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
12401 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12405 /* toggle speaker-output according to the hp-jack state */
12406 static void alc269_quanta_fl1_speaker_automute(struct hda_codec
*codec
)
12408 unsigned int present
;
12409 unsigned char bits
;
12411 present
= snd_hda_codec_read(codec
, 0x15, 0,
12412 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12413 bits
= present
? AMP_IN_MUTE(0) : 0;
12414 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
12415 AMP_IN_MUTE(0), bits
);
12416 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
12417 AMP_IN_MUTE(0), bits
);
12419 snd_hda_codec_write(codec
, 0x20, 0,
12420 AC_VERB_SET_COEF_INDEX
, 0x0c);
12421 snd_hda_codec_write(codec
, 0x20, 0,
12422 AC_VERB_SET_PROC_COEF
, 0x680);
12424 snd_hda_codec_write(codec
, 0x20, 0,
12425 AC_VERB_SET_COEF_INDEX
, 0x0c);
12426 snd_hda_codec_write(codec
, 0x20, 0,
12427 AC_VERB_SET_PROC_COEF
, 0x480);
12430 /* toggle speaker-output according to the hp-jacks state */
12431 static void alc269_lifebook_speaker_automute(struct hda_codec
*codec
)
12433 unsigned int present
;
12434 unsigned char bits
;
12436 /* Check laptop headphone socket */
12437 present
= snd_hda_codec_read(codec
, 0x15, 0,
12438 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12440 /* Check port replicator headphone socket */
12441 present
|= snd_hda_codec_read(codec
, 0x1a, 0,
12442 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12444 bits
= present
? AMP_IN_MUTE(0) : 0;
12445 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
12446 AMP_IN_MUTE(0), bits
);
12447 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
12448 AMP_IN_MUTE(0), bits
);
12450 snd_hda_codec_write(codec
, 0x20, 0,
12451 AC_VERB_SET_COEF_INDEX
, 0x0c);
12452 snd_hda_codec_write(codec
, 0x20, 0,
12453 AC_VERB_SET_PROC_COEF
, 0x680);
12455 snd_hda_codec_write(codec
, 0x20, 0,
12456 AC_VERB_SET_COEF_INDEX
, 0x0c);
12457 snd_hda_codec_write(codec
, 0x20, 0,
12458 AC_VERB_SET_PROC_COEF
, 0x480);
12461 static void alc269_quanta_fl1_mic_automute(struct hda_codec
*codec
)
12463 unsigned int present
;
12465 present
= snd_hda_codec_read(codec
, 0x18, 0,
12466 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12467 snd_hda_codec_write(codec
, 0x23, 0,
12468 AC_VERB_SET_CONNECT_SEL
, present
? 0x0 : 0x1);
12471 static void alc269_lifebook_mic_autoswitch(struct hda_codec
*codec
)
12473 unsigned int present_laptop
;
12474 unsigned int present_dock
;
12476 present_laptop
= snd_hda_codec_read(codec
, 0x18, 0,
12477 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12479 present_dock
= snd_hda_codec_read(codec
, 0x1b, 0,
12480 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12482 /* Laptop mic port overrides dock mic port, design decision */
12484 snd_hda_codec_write(codec
, 0x23, 0,
12485 AC_VERB_SET_CONNECT_SEL
, 0x3);
12486 if (present_laptop
)
12487 snd_hda_codec_write(codec
, 0x23, 0,
12488 AC_VERB_SET_CONNECT_SEL
, 0x0);
12489 if (!present_dock
&& !present_laptop
)
12490 snd_hda_codec_write(codec
, 0x23, 0,
12491 AC_VERB_SET_CONNECT_SEL
, 0x1);
12494 static void alc269_quanta_fl1_unsol_event(struct hda_codec
*codec
,
12497 if ((res
>> 26) == ALC880_HP_EVENT
)
12498 alc269_quanta_fl1_speaker_automute(codec
);
12499 if ((res
>> 26) == ALC880_MIC_EVENT
)
12500 alc269_quanta_fl1_mic_automute(codec
);
12503 static void alc269_lifebook_unsol_event(struct hda_codec
*codec
,
12506 if ((res
>> 26) == ALC880_HP_EVENT
)
12507 alc269_lifebook_speaker_automute(codec
);
12508 if ((res
>> 26) == ALC880_MIC_EVENT
)
12509 alc269_lifebook_mic_autoswitch(codec
);
12512 static void alc269_quanta_fl1_init_hook(struct hda_codec
*codec
)
12514 alc269_quanta_fl1_speaker_automute(codec
);
12515 alc269_quanta_fl1_mic_automute(codec
);
12518 static void alc269_lifebook_init_hook(struct hda_codec
*codec
)
12520 alc269_lifebook_speaker_automute(codec
);
12521 alc269_lifebook_mic_autoswitch(codec
);
12524 static struct hda_verb alc269_eeepc_dmic_init_verbs
[] = {
12525 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
12526 {0x23, AC_VERB_SET_CONNECT_SEL
, 0x05},
12527 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb026 },
12528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7019 | (0x00 << 8))},
12529 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12530 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
12531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
12535 static struct hda_verb alc269_eeepc_amic_init_verbs
[] = {
12536 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
12537 {0x23, AC_VERB_SET_CONNECT_SEL
, 0x01},
12538 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb026 },
12539 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x701b | (0x00 << 8))},
12540 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
12541 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
12545 /* toggle speaker-output according to the hp-jack state */
12546 static void alc269_speaker_automute(struct hda_codec
*codec
)
12548 unsigned int present
;
12549 unsigned char bits
;
12551 present
= snd_hda_codec_read(codec
, 0x15, 0,
12552 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12553 bits
= present
? AMP_IN_MUTE(0) : 0;
12554 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
12555 AMP_IN_MUTE(0), bits
);
12556 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
12557 AMP_IN_MUTE(0), bits
);
12560 static void alc269_eeepc_dmic_automute(struct hda_codec
*codec
)
12562 unsigned int present
;
12564 present
= snd_hda_codec_read(codec
, 0x18, 0,
12565 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12566 snd_hda_codec_write(codec
, 0x23, 0,
12567 AC_VERB_SET_CONNECT_SEL
, (present
? 0 : 5));
12570 static void alc269_eeepc_amic_automute(struct hda_codec
*codec
)
12572 unsigned int present
;
12574 present
= snd_hda_codec_read(codec
, 0x18, 0,
12575 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
12576 snd_hda_codec_write(codec
, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
12577 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
12578 snd_hda_codec_write(codec
, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
12579 0x7000 | (0x01 << 8) | (present
? 0x80 : 0));
12582 /* unsolicited event for HP jack sensing */
12583 static void alc269_eeepc_dmic_unsol_event(struct hda_codec
*codec
,
12586 if ((res
>> 26) == ALC880_HP_EVENT
)
12587 alc269_speaker_automute(codec
);
12589 if ((res
>> 26) == ALC880_MIC_EVENT
)
12590 alc269_eeepc_dmic_automute(codec
);
12593 static void alc269_eeepc_dmic_inithook(struct hda_codec
*codec
)
12595 alc269_speaker_automute(codec
);
12596 alc269_eeepc_dmic_automute(codec
);
12599 /* unsolicited event for HP jack sensing */
12600 static void alc269_eeepc_amic_unsol_event(struct hda_codec
*codec
,
12603 if ((res
>> 26) == ALC880_HP_EVENT
)
12604 alc269_speaker_automute(codec
);
12606 if ((res
>> 26) == ALC880_MIC_EVENT
)
12607 alc269_eeepc_amic_automute(codec
);
12610 static void alc269_eeepc_amic_inithook(struct hda_codec
*codec
)
12612 alc269_speaker_automute(codec
);
12613 alc269_eeepc_amic_automute(codec
);
12617 * generic initialization of ADC, input mixers and output mixers
12619 static struct hda_verb alc269_init_verbs
[] = {
12621 * Unmute ADC0 and set the default input to mic-in
12623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
12625 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12626 * analog-loopback mixer widget
12627 * Note: PASD motherboards uses the Line In 2 as the input for
12628 * front panel mic (mic 2)
12630 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
12632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
12633 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
12634 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
12635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
12638 * Set up output mixers (0x0c - 0x0e)
12640 /* set vol=0 to output mixers */
12641 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
12642 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
12644 /* set up input amps for analog loopback */
12645 /* Amp Indices: DAC = 0, mixer = 1 */
12646 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
12647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
12648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
12649 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
12650 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
12651 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
12653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
12654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
12655 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
12656 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
12657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
12658 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12659 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
12661 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
12662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
12663 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
12664 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
12665 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
12666 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
12667 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
12669 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
12670 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
12672 /* FIXME: use matrix-type input source selection */
12673 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12674 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
12676 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
12677 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
12678 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
12681 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
12682 {0x15, AC_VERB_SET_EAPD_BTLENABLE
, 2},
12686 /* add playback controls from the parsed DAC table */
12687 static int alc269_auto_create_multi_out_ctls(struct alc_spec
*spec
,
12688 const struct auto_pin_cfg
*cfg
)
12693 spec
->multiout
.num_dacs
= 1; /* only use one dac */
12694 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
12695 spec
->multiout
.dac_nids
[0] = 2;
12697 nid
= cfg
->line_out_pins
[0];
12699 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
12700 "Front Playback Volume",
12701 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
));
12704 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
12705 "Front Playback Switch",
12706 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
12711 nid
= cfg
->speaker_pins
[0];
12713 if (!cfg
->line_out_pins
[0]) {
12714 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
12715 "Speaker Playback Volume",
12716 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12722 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
12723 "Speaker Playback Switch",
12724 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
12729 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
12730 "Speaker Playback Switch",
12731 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
12737 nid
= cfg
->hp_pins
[0];
12739 /* spec->multiout.hp_nid = 2; */
12740 if (!cfg
->line_out_pins
[0] && !cfg
->speaker_pins
[0]) {
12741 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
12742 "Headphone Playback Volume",
12743 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12749 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
12750 "Headphone Playback Switch",
12751 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
12756 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
12757 "Headphone Playback Switch",
12758 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
12767 static int alc269_auto_create_analog_input_ctls(struct alc_spec
*spec
,
12768 const struct auto_pin_cfg
*cfg
)
12772 err
= alc880_auto_create_analog_input_ctls(spec
, cfg
);
12775 /* digital-mic input pin is excluded in alc880_auto_create..()
12776 * because it's under 0x18
12778 if (cfg
->input_pins
[AUTO_PIN_MIC
] == 0x12 ||
12779 cfg
->input_pins
[AUTO_PIN_FRONT_MIC
] == 0x12) {
12780 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
12781 imux
->items
[imux
->num_items
].label
= "Int Mic";
12782 imux
->items
[imux
->num_items
].index
= 0x05;
12788 #ifdef CONFIG_SND_HDA_POWER_SAVE
12789 #define alc269_loopbacks alc880_loopbacks
12792 /* pcm configuration: identiacal with ALC880 */
12793 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12794 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12795 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12796 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12799 * BIOS auto configuration
12801 static int alc269_parse_auto_config(struct hda_codec
*codec
)
12803 struct alc_spec
*spec
= codec
->spec
;
12805 static hda_nid_t alc269_ignore
[] = { 0x1d, 0 };
12807 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
12812 err
= alc269_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
12815 err
= alc269_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
12819 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
12821 if (spec
->autocfg
.dig_outs
)
12822 spec
->multiout
.dig_out_nid
= ALC269_DIGOUT_NID
;
12824 if (spec
->kctls
.list
)
12825 add_mixer(spec
, spec
->kctls
.list
);
12827 add_verb(spec
, alc269_init_verbs
);
12828 spec
->num_mux_defs
= 1;
12829 spec
->input_mux
= &spec
->private_imux
[0];
12830 /* set default input source */
12831 snd_hda_codec_write_cache(codec
, alc269_capsrc_nids
[0],
12832 0, AC_VERB_SET_CONNECT_SEL
,
12833 spec
->input_mux
->items
[0].index
);
12835 err
= alc_auto_add_mic_boost(codec
);
12839 if (!spec
->cap_mixer
&& !spec
->no_analog
)
12840 set_capture_mixer(spec
);
12845 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12846 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12847 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12850 /* init callback for auto-configuration model -- overriding the default init */
12851 static void alc269_auto_init(struct hda_codec
*codec
)
12853 struct alc_spec
*spec
= codec
->spec
;
12854 alc269_auto_init_multi_out(codec
);
12855 alc269_auto_init_hp_out(codec
);
12856 alc269_auto_init_analog_input(codec
);
12857 if (spec
->unsol_event
)
12858 alc_inithook(codec
);
12862 * configuration and preset
12864 static const char *alc269_models
[ALC269_MODEL_LAST
] = {
12865 [ALC269_BASIC
] = "basic",
12866 [ALC269_QUANTA_FL1
] = "quanta",
12867 [ALC269_ASUS_EEEPC_P703
] = "eeepc-p703",
12868 [ALC269_ASUS_EEEPC_P901
] = "eeepc-p901",
12869 [ALC269_FUJITSU
] = "fujitsu",
12870 [ALC269_LIFEBOOK
] = "lifebook"
12873 static struct snd_pci_quirk alc269_cfg_tbl
[] = {
12874 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1
),
12875 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12876 ALC269_ASUS_EEEPC_P703
),
12877 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12878 ALC269_ASUS_EEEPC_P901
),
12879 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12880 ALC269_ASUS_EEEPC_P901
),
12881 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU
),
12882 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK
),
12886 static struct alc_config_preset alc269_presets
[] = {
12888 .mixers
= { alc269_base_mixer
},
12889 .init_verbs
= { alc269_init_verbs
},
12890 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12891 .dac_nids
= alc269_dac_nids
,
12893 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12894 .channel_mode
= alc269_modes
,
12895 .input_mux
= &alc269_capture_source
,
12897 [ALC269_QUANTA_FL1
] = {
12898 .mixers
= { alc269_quanta_fl1_mixer
},
12899 .init_verbs
= { alc269_init_verbs
, alc269_quanta_fl1_verbs
},
12900 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12901 .dac_nids
= alc269_dac_nids
,
12903 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12904 .channel_mode
= alc269_modes
,
12905 .input_mux
= &alc269_capture_source
,
12906 .unsol_event
= alc269_quanta_fl1_unsol_event
,
12907 .init_hook
= alc269_quanta_fl1_init_hook
,
12909 [ALC269_ASUS_EEEPC_P703
] = {
12910 .mixers
= { alc269_eeepc_mixer
},
12911 .cap_mixer
= alc269_epc_capture_mixer
,
12912 .init_verbs
= { alc269_init_verbs
,
12913 alc269_eeepc_amic_init_verbs
},
12914 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12915 .dac_nids
= alc269_dac_nids
,
12917 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12918 .channel_mode
= alc269_modes
,
12919 .input_mux
= &alc269_eeepc_amic_capture_source
,
12920 .unsol_event
= alc269_eeepc_amic_unsol_event
,
12921 .init_hook
= alc269_eeepc_amic_inithook
,
12923 [ALC269_ASUS_EEEPC_P901
] = {
12924 .mixers
= { alc269_eeepc_mixer
},
12925 .cap_mixer
= alc269_epc_capture_mixer
,
12926 .init_verbs
= { alc269_init_verbs
,
12927 alc269_eeepc_dmic_init_verbs
},
12928 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12929 .dac_nids
= alc269_dac_nids
,
12931 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12932 .channel_mode
= alc269_modes
,
12933 .input_mux
= &alc269_eeepc_dmic_capture_source
,
12934 .unsol_event
= alc269_eeepc_dmic_unsol_event
,
12935 .init_hook
= alc269_eeepc_dmic_inithook
,
12937 [ALC269_FUJITSU
] = {
12938 .mixers
= { alc269_fujitsu_mixer
},
12939 .cap_mixer
= alc269_epc_capture_mixer
,
12940 .init_verbs
= { alc269_init_verbs
,
12941 alc269_eeepc_dmic_init_verbs
},
12942 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12943 .dac_nids
= alc269_dac_nids
,
12945 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12946 .channel_mode
= alc269_modes
,
12947 .input_mux
= &alc269_eeepc_dmic_capture_source
,
12948 .unsol_event
= alc269_eeepc_dmic_unsol_event
,
12949 .init_hook
= alc269_eeepc_dmic_inithook
,
12951 [ALC269_LIFEBOOK
] = {
12952 .mixers
= { alc269_lifebook_mixer
},
12953 .init_verbs
= { alc269_init_verbs
, alc269_lifebook_verbs
},
12954 .num_dacs
= ARRAY_SIZE(alc269_dac_nids
),
12955 .dac_nids
= alc269_dac_nids
,
12957 .num_channel_mode
= ARRAY_SIZE(alc269_modes
),
12958 .channel_mode
= alc269_modes
,
12959 .input_mux
= &alc269_capture_source
,
12960 .unsol_event
= alc269_lifebook_unsol_event
,
12961 .init_hook
= alc269_lifebook_init_hook
,
12965 static int patch_alc269(struct hda_codec
*codec
)
12967 struct alc_spec
*spec
;
12971 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
12975 codec
->spec
= spec
;
12977 alc_fix_pll_init(codec
, 0x20, 0x04, 15);
12979 board_config
= snd_hda_check_board_config(codec
, ALC269_MODEL_LAST
,
12983 if (board_config
< 0) {
12984 printk(KERN_INFO
"hda_codec: Unknown model for ALC269, "
12985 "trying auto-probe from BIOS...\n");
12986 board_config
= ALC269_AUTO
;
12989 if (board_config
== ALC269_AUTO
) {
12990 /* automatic parse from the BIOS config */
12991 err
= alc269_parse_auto_config(codec
);
12997 "hda_codec: Cannot set up configuration "
12998 "from BIOS. Using base mode...\n");
12999 board_config
= ALC269_BASIC
;
13003 err
= snd_hda_attach_beep_device(codec
, 0x1);
13009 if (board_config
!= ALC269_AUTO
)
13010 setup_preset(spec
, &alc269_presets
[board_config
]);
13012 spec
->stream_name_analog
= "ALC269 Analog";
13013 spec
->stream_analog_playback
= &alc269_pcm_analog_playback
;
13014 spec
->stream_analog_capture
= &alc269_pcm_analog_capture
;
13016 spec
->stream_name_digital
= "ALC269 Digital";
13017 spec
->stream_digital_playback
= &alc269_pcm_digital_playback
;
13018 spec
->stream_digital_capture
= &alc269_pcm_digital_capture
;
13020 spec
->adc_nids
= alc269_adc_nids
;
13021 spec
->num_adc_nids
= ARRAY_SIZE(alc269_adc_nids
);
13022 spec
->capsrc_nids
= alc269_capsrc_nids
;
13023 if (!spec
->cap_mixer
)
13024 set_capture_mixer(spec
);
13025 set_beep_amp(spec
, 0x0b, 0x04, HDA_INPUT
);
13027 codec
->patch_ops
= alc_patch_ops
;
13028 if (board_config
== ALC269_AUTO
)
13029 spec
->init_hook
= alc269_auto_init
;
13030 #ifdef CONFIG_SND_HDA_POWER_SAVE
13031 if (!spec
->loopback
.amplist
)
13032 spec
->loopback
.amplist
= alc269_loopbacks
;
13034 codec
->proc_widget_hook
= print_realtek_coef
;
13040 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13044 * set the path ways for 2 channel output
13045 * need to set the codec line out and mic 1 pin widgets to inputs
13047 static struct hda_verb alc861_threestack_ch2_init
[] = {
13048 /* set pin widget 1Ah (line in) for input */
13049 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13050 /* set pin widget 18h (mic1/2) for input, for mic also enable
13053 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13055 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c },
13057 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
13058 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8)) }, /*line-in*/
13064 * need to set the codec line out and mic 1 pin widgets to outputs
13066 static struct hda_verb alc861_threestack_ch6_init
[] = {
13067 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13068 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13069 /* set pin widget 18h (mic1) for output (CLFE)*/
13070 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13072 { 0x0c, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13073 { 0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13075 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080 },
13077 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
13078 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8)) }, /*line in*/
13083 static struct hda_channel_mode alc861_threestack_modes
[2] = {
13084 { 2, alc861_threestack_ch2_init
},
13085 { 6, alc861_threestack_ch6_init
},
13087 /* Set mic1 as input and unmute the mixer */
13088 static struct hda_verb alc861_uniwill_m31_ch2_init
[] = {
13089 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13090 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
13093 /* Set mic1 as output and mute mixer */
13094 static struct hda_verb alc861_uniwill_m31_ch4_init
[] = {
13095 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13096 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
13100 static struct hda_channel_mode alc861_uniwill_m31_modes
[2] = {
13101 { 2, alc861_uniwill_m31_ch2_init
},
13102 { 4, alc861_uniwill_m31_ch4_init
},
13105 /* Set mic1 and line-in as input and unmute the mixer */
13106 static struct hda_verb alc861_asus_ch2_init
[] = {
13107 /* set pin widget 1Ah (line in) for input */
13108 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13109 /* set pin widget 18h (mic1/2) for input, for mic also enable
13112 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13114 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c },
13116 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
13117 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8)) }, /*line-in*/
13121 /* Set mic1 nad line-in as output and mute mixer */
13122 static struct hda_verb alc861_asus_ch6_init
[] = {
13123 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13124 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13125 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13126 /* set pin widget 18h (mic1) for output (CLFE)*/
13127 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13128 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13129 { 0x0c, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13130 { 0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13132 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080 },
13134 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
13135 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8)) }, /*line in*/
13140 static struct hda_channel_mode alc861_asus_modes
[2] = {
13141 { 2, alc861_asus_ch2_init
},
13142 { 6, alc861_asus_ch6_init
},
13147 static struct snd_kcontrol_new alc861_base_mixer
[] = {
13148 /* output mixer control */
13149 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
13150 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
13151 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
13152 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
13153 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT
),
13155 /*Input mixer control */
13156 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13157 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13158 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
13159 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
13160 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
13161 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
13162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
13163 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
13164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
13165 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
13170 static struct snd_kcontrol_new alc861_3ST_mixer
[] = {
13171 /* output mixer control */
13172 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
13173 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
13174 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
13175 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
13176 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13178 /* Input mixer control */
13179 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13180 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13181 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
13182 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
13183 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
13184 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
13185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
13186 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
13187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
13188 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
13191 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
13192 .name
= "Channel Mode",
13193 .info
= alc_ch_mode_info
,
13194 .get
= alc_ch_mode_get
,
13195 .put
= alc_ch_mode_put
,
13196 .private_value
= ARRAY_SIZE(alc861_threestack_modes
),
13201 static struct snd_kcontrol_new alc861_toshiba_mixer
[] = {
13202 /* output mixer control */
13203 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
13204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
13205 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
13210 static struct snd_kcontrol_new alc861_uniwill_m31_mixer
[] = {
13211 /* output mixer control */
13212 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
13213 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
13214 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
13215 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
13216 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13218 /* Input mixer control */
13219 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13220 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13221 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
13222 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
13223 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
13224 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
13225 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
13226 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
13227 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
13228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
13231 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
13232 .name
= "Channel Mode",
13233 .info
= alc_ch_mode_info
,
13234 .get
= alc_ch_mode_get
,
13235 .put
= alc_ch_mode_put
,
13236 .private_value
= ARRAY_SIZE(alc861_uniwill_m31_modes
),
13241 static struct snd_kcontrol_new alc861_asus_mixer
[] = {
13242 /* output mixer control */
13243 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
13244 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
13245 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
13246 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
13247 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT
),
13249 /* Input mixer control */
13250 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT
),
13251 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
13252 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
13253 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
13254 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
13255 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
13256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
13257 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
13258 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
13259 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT
),
13262 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
13263 .name
= "Channel Mode",
13264 .info
= alc_ch_mode_info
,
13265 .get
= alc_ch_mode_get
,
13266 .put
= alc_ch_mode_put
,
13267 .private_value
= ARRAY_SIZE(alc861_asus_modes
),
13272 /* additional mixer */
13273 static struct snd_kcontrol_new alc861_asus_laptop_mixer
[] = {
13274 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
13275 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
13280 * generic initialization of ADC, input mixers and output mixers
13282 static struct hda_verb alc861_base_init_verbs
[] = {
13284 * Unmute ADC0 and set the default input to mic-in
13286 /* port-A for surround (rear panel) */
13287 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13288 { 0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13289 /* port-B for mic-in (rear panel) with vref */
13290 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13291 /* port-C for line-in (rear panel) */
13292 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13293 /* port-D for Front */
13294 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13295 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13296 /* port-E for HP out (front panel) */
13297 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
13298 /* route front PCM to HP */
13299 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13300 /* port-F for mic-in (front panel) with vref */
13301 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13302 /* port-G for CLFE (rear panel) */
13303 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13304 { 0x1f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13305 /* port-H for side (rear panel) */
13306 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13307 { 0x20, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13309 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13310 /* route front mic to ADC1*/
13311 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
13312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13314 /* Unmute DAC0~3 & spdif out*/
13315 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13316 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13317 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13318 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13321 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13322 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13323 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13324 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13325 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13327 /* Unmute Stereo Mixer 15 */
13328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13329 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
13333 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13334 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13341 /* hp used DAC 3 (Front) */
13342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13348 static struct hda_verb alc861_threestack_init_verbs
[] = {
13350 * Unmute ADC0 and set the default input to mic-in
13352 /* port-A for surround (rear panel) */
13353 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13354 /* port-B for mic-in (rear panel) with vref */
13355 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13356 /* port-C for line-in (rear panel) */
13357 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13358 /* port-D for Front */
13359 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13360 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13361 /* port-E for HP out (front panel) */
13362 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
13363 /* route front PCM to HP */
13364 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13365 /* port-F for mic-in (front panel) with vref */
13366 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13367 /* port-G for CLFE (rear panel) */
13368 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13369 /* port-H for side (rear panel) */
13370 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13372 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13373 /* route front mic to ADC1*/
13374 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
13375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13376 /* Unmute DAC0~3 & spdif out*/
13377 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13378 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13379 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13380 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13383 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13384 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13385 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13386 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13387 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13389 /* Unmute Stereo Mixer 15 */
13390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13391 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13392 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13393 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
13395 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13396 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13397 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13398 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13401 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13403 /* hp used DAC 3 (Front) */
13404 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13405 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13409 static struct hda_verb alc861_uniwill_m31_init_verbs
[] = {
13411 * Unmute ADC0 and set the default input to mic-in
13413 /* port-A for surround (rear panel) */
13414 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13415 /* port-B for mic-in (rear panel) with vref */
13416 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13417 /* port-C for line-in (rear panel) */
13418 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13419 /* port-D for Front */
13420 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13421 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13422 /* port-E for HP out (front panel) */
13423 /* this has to be set to VREF80 */
13424 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13425 /* route front PCM to HP */
13426 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13427 /* port-F for mic-in (front panel) with vref */
13428 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13429 /* port-G for CLFE (rear panel) */
13430 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13431 /* port-H for side (rear panel) */
13432 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
13434 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13435 /* route front mic to ADC1*/
13436 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
13437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13438 /* Unmute DAC0~3 & spdif out*/
13439 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13440 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13441 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13442 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13445 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13446 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13447 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13448 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13449 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13451 /* Unmute Stereo Mixer 15 */
13452 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13453 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13455 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
13457 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13458 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13459 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13460 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13462 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13463 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13464 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13465 /* hp used DAC 3 (Front) */
13466 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13467 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13471 static struct hda_verb alc861_asus_init_verbs
[] = {
13473 * Unmute ADC0 and set the default input to mic-in
13475 /* port-A for surround (rear panel)
13476 * according to codec#0 this is the HP jack
13478 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 }, /* was 0x00 */
13479 /* route front PCM to HP */
13480 { 0x0e, AC_VERB_SET_CONNECT_SEL
, 0x01 },
13481 /* port-B for mic-in (rear panel) with vref */
13482 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13483 /* port-C for line-in (rear panel) */
13484 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13485 /* port-D for Front */
13486 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13487 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13488 /* port-E for HP out (front panel) */
13489 /* this has to be set to VREF80 */
13490 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13491 /* route front PCM to HP */
13492 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
13493 /* port-F for mic-in (front panel) with vref */
13494 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
13495 /* port-G for CLFE (rear panel) */
13496 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13497 /* port-H for side (rear panel) */
13498 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
13500 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
13501 /* route front mic to ADC1*/
13502 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
13503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13504 /* Unmute DAC0~3 & spdif out*/
13505 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13506 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13507 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13508 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13510 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13511 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13512 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13513 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13514 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13516 /* Unmute Stereo Mixer 15 */
13517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13519 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13520 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
13522 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13523 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13524 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13525 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13526 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13528 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13530 /* hp used DAC 3 (Front) */
13531 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13532 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13536 /* additional init verbs for ASUS laptops */
13537 static struct hda_verb alc861_asus_laptop_init_verbs
[] = {
13538 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x45 }, /* HP-out */
13539 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2) }, /* mute line-in */
13544 * generic initialization of ADC, input mixers and output mixers
13546 static struct hda_verb alc861_auto_init_verbs
[] = {
13548 * Unmute ADC0 and set the default input to mic-in
13550 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13553 /* Unmute DAC0~3 & spdif out*/
13554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
13555 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
13556 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
13557 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
13558 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
13560 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13561 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13562 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13563 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13564 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13566 /* Unmute Stereo Mixer 15 */
13567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13568 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c},
13572 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13573 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13574 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13575 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13576 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13577 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13578 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
13579 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
13581 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
13582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
13583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
13586 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
13587 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
13588 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
13590 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* set Mic 1 */
13595 static struct hda_verb alc861_toshiba_init_verbs
[] = {
13596 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
13601 /* toggle speaker-output according to the hp-jack state */
13602 static void alc861_toshiba_automute(struct hda_codec
*codec
)
13604 unsigned int present
;
13606 present
= snd_hda_codec_read(codec
, 0x0f, 0,
13607 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
13608 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_INPUT
, 0,
13609 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
13610 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_INPUT
, 3,
13611 HDA_AMP_MUTE
, present
? 0 : HDA_AMP_MUTE
);
13614 static void alc861_toshiba_unsol_event(struct hda_codec
*codec
,
13617 if ((res
>> 26) == ALC880_HP_EVENT
)
13618 alc861_toshiba_automute(codec
);
13621 /* pcm configuration: identiacal with ALC880 */
13622 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13623 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13624 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13625 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13628 #define ALC861_DIGOUT_NID 0x07
13630 static struct hda_channel_mode alc861_8ch_modes
[1] = {
13634 static hda_nid_t alc861_dac_nids
[4] = {
13635 /* front, surround, clfe, side */
13636 0x03, 0x06, 0x05, 0x04
13639 static hda_nid_t alc660_dac_nids
[3] = {
13640 /* front, clfe, surround */
13644 static hda_nid_t alc861_adc_nids
[1] = {
13649 static struct hda_input_mux alc861_capture_source
= {
13653 { "Front Mic", 0x3 },
13660 /* fill in the dac_nids table from the parsed pin configuration */
13661 static int alc861_auto_fill_dac_nids(struct alc_spec
*spec
,
13662 const struct auto_pin_cfg
*cfg
)
13667 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
13668 for (i
= 0; i
< cfg
->line_outs
; i
++) {
13669 nid
= cfg
->line_out_pins
[i
];
13671 if (i
>= ARRAY_SIZE(alc861_dac_nids
))
13673 spec
->multiout
.dac_nids
[i
] = alc861_dac_nids
[i
];
13676 spec
->multiout
.num_dacs
= cfg
->line_outs
;
13680 /* add playback controls from the parsed DAC table */
13681 static int alc861_auto_create_multi_out_ctls(struct alc_spec
*spec
,
13682 const struct auto_pin_cfg
*cfg
)
13685 static const char *chname
[4] = {
13686 "Front", "Surround", NULL
/*CLFE*/, "Side"
13691 for (i
= 0; i
< cfg
->line_outs
; i
++) {
13692 nid
= spec
->multiout
.dac_nids
[i
];
13697 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
13698 "Center Playback Switch",
13699 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
13703 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
13704 "LFE Playback Switch",
13705 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
13710 for (idx
= 0; idx
< ARRAY_SIZE(alc861_dac_nids
) - 1;
13712 if (nid
== alc861_dac_nids
[idx
])
13714 sprintf(name
, "%s Playback Switch", chname
[idx
]);
13715 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
13716 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
13725 static int alc861_auto_create_hp_ctls(struct alc_spec
*spec
, hda_nid_t pin
)
13733 if ((pin
>= 0x0b && pin
<= 0x10) || pin
== 0x1f || pin
== 0x20) {
13735 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
13736 "Headphone Playback Switch",
13737 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
13740 spec
->multiout
.hp_nid
= nid
;
13745 /* create playback/capture controls for input pins */
13746 static int alc861_auto_create_analog_input_ctls(struct alc_spec
*spec
,
13747 const struct auto_pin_cfg
*cfg
)
13749 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
13750 int i
, err
, idx
, idx1
;
13752 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
13753 switch (cfg
->input_pins
[i
]) {
13756 idx
= 2; /* Line In */
13760 idx
= 2; /* Line In */
13764 idx
= 1; /* Mic In */
13768 idx
= 1; /* Mic In */
13778 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
13779 auto_pin_cfg_labels
[i
], idx
, 0x15);
13783 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
13784 imux
->items
[imux
->num_items
].index
= idx1
;
13790 static void alc861_auto_set_output_and_unmute(struct hda_codec
*codec
,
13792 int pin_type
, int dac_idx
)
13794 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
13796 snd_hda_codec_write(codec
, dac_idx
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
13800 static void alc861_auto_init_multi_out(struct hda_codec
*codec
)
13802 struct alc_spec
*spec
= codec
->spec
;
13805 alc_subsystem_id(codec
, 0x0e, 0x0f, 0x0b);
13806 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
13807 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
13808 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
13810 alc861_auto_set_output_and_unmute(codec
, nid
, pin_type
,
13811 spec
->multiout
.dac_nids
[i
]);
13815 static void alc861_auto_init_hp_out(struct hda_codec
*codec
)
13817 struct alc_spec
*spec
= codec
->spec
;
13820 pin
= spec
->autocfg
.hp_pins
[0];
13821 if (pin
) /* connect to front */
13822 alc861_auto_set_output_and_unmute(codec
, pin
, PIN_HP
,
13823 spec
->multiout
.dac_nids
[0]);
13824 pin
= spec
->autocfg
.speaker_pins
[0];
13826 alc861_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
13829 static void alc861_auto_init_analog_input(struct hda_codec
*codec
)
13831 struct alc_spec
*spec
= codec
->spec
;
13834 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
13835 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
13836 if (nid
>= 0x0c && nid
<= 0x11) {
13837 snd_hda_codec_write(codec
, nid
, 0,
13838 AC_VERB_SET_PIN_WIDGET_CONTROL
,
13839 i
<= AUTO_PIN_FRONT_MIC
?
13840 PIN_VREF80
: PIN_IN
);
13845 /* parse the BIOS configuration and set up the alc_spec */
13846 /* return 1 if successful, 0 if the proper config is not found,
13847 * or a negative error code
13849 static int alc861_parse_auto_config(struct hda_codec
*codec
)
13851 struct alc_spec
*spec
= codec
->spec
;
13853 static hda_nid_t alc861_ignore
[] = { 0x1d, 0 };
13855 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
13859 if (!spec
->autocfg
.line_outs
)
13860 return 0; /* can't find valid BIOS pin config */
13862 err
= alc861_auto_fill_dac_nids(spec
, &spec
->autocfg
);
13865 err
= alc861_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
13868 err
= alc861_auto_create_hp_ctls(spec
, spec
->autocfg
.hp_pins
[0]);
13871 err
= alc861_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
13875 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
13877 if (spec
->autocfg
.dig_outs
)
13878 spec
->multiout
.dig_out_nid
= ALC861_DIGOUT_NID
;
13880 if (spec
->kctls
.list
)
13881 add_mixer(spec
, spec
->kctls
.list
);
13883 add_verb(spec
, alc861_auto_init_verbs
);
13885 spec
->num_mux_defs
= 1;
13886 spec
->input_mux
= &spec
->private_imux
[0];
13888 spec
->adc_nids
= alc861_adc_nids
;
13889 spec
->num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
);
13890 set_capture_mixer(spec
);
13895 /* additional initialization for auto-configuration model */
13896 static void alc861_auto_init(struct hda_codec
*codec
)
13898 struct alc_spec
*spec
= codec
->spec
;
13899 alc861_auto_init_multi_out(codec
);
13900 alc861_auto_init_hp_out(codec
);
13901 alc861_auto_init_analog_input(codec
);
13902 if (spec
->unsol_event
)
13903 alc_inithook(codec
);
13906 #ifdef CONFIG_SND_HDA_POWER_SAVE
13907 static struct hda_amp_list alc861_loopbacks
[] = {
13908 { 0x15, HDA_INPUT
, 0 },
13909 { 0x15, HDA_INPUT
, 1 },
13910 { 0x15, HDA_INPUT
, 2 },
13911 { 0x15, HDA_INPUT
, 3 },
13918 * configuration and preset
13920 static const char *alc861_models
[ALC861_MODEL_LAST
] = {
13921 [ALC861_3ST
] = "3stack",
13922 [ALC660_3ST
] = "3stack-660",
13923 [ALC861_3ST_DIG
] = "3stack-dig",
13924 [ALC861_6ST_DIG
] = "6stack-dig",
13925 [ALC861_UNIWILL_M31
] = "uniwill-m31",
13926 [ALC861_TOSHIBA
] = "toshiba",
13927 [ALC861_ASUS
] = "asus",
13928 [ALC861_ASUS_LAPTOP
] = "asus-laptop",
13929 [ALC861_AUTO
] = "auto",
13932 static struct snd_pci_quirk alc861_cfg_tbl
[] = {
13933 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST
),
13934 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP
),
13935 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP
),
13936 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS
),
13937 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP
),
13938 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG
),
13939 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA
),
13940 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13941 * Any other models that need this preset?
13943 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13944 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST
),
13945 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST
),
13946 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31
),
13947 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31
),
13948 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP
),
13949 /* FIXME: the below seems conflict */
13950 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13951 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST
),
13952 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST
),
13956 static struct alc_config_preset alc861_presets
[] = {
13958 .mixers
= { alc861_3ST_mixer
},
13959 .init_verbs
= { alc861_threestack_init_verbs
},
13960 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
13961 .dac_nids
= alc861_dac_nids
,
13962 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
13963 .channel_mode
= alc861_threestack_modes
,
13965 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
13966 .adc_nids
= alc861_adc_nids
,
13967 .input_mux
= &alc861_capture_source
,
13969 [ALC861_3ST_DIG
] = {
13970 .mixers
= { alc861_base_mixer
},
13971 .init_verbs
= { alc861_threestack_init_verbs
},
13972 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
13973 .dac_nids
= alc861_dac_nids
,
13974 .dig_out_nid
= ALC861_DIGOUT_NID
,
13975 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
13976 .channel_mode
= alc861_threestack_modes
,
13978 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
13979 .adc_nids
= alc861_adc_nids
,
13980 .input_mux
= &alc861_capture_source
,
13982 [ALC861_6ST_DIG
] = {
13983 .mixers
= { alc861_base_mixer
},
13984 .init_verbs
= { alc861_base_init_verbs
},
13985 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
13986 .dac_nids
= alc861_dac_nids
,
13987 .dig_out_nid
= ALC861_DIGOUT_NID
,
13988 .num_channel_mode
= ARRAY_SIZE(alc861_8ch_modes
),
13989 .channel_mode
= alc861_8ch_modes
,
13990 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
13991 .adc_nids
= alc861_adc_nids
,
13992 .input_mux
= &alc861_capture_source
,
13995 .mixers
= { alc861_3ST_mixer
},
13996 .init_verbs
= { alc861_threestack_init_verbs
},
13997 .num_dacs
= ARRAY_SIZE(alc660_dac_nids
),
13998 .dac_nids
= alc660_dac_nids
,
13999 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
14000 .channel_mode
= alc861_threestack_modes
,
14002 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
14003 .adc_nids
= alc861_adc_nids
,
14004 .input_mux
= &alc861_capture_source
,
14006 [ALC861_UNIWILL_M31
] = {
14007 .mixers
= { alc861_uniwill_m31_mixer
},
14008 .init_verbs
= { alc861_uniwill_m31_init_verbs
},
14009 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
14010 .dac_nids
= alc861_dac_nids
,
14011 .dig_out_nid
= ALC861_DIGOUT_NID
,
14012 .num_channel_mode
= ARRAY_SIZE(alc861_uniwill_m31_modes
),
14013 .channel_mode
= alc861_uniwill_m31_modes
,
14015 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
14016 .adc_nids
= alc861_adc_nids
,
14017 .input_mux
= &alc861_capture_source
,
14019 [ALC861_TOSHIBA
] = {
14020 .mixers
= { alc861_toshiba_mixer
},
14021 .init_verbs
= { alc861_base_init_verbs
,
14022 alc861_toshiba_init_verbs
},
14023 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
14024 .dac_nids
= alc861_dac_nids
,
14025 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
14026 .channel_mode
= alc883_3ST_2ch_modes
,
14027 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
14028 .adc_nids
= alc861_adc_nids
,
14029 .input_mux
= &alc861_capture_source
,
14030 .unsol_event
= alc861_toshiba_unsol_event
,
14031 .init_hook
= alc861_toshiba_automute
,
14034 .mixers
= { alc861_asus_mixer
},
14035 .init_verbs
= { alc861_asus_init_verbs
},
14036 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
14037 .dac_nids
= alc861_dac_nids
,
14038 .dig_out_nid
= ALC861_DIGOUT_NID
,
14039 .num_channel_mode
= ARRAY_SIZE(alc861_asus_modes
),
14040 .channel_mode
= alc861_asus_modes
,
14043 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
14044 .adc_nids
= alc861_adc_nids
,
14045 .input_mux
= &alc861_capture_source
,
14047 [ALC861_ASUS_LAPTOP
] = {
14048 .mixers
= { alc861_toshiba_mixer
, alc861_asus_laptop_mixer
},
14049 .init_verbs
= { alc861_asus_init_verbs
,
14050 alc861_asus_laptop_init_verbs
},
14051 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
14052 .dac_nids
= alc861_dac_nids
,
14053 .dig_out_nid
= ALC861_DIGOUT_NID
,
14054 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
14055 .channel_mode
= alc883_3ST_2ch_modes
,
14057 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
14058 .adc_nids
= alc861_adc_nids
,
14059 .input_mux
= &alc861_capture_source
,
14064 static int patch_alc861(struct hda_codec
*codec
)
14066 struct alc_spec
*spec
;
14070 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
14074 codec
->spec
= spec
;
14076 board_config
= snd_hda_check_board_config(codec
, ALC861_MODEL_LAST
,
14080 if (board_config
< 0) {
14081 printk(KERN_INFO
"hda_codec: Unknown model for ALC861, "
14082 "trying auto-probe from BIOS...\n");
14083 board_config
= ALC861_AUTO
;
14086 if (board_config
== ALC861_AUTO
) {
14087 /* automatic parse from the BIOS config */
14088 err
= alc861_parse_auto_config(codec
);
14094 "hda_codec: Cannot set up configuration "
14095 "from BIOS. Using base mode...\n");
14096 board_config
= ALC861_3ST_DIG
;
14100 err
= snd_hda_attach_beep_device(codec
, 0x23);
14106 if (board_config
!= ALC861_AUTO
)
14107 setup_preset(spec
, &alc861_presets
[board_config
]);
14109 spec
->stream_name_analog
= "ALC861 Analog";
14110 spec
->stream_analog_playback
= &alc861_pcm_analog_playback
;
14111 spec
->stream_analog_capture
= &alc861_pcm_analog_capture
;
14113 spec
->stream_name_digital
= "ALC861 Digital";
14114 spec
->stream_digital_playback
= &alc861_pcm_digital_playback
;
14115 spec
->stream_digital_capture
= &alc861_pcm_digital_capture
;
14117 set_beep_amp(spec
, 0x23, 0, HDA_OUTPUT
);
14119 spec
->vmaster_nid
= 0x03;
14121 codec
->patch_ops
= alc_patch_ops
;
14122 if (board_config
== ALC861_AUTO
)
14123 spec
->init_hook
= alc861_auto_init
;
14124 #ifdef CONFIG_SND_HDA_POWER_SAVE
14125 if (!spec
->loopback
.amplist
)
14126 spec
->loopback
.amplist
= alc861_loopbacks
;
14128 codec
->proc_widget_hook
= print_realtek_coef
;
14134 * ALC861-VD support
14138 * In addition, an independent DAC
14140 #define ALC861VD_DIGOUT_NID 0x06
14142 static hda_nid_t alc861vd_dac_nids
[4] = {
14143 /* front, surr, clfe, side surr */
14144 0x02, 0x03, 0x04, 0x05
14147 /* dac_nids for ALC660vd are in a different order - according to
14148 * Realtek's driver.
14149 * This should probably tesult in a different mixer for 6stack models
14150 * of ALC660vd codecs, but for now there is only 3stack mixer
14151 * - and it is the same as in 861vd.
14152 * adc_nids in ALC660vd are (is) the same as in 861vd
14154 static hda_nid_t alc660vd_dac_nids
[3] = {
14155 /* front, rear, clfe, rear_surr */
14159 static hda_nid_t alc861vd_adc_nids
[1] = {
14164 static hda_nid_t alc861vd_capsrc_nids
[1] = { 0x22 };
14167 /* FIXME: should be a matrix-type input source selection */
14168 static struct hda_input_mux alc861vd_capture_source
= {
14172 { "Front Mic", 0x1 },
14178 static struct hda_input_mux alc861vd_dallas_capture_source
= {
14181 { "Ext Mic", 0x0 },
14182 { "Int Mic", 0x1 },
14186 static struct hda_input_mux alc861vd_hp_capture_source
= {
14189 { "Front Mic", 0x0 },
14190 { "ATAPI Mic", 0x1 },
14197 static struct hda_channel_mode alc861vd_3stack_2ch_modes
[1] = {
14204 static struct hda_verb alc861vd_6stack_ch6_init
[] = {
14205 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
14206 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14207 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14208 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14215 static struct hda_verb alc861vd_6stack_ch8_init
[] = {
14216 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14217 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14218 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14219 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14223 static struct hda_channel_mode alc861vd_6stack_modes
[2] = {
14224 { 6, alc861vd_6stack_ch6_init
},
14225 { 8, alc861vd_6stack_ch8_init
},
14228 static struct snd_kcontrol_new alc861vd_chmode_mixer
[] = {
14230 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
14231 .name
= "Channel Mode",
14232 .info
= alc_ch_mode_info
,
14233 .get
= alc_ch_mode_get
,
14234 .put
= alc_ch_mode_put
,
14239 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14240 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14242 static struct snd_kcontrol_new alc861vd_6st_mixer
[] = {
14243 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
14244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
14246 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
14247 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
14249 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14251 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14253 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
14254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
14256 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT
),
14257 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
14259 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
14261 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
14262 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
14263 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
14265 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
14266 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
14267 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
14269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
14270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
14272 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
14273 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
14278 static struct snd_kcontrol_new alc861vd_3st_mixer
[] = {
14279 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
14280 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
14282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
14284 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
14285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
14286 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
14288 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
14289 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
14290 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
14292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
14293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
14295 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
14296 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
14301 static struct snd_kcontrol_new alc861vd_lenovo_mixer
[] = {
14302 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
14303 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14304 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
14306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
14308 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
14309 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
14310 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
14312 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
14313 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
14314 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
14316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
14317 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
14322 /* Pin assignment: Speaker=0x14, HP = 0x15,
14323 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14325 static struct snd_kcontrol_new alc861vd_dallas_mixer
[] = {
14326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
14327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT
),
14328 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
14329 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT
),
14330 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT
),
14331 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
14332 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
14333 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT
),
14334 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
14335 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
14339 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14340 * Front Mic=0x18, ATAPI Mic = 0x19,
14342 static struct snd_kcontrol_new alc861vd_hp_mixer
[] = {
14343 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
14344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
14345 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
14346 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT
),
14347 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
14348 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
14349 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
14350 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
14356 * generic initialization of ADC, input mixers and output mixers
14358 static struct hda_verb alc861vd_volume_init_verbs
[] = {
14360 * Unmute ADC0 and set the default input to mic-in
14362 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
14363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
14365 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14366 * the analog-loopback mixer widget
14368 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
14372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
14373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
14375 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
14377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
14378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
14379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
14382 * Set up output mixers (0x02 - 0x05)
14384 /* set vol=0 to output mixers */
14385 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14386 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14387 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14388 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14390 /* set up input amps for analog loopback */
14391 /* Amp Indices: DAC = 0, mixer = 1 */
14392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14405 * 3-stack pin configuration:
14406 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14408 static struct hda_verb alc861vd_3stack_init_verbs
[] = {
14410 * Set pin mode and muting
14412 /* set front pin widgets 0x14 for output */
14413 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14414 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14415 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
14417 /* Mic (rear) pin: input vref at 80% */
14418 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
14419 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14420 /* Front Mic pin: input vref at 80% */
14421 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
14422 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14423 /* Line In pin: input */
14424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14426 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
14428 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14429 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
14430 /* CD pin widget for input */
14431 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14437 * 6-stack pin configuration:
14439 static struct hda_verb alc861vd_6stack_init_verbs
[] = {
14441 * Set pin mode and muting
14443 /* set front pin widgets 0x14 for output */
14444 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14446 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
14448 /* Rear Pin: output 1 (0x0d) */
14449 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14451 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
14452 /* CLFE Pin: output 2 (0x0e) */
14453 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14454 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14455 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
14456 /* Side Pin: output 3 (0x0f) */
14457 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14459 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
14461 /* Mic (rear) pin: input vref at 80% */
14462 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
14463 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14464 /* Front Mic pin: input vref at 80% */
14465 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
14466 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14467 /* Line In pin: input */
14468 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14469 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14470 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14471 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
14472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14473 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
14474 /* CD pin widget for input */
14475 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14480 static struct hda_verb alc861vd_eapd_verbs
[] = {
14481 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
14485 static struct hda_verb alc660vd_eapd_verbs
[] = {
14486 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
14487 {0x15, AC_VERB_SET_EAPD_BTLENABLE
, 2},
14491 static struct hda_verb alc861vd_lenovo_unsol_verbs
[] = {
14492 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
14493 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
14494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)},
14495 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
14496 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
14500 /* toggle speaker-output according to the hp-jack state */
14501 static void alc861vd_lenovo_hp_automute(struct hda_codec
*codec
)
14503 unsigned int present
;
14504 unsigned char bits
;
14506 present
= snd_hda_codec_read(codec
, 0x1b, 0,
14507 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
14508 bits
= present
? HDA_AMP_MUTE
: 0;
14509 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
14510 HDA_AMP_MUTE
, bits
);
14513 static void alc861vd_lenovo_mic_automute(struct hda_codec
*codec
)
14515 unsigned int present
;
14516 unsigned char bits
;
14518 present
= snd_hda_codec_read(codec
, 0x18, 0,
14519 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
14520 bits
= present
? HDA_AMP_MUTE
: 0;
14521 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, 1,
14522 HDA_AMP_MUTE
, bits
);
14525 static void alc861vd_lenovo_automute(struct hda_codec
*codec
)
14527 alc861vd_lenovo_hp_automute(codec
);
14528 alc861vd_lenovo_mic_automute(codec
);
14531 static void alc861vd_lenovo_unsol_event(struct hda_codec
*codec
,
14534 switch (res
>> 26) {
14535 case ALC880_HP_EVENT
:
14536 alc861vd_lenovo_hp_automute(codec
);
14538 case ALC880_MIC_EVENT
:
14539 alc861vd_lenovo_mic_automute(codec
);
14544 static struct hda_verb alc861vd_dallas_verbs
[] = {
14545 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14546 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14547 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14548 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
14550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
14551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
14552 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14553 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14554 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14555 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14557 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
14559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14562 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14563 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14564 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14565 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
14566 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
14568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
14569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14570 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
14571 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
14572 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14573 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14574 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14575 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
14577 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
14578 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
14579 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
14580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
14582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
14583 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
14584 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
14589 /* toggle speaker-output according to the hp-jack state */
14590 static void alc861vd_dallas_automute(struct hda_codec
*codec
)
14592 unsigned int present
;
14594 present
= snd_hda_codec_read(codec
, 0x15, 0,
14595 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
14596 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
14597 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
14600 static void alc861vd_dallas_unsol_event(struct hda_codec
*codec
, unsigned int res
)
14602 if ((res
>> 26) == ALC880_HP_EVENT
)
14603 alc861vd_dallas_automute(codec
);
14606 #ifdef CONFIG_SND_HDA_POWER_SAVE
14607 #define alc861vd_loopbacks alc880_loopbacks
14610 /* pcm configuration: identiacal with ALC880 */
14611 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14612 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14613 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14614 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14617 * configuration and preset
14619 static const char *alc861vd_models
[ALC861VD_MODEL_LAST
] = {
14620 [ALC660VD_3ST
] = "3stack-660",
14621 [ALC660VD_3ST_DIG
] = "3stack-660-digout",
14622 [ALC660VD_ASUS_V1S
] = "asus-v1s",
14623 [ALC861VD_3ST
] = "3stack",
14624 [ALC861VD_3ST_DIG
] = "3stack-digout",
14625 [ALC861VD_6ST_DIG
] = "6stack-digout",
14626 [ALC861VD_LENOVO
] = "lenovo",
14627 [ALC861VD_DALLAS
] = "dallas",
14628 [ALC861VD_HP
] = "hp",
14629 [ALC861VD_AUTO
] = "auto",
14632 static struct snd_pci_quirk alc861vd_cfg_tbl
[] = {
14633 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST
),
14634 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP
),
14635 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST
),
14636 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST
),
14637 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S
),
14638 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG
),
14639 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST
),
14640 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO
),
14641 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14642 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS
),
14643 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO
),
14644 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS
),
14645 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG
),
14646 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO
),
14647 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG
),
14651 static struct alc_config_preset alc861vd_presets
[] = {
14653 .mixers
= { alc861vd_3st_mixer
},
14654 .init_verbs
= { alc861vd_volume_init_verbs
,
14655 alc861vd_3stack_init_verbs
},
14656 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
14657 .dac_nids
= alc660vd_dac_nids
,
14658 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14659 .channel_mode
= alc861vd_3stack_2ch_modes
,
14660 .input_mux
= &alc861vd_capture_source
,
14662 [ALC660VD_3ST_DIG
] = {
14663 .mixers
= { alc861vd_3st_mixer
},
14664 .init_verbs
= { alc861vd_volume_init_verbs
,
14665 alc861vd_3stack_init_verbs
},
14666 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
14667 .dac_nids
= alc660vd_dac_nids
,
14668 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
14669 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14670 .channel_mode
= alc861vd_3stack_2ch_modes
,
14671 .input_mux
= &alc861vd_capture_source
,
14674 .mixers
= { alc861vd_3st_mixer
},
14675 .init_verbs
= { alc861vd_volume_init_verbs
,
14676 alc861vd_3stack_init_verbs
},
14677 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
14678 .dac_nids
= alc861vd_dac_nids
,
14679 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14680 .channel_mode
= alc861vd_3stack_2ch_modes
,
14681 .input_mux
= &alc861vd_capture_source
,
14683 [ALC861VD_3ST_DIG
] = {
14684 .mixers
= { alc861vd_3st_mixer
},
14685 .init_verbs
= { alc861vd_volume_init_verbs
,
14686 alc861vd_3stack_init_verbs
},
14687 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
14688 .dac_nids
= alc861vd_dac_nids
,
14689 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
14690 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14691 .channel_mode
= alc861vd_3stack_2ch_modes
,
14692 .input_mux
= &alc861vd_capture_source
,
14694 [ALC861VD_6ST_DIG
] = {
14695 .mixers
= { alc861vd_6st_mixer
, alc861vd_chmode_mixer
},
14696 .init_verbs
= { alc861vd_volume_init_verbs
,
14697 alc861vd_6stack_init_verbs
},
14698 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
14699 .dac_nids
= alc861vd_dac_nids
,
14700 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
14701 .num_channel_mode
= ARRAY_SIZE(alc861vd_6stack_modes
),
14702 .channel_mode
= alc861vd_6stack_modes
,
14703 .input_mux
= &alc861vd_capture_source
,
14705 [ALC861VD_LENOVO
] = {
14706 .mixers
= { alc861vd_lenovo_mixer
},
14707 .init_verbs
= { alc861vd_volume_init_verbs
,
14708 alc861vd_3stack_init_verbs
,
14709 alc861vd_eapd_verbs
,
14710 alc861vd_lenovo_unsol_verbs
},
14711 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
14712 .dac_nids
= alc660vd_dac_nids
,
14713 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14714 .channel_mode
= alc861vd_3stack_2ch_modes
,
14715 .input_mux
= &alc861vd_capture_source
,
14716 .unsol_event
= alc861vd_lenovo_unsol_event
,
14717 .init_hook
= alc861vd_lenovo_automute
,
14719 [ALC861VD_DALLAS
] = {
14720 .mixers
= { alc861vd_dallas_mixer
},
14721 .init_verbs
= { alc861vd_dallas_verbs
},
14722 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
14723 .dac_nids
= alc861vd_dac_nids
,
14724 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14725 .channel_mode
= alc861vd_3stack_2ch_modes
,
14726 .input_mux
= &alc861vd_dallas_capture_source
,
14727 .unsol_event
= alc861vd_dallas_unsol_event
,
14728 .init_hook
= alc861vd_dallas_automute
,
14731 .mixers
= { alc861vd_hp_mixer
},
14732 .init_verbs
= { alc861vd_dallas_verbs
, alc861vd_eapd_verbs
},
14733 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
14734 .dac_nids
= alc861vd_dac_nids
,
14735 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
14736 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14737 .channel_mode
= alc861vd_3stack_2ch_modes
,
14738 .input_mux
= &alc861vd_hp_capture_source
,
14739 .unsol_event
= alc861vd_dallas_unsol_event
,
14740 .init_hook
= alc861vd_dallas_automute
,
14742 [ALC660VD_ASUS_V1S
] = {
14743 .mixers
= { alc861vd_lenovo_mixer
},
14744 .init_verbs
= { alc861vd_volume_init_verbs
,
14745 alc861vd_3stack_init_verbs
,
14746 alc861vd_eapd_verbs
,
14747 alc861vd_lenovo_unsol_verbs
},
14748 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
14749 .dac_nids
= alc660vd_dac_nids
,
14750 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
14751 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
14752 .channel_mode
= alc861vd_3stack_2ch_modes
,
14753 .input_mux
= &alc861vd_capture_source
,
14754 .unsol_event
= alc861vd_lenovo_unsol_event
,
14755 .init_hook
= alc861vd_lenovo_automute
,
14760 * BIOS auto configuration
14762 static void alc861vd_auto_set_output_and_unmute(struct hda_codec
*codec
,
14763 hda_nid_t nid
, int pin_type
, int dac_idx
)
14765 alc_set_pin_output(codec
, nid
, pin_type
);
14768 static void alc861vd_auto_init_multi_out(struct hda_codec
*codec
)
14770 struct alc_spec
*spec
= codec
->spec
;
14773 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
14774 for (i
= 0; i
<= HDA_SIDE
; i
++) {
14775 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
14776 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
14778 alc861vd_auto_set_output_and_unmute(codec
, nid
,
14784 static void alc861vd_auto_init_hp_out(struct hda_codec
*codec
)
14786 struct alc_spec
*spec
= codec
->spec
;
14789 pin
= spec
->autocfg
.hp_pins
[0];
14790 if (pin
) /* connect to front and use dac 0 */
14791 alc861vd_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
14792 pin
= spec
->autocfg
.speaker_pins
[0];
14794 alc861vd_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
14797 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14798 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14800 static void alc861vd_auto_init_analog_input(struct hda_codec
*codec
)
14802 struct alc_spec
*spec
= codec
->spec
;
14805 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
14806 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
14807 if (alc861vd_is_input_pin(nid
)) {
14808 snd_hda_codec_write(codec
, nid
, 0,
14809 AC_VERB_SET_PIN_WIDGET_CONTROL
,
14810 i
<= AUTO_PIN_FRONT_MIC
?
14811 PIN_VREF80
: PIN_IN
);
14812 if (nid
!= ALC861VD_PIN_CD_NID
)
14813 snd_hda_codec_write(codec
, nid
, 0,
14814 AC_VERB_SET_AMP_GAIN_MUTE
,
14820 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14822 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14823 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14825 /* add playback controls from the parsed DAC table */
14826 /* Based on ALC880 version. But ALC861VD has separate,
14827 * different NIDs for mute/unmute switch and volume control */
14828 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec
*spec
,
14829 const struct auto_pin_cfg
*cfg
)
14832 static const char *chname
[4] = {"Front", "Surround", "CLFE", "Side"};
14833 hda_nid_t nid_v
, nid_s
;
14836 for (i
= 0; i
< cfg
->line_outs
; i
++) {
14837 if (!spec
->multiout
.dac_nids
[i
])
14839 nid_v
= alc861vd_idx_to_mixer_vol(
14841 spec
->multiout
.dac_nids
[i
]));
14842 nid_s
= alc861vd_idx_to_mixer_switch(
14844 spec
->multiout
.dac_nids
[i
]));
14848 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
14849 "Center Playback Volume",
14850 HDA_COMPOSE_AMP_VAL(nid_v
, 1, 0,
14854 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
14855 "LFE Playback Volume",
14856 HDA_COMPOSE_AMP_VAL(nid_v
, 2, 0,
14860 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
14861 "Center Playback Switch",
14862 HDA_COMPOSE_AMP_VAL(nid_s
, 1, 2,
14866 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
14867 "LFE Playback Switch",
14868 HDA_COMPOSE_AMP_VAL(nid_s
, 2, 2,
14873 sprintf(name
, "%s Playback Volume", chname
[i
]);
14874 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
14875 HDA_COMPOSE_AMP_VAL(nid_v
, 3, 0,
14879 sprintf(name
, "%s Playback Switch", chname
[i
]);
14880 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
14881 HDA_COMPOSE_AMP_VAL(nid_s
, 3, 2,
14890 /* add playback controls for speaker and HP outputs */
14891 /* Based on ALC880 version. But ALC861VD has separate,
14892 * different NIDs for mute/unmute switch and volume control */
14893 static int alc861vd_auto_create_extra_out(struct alc_spec
*spec
,
14894 hda_nid_t pin
, const char *pfx
)
14896 hda_nid_t nid_v
, nid_s
;
14903 if (alc880_is_fixed_pin(pin
)) {
14904 nid_v
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
14905 /* specify the DAC as the extra output */
14906 if (!spec
->multiout
.hp_nid
)
14907 spec
->multiout
.hp_nid
= nid_v
;
14909 spec
->multiout
.extra_out_nid
[0] = nid_v
;
14910 /* control HP volume/switch on the output mixer amp */
14911 nid_v
= alc861vd_idx_to_mixer_vol(
14912 alc880_fixed_pin_idx(pin
));
14913 nid_s
= alc861vd_idx_to_mixer_switch(
14914 alc880_fixed_pin_idx(pin
));
14916 sprintf(name
, "%s Playback Volume", pfx
);
14917 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
14918 HDA_COMPOSE_AMP_VAL(nid_v
, 3, 0, HDA_OUTPUT
));
14921 sprintf(name
, "%s Playback Switch", pfx
);
14922 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
14923 HDA_COMPOSE_AMP_VAL(nid_s
, 3, 2, HDA_INPUT
));
14926 } else if (alc880_is_multi_pin(pin
)) {
14927 /* set manual connection */
14928 /* we have only a switch on HP-out PIN */
14929 sprintf(name
, "%s Playback Switch", pfx
);
14930 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
14931 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
14938 /* parse the BIOS configuration and set up the alc_spec
14939 * return 1 if successful, 0 if the proper config is not found,
14940 * or a negative error code
14941 * Based on ALC880 version - had to change it to override
14942 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14943 static int alc861vd_parse_auto_config(struct hda_codec
*codec
)
14945 struct alc_spec
*spec
= codec
->spec
;
14947 static hda_nid_t alc861vd_ignore
[] = { 0x1d, 0 };
14949 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
14953 if (!spec
->autocfg
.line_outs
)
14954 return 0; /* can't find valid BIOS pin config */
14956 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
14959 err
= alc861vd_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
14962 err
= alc861vd_auto_create_extra_out(spec
,
14963 spec
->autocfg
.speaker_pins
[0],
14967 err
= alc861vd_auto_create_extra_out(spec
,
14968 spec
->autocfg
.hp_pins
[0],
14972 err
= alc880_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
14976 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
14978 if (spec
->autocfg
.dig_outs
)
14979 spec
->multiout
.dig_out_nid
= ALC861VD_DIGOUT_NID
;
14981 if (spec
->kctls
.list
)
14982 add_mixer(spec
, spec
->kctls
.list
);
14984 add_verb(spec
, alc861vd_volume_init_verbs
);
14986 spec
->num_mux_defs
= 1;
14987 spec
->input_mux
= &spec
->private_imux
[0];
14989 err
= alc_auto_add_mic_boost(codec
);
14996 /* additional initialization for auto-configuration model */
14997 static void alc861vd_auto_init(struct hda_codec
*codec
)
14999 struct alc_spec
*spec
= codec
->spec
;
15000 alc861vd_auto_init_multi_out(codec
);
15001 alc861vd_auto_init_hp_out(codec
);
15002 alc861vd_auto_init_analog_input(codec
);
15003 alc861vd_auto_init_input_src(codec
);
15004 if (spec
->unsol_event
)
15005 alc_inithook(codec
);
15008 static int patch_alc861vd(struct hda_codec
*codec
)
15010 struct alc_spec
*spec
;
15011 int err
, board_config
;
15013 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
15017 codec
->spec
= spec
;
15019 board_config
= snd_hda_check_board_config(codec
, ALC861VD_MODEL_LAST
,
15023 if (board_config
< 0 || board_config
>= ALC861VD_MODEL_LAST
) {
15024 printk(KERN_INFO
"hda_codec: Unknown model for ALC660VD/"
15025 "ALC861VD, trying auto-probe from BIOS...\n");
15026 board_config
= ALC861VD_AUTO
;
15029 if (board_config
== ALC861VD_AUTO
) {
15030 /* automatic parse from the BIOS config */
15031 err
= alc861vd_parse_auto_config(codec
);
15037 "hda_codec: Cannot set up configuration "
15038 "from BIOS. Using base mode...\n");
15039 board_config
= ALC861VD_3ST
;
15043 err
= snd_hda_attach_beep_device(codec
, 0x23);
15049 if (board_config
!= ALC861VD_AUTO
)
15050 setup_preset(spec
, &alc861vd_presets
[board_config
]);
15052 if (codec
->vendor_id
== 0x10ec0660) {
15053 spec
->stream_name_analog
= "ALC660-VD Analog";
15054 spec
->stream_name_digital
= "ALC660-VD Digital";
15055 /* always turn on EAPD */
15056 add_verb(spec
, alc660vd_eapd_verbs
);
15058 spec
->stream_name_analog
= "ALC861VD Analog";
15059 spec
->stream_name_digital
= "ALC861VD Digital";
15062 spec
->stream_analog_playback
= &alc861vd_pcm_analog_playback
;
15063 spec
->stream_analog_capture
= &alc861vd_pcm_analog_capture
;
15065 spec
->stream_digital_playback
= &alc861vd_pcm_digital_playback
;
15066 spec
->stream_digital_capture
= &alc861vd_pcm_digital_capture
;
15068 spec
->adc_nids
= alc861vd_adc_nids
;
15069 spec
->num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
);
15070 spec
->capsrc_nids
= alc861vd_capsrc_nids
;
15071 spec
->capture_style
= CAPT_MIX
;
15073 set_capture_mixer(spec
);
15074 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
15076 spec
->vmaster_nid
= 0x02;
15078 codec
->patch_ops
= alc_patch_ops
;
15080 if (board_config
== ALC861VD_AUTO
)
15081 spec
->init_hook
= alc861vd_auto_init
;
15082 #ifdef CONFIG_SND_HDA_POWER_SAVE
15083 if (!spec
->loopback
.amplist
)
15084 spec
->loopback
.amplist
= alc861vd_loopbacks
;
15086 codec
->proc_widget_hook
= print_realtek_coef
;
15094 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15095 * configuration. Each pin widget can choose any input DACs and a mixer.
15096 * Each ADC is connected from a mixer of all inputs. This makes possible
15097 * 6-channel independent captures.
15099 * In addition, an independent DAC for the multi-playback (not used in this
15102 #define ALC662_DIGOUT_NID 0x06
15103 #define ALC662_DIGIN_NID 0x0a
15105 static hda_nid_t alc662_dac_nids
[4] = {
15106 /* front, rear, clfe, rear_surr */
15110 static hda_nid_t alc662_adc_nids
[1] = {
15115 static hda_nid_t alc662_capsrc_nids
[1] = { 0x22 };
15118 /* FIXME: should be a matrix-type input source selection */
15119 static struct hda_input_mux alc662_capture_source
= {
15123 { "Front Mic", 0x1 },
15129 static struct hda_input_mux alc662_lenovo_101e_capture_source
= {
15137 static struct hda_input_mux alc662_eeepc_capture_source
= {
15145 static struct hda_input_mux alc663_capture_source
= {
15149 { "Front Mic", 0x1 },
15154 static struct hda_input_mux alc663_m51va_capture_source
= {
15157 { "Ext-Mic", 0x0 },
15165 static struct hda_channel_mode alc662_3ST_2ch_modes
[1] = {
15172 static struct hda_verb alc662_3ST_ch2_init
[] = {
15173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
15174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
15175 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15176 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
15183 static struct hda_verb alc662_3ST_ch6_init
[] = {
15184 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15185 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15186 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
15187 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15188 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15189 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
15193 static struct hda_channel_mode alc662_3ST_6ch_modes
[2] = {
15194 { 2, alc662_3ST_ch2_init
},
15195 { 6, alc662_3ST_ch6_init
},
15201 static struct hda_verb alc662_sixstack_ch6_init
[] = {
15202 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
15203 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
15204 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15211 static struct hda_verb alc662_sixstack_ch8_init
[] = {
15212 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15213 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15214 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15218 static struct hda_channel_mode alc662_5stack_modes
[2] = {
15219 { 2, alc662_sixstack_ch6_init
},
15220 { 6, alc662_sixstack_ch8_init
},
15223 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15224 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15227 static struct snd_kcontrol_new alc662_base_mixer
[] = {
15228 /* output mixer control */
15229 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT
),
15230 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT
),
15231 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT
),
15232 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT
),
15233 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT
),
15234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT
),
15235 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT
),
15236 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT
),
15237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15239 /*Input mixer control */
15240 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT
),
15241 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT
),
15242 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT
),
15243 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT
),
15244 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT
),
15245 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT
),
15246 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT
),
15247 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT
),
15251 static struct snd_kcontrol_new alc662_3ST_2ch_mixer
[] = {
15252 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15253 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT
),
15254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
15256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
15257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
15258 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
15259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15261 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15266 static struct snd_kcontrol_new alc662_3ST_6ch_mixer
[] = {
15267 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15268 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT
),
15269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15270 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT
),
15271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT
),
15272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT
),
15273 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT
),
15274 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT
),
15275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
15277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
15278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
15279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
15280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15281 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15282 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15283 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15287 static struct snd_kcontrol_new alc662_lenovo_101e_mixer
[] = {
15288 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15289 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT
),
15290 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15291 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT
),
15292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
15294 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
15295 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15300 static struct snd_kcontrol_new alc662_eeepc_p701_mixer
[] = {
15301 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
15303 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15304 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15306 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT
),
15307 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15308 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15310 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT
),
15311 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15312 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15316 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer
[] = {
15317 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15318 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
15319 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15320 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT
),
15321 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT
),
15322 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT
),
15323 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT
),
15324 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT
),
15325 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15326 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT
),
15327 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
15328 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
15329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15334 static struct hda_bind_ctls alc663_asus_bind_master_vol
= {
15335 .ops
= &snd_hda_bind_vol
,
15337 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
15338 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT
),
15343 static struct hda_bind_ctls alc663_asus_one_bind_switch
= {
15344 .ops
= &snd_hda_bind_sw
,
15346 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
15347 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT
),
15352 static struct snd_kcontrol_new alc663_m51va_mixer
[] = {
15353 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol
),
15354 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch
),
15355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15356 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15360 static struct hda_bind_ctls alc663_asus_tree_bind_switch
= {
15361 .ops
= &snd_hda_bind_sw
,
15363 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
15364 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
15365 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT
),
15370 static struct snd_kcontrol_new alc663_two_hp_m1_mixer
[] = {
15371 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol
),
15372 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch
),
15373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15375 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15376 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15381 static struct hda_bind_ctls alc663_asus_four_bind_switch
= {
15382 .ops
= &snd_hda_bind_sw
,
15384 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
15385 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
15386 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT
),
15391 static struct snd_kcontrol_new alc663_two_hp_m2_mixer
[] = {
15392 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol
),
15393 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch
),
15394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15395 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15396 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15397 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15401 static struct snd_kcontrol_new alc662_1bjd_mixer
[] = {
15402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15403 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
15404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
15405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15407 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15408 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15412 static struct hda_bind_ctls alc663_asus_two_bind_master_vol
= {
15413 .ops
= &snd_hda_bind_vol
,
15415 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT
),
15416 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT
),
15421 static struct hda_bind_ctls alc663_asus_two_bind_switch
= {
15422 .ops
= &snd_hda_bind_sw
,
15424 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
15425 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT
),
15430 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer
[] = {
15431 HDA_BIND_VOL("Master Playback Volume",
15432 &alc663_asus_two_bind_master_vol
),
15433 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch
),
15434 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15435 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT
),
15436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15441 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer
[] = {
15442 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol
),
15443 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch
),
15444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
15446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15451 static struct snd_kcontrol_new alc663_g71v_mixer
[] = {
15452 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15453 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
15454 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
15455 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
15456 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT
),
15458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15460 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15461 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15465 static struct snd_kcontrol_new alc663_g50v_mixer
[] = {
15466 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
15467 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
15468 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT
),
15470 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
15471 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
15472 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
15473 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
15474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
15475 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
15479 static struct snd_kcontrol_new alc662_chmode_mixer
[] = {
15481 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
15482 .name
= "Channel Mode",
15483 .info
= alc_ch_mode_info
,
15484 .get
= alc_ch_mode_get
,
15485 .put
= alc_ch_mode_put
,
15490 static struct hda_verb alc662_init_verbs
[] = {
15491 /* ADC: mute amp left and right */
15492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15493 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
15494 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
15498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
15499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
15500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
15502 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15503 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15504 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15505 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15509 /* Front Pin: output 0 (0x0c) */
15510 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15511 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15513 /* Rear Pin: output 1 (0x0d) */
15514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15517 /* CLFE Pin: output 2 (0x0e) */
15518 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15521 /* Mic (rear) pin: input vref at 80% */
15522 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
15523 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
15524 /* Front Mic pin: input vref at 80% */
15525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
15526 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
15527 /* Line In pin: input */
15528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
15530 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15532 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15533 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
15534 /* CD pin widget for input */
15535 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15537 /* FIXME: use matrix-type input source selection */
15538 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
15543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
15545 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15547 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
15548 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
15550 /* always trun on EAPD */
15551 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
15552 {0x15, AC_VERB_SET_EAPD_BTLENABLE
, 2},
15557 static struct hda_verb alc662_sue_init_verbs
[] = {
15558 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_FRONT_EVENT
},
15559 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_HP_EVENT
},
15563 static struct hda_verb alc662_eeepc_sue_init_verbs
[] = {
15564 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15565 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15569 /* Set Unsolicited Event*/
15570 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs
[] = {
15571 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
15572 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15577 * generic initialization of ADC, input mixers and output mixers
15579 static struct hda_verb alc662_auto_init_verbs
[] = {
15581 * Unmute ADC and set the default input to mic-in
15583 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
15584 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15586 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15588 * Note: PASD motherboards uses the Line In 2 as the input for front
15589 * panel mic (mic 2)
15591 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15592 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15593 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
15594 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
15595 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
15596 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
15599 * Set up output mixers (0x0c - 0x0f)
15601 /* set vol=0 to output mixers */
15602 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
15603 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
15604 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
15606 /* set up input amps for analog loopback */
15607 /* Amp Indices: DAC = 0, mixer = 1 */
15608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15611 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15612 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15613 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15616 /* FIXME: use matrix-type input source selection */
15617 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15620 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15624 /* additional verbs for ALC663 */
15625 static struct hda_verb alc663_auto_init_verbs
[] = {
15626 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
15627 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15631 static struct hda_verb alc663_m51va_init_verbs
[] = {
15632 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15633 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15634 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15635 {0x21, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15636 {0x21, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Headphone */
15637 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15638 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(9)},
15639 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15640 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15644 static struct hda_verb alc663_21jd_amic_init_verbs
[] = {
15645 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15646 {0x21, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15647 {0x21, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Headphone */
15648 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15649 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15650 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15651 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15655 static struct hda_verb alc662_1bjd_amic_init_verbs
[] = {
15656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15657 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15658 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15659 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Headphone */
15660 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15661 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15662 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15663 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15667 static struct hda_verb alc663_15jd_amic_init_verbs
[] = {
15668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15669 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15670 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Headphone */
15671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15673 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15674 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15678 static struct hda_verb alc663_two_hp_amic_m1_init_verbs
[] = {
15679 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15680 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15681 {0x21, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15682 {0x21, AC_VERB_SET_CONNECT_SEL
, 0x0}, /* Headphone */
15683 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15685 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x0}, /* Headphone */
15686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15688 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15689 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15690 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15694 static struct hda_verb alc663_two_hp_amic_m2_init_verbs
[] = {
15695 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
15696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15697 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15698 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Headphone */
15699 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15701 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Headphone */
15702 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15703 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
15704 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15706 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15710 static struct hda_verb alc663_g71v_init_verbs
[] = {
15711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15712 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15713 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15715 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15716 {0x21, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15717 {0x21, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Headphone */
15719 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_FRONT_EVENT
},
15720 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_MIC_EVENT
},
15721 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_HP_EVENT
},
15725 static struct hda_verb alc663_g50v_init_verbs
[] = {
15726 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
15727 {0x21, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
15728 {0x21, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Headphone */
15730 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15731 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15735 static struct hda_verb alc662_ecs_init_verbs
[] = {
15736 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, 0x701f},
15737 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
15738 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
15739 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
15743 static struct snd_kcontrol_new alc662_auto_capture_mixer
[] = {
15744 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
15745 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
15749 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec
*codec
)
15751 unsigned int present
;
15752 unsigned char bits
;
15754 present
= snd_hda_codec_read(codec
, 0x14, 0,
15755 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
15756 bits
= present
? HDA_AMP_MUTE
: 0;
15757 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
15758 HDA_AMP_MUTE
, bits
);
15761 static void alc662_lenovo_101e_all_automute(struct hda_codec
*codec
)
15763 unsigned int present
;
15764 unsigned char bits
;
15766 present
= snd_hda_codec_read(codec
, 0x1b, 0,
15767 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
15768 bits
= present
? HDA_AMP_MUTE
: 0;
15769 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
15770 HDA_AMP_MUTE
, bits
);
15771 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
15772 HDA_AMP_MUTE
, bits
);
15775 static void alc662_lenovo_101e_unsol_event(struct hda_codec
*codec
,
15778 if ((res
>> 26) == ALC880_HP_EVENT
)
15779 alc662_lenovo_101e_all_automute(codec
);
15780 if ((res
>> 26) == ALC880_FRONT_EVENT
)
15781 alc662_lenovo_101e_ispeaker_automute(codec
);
15784 static void alc662_eeepc_mic_automute(struct hda_codec
*codec
)
15786 unsigned int present
;
15788 present
= snd_hda_codec_read(codec
, 0x18, 0,
15789 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
15790 snd_hda_codec_write(codec
, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15791 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
15792 snd_hda_codec_write(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15793 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
15794 snd_hda_codec_write(codec
, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15795 0x7000 | (0x01 << 8) | (present
? 0x80 : 0));
15796 snd_hda_codec_write(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15797 0x7000 | (0x01 << 8) | (present
? 0x80 : 0));
15800 /* unsolicited event for HP jack sensing */
15801 static void alc662_eeepc_unsol_event(struct hda_codec
*codec
,
15804 if ((res
>> 26) == ALC880_HP_EVENT
)
15805 alc262_hippo1_automute( codec
);
15807 if ((res
>> 26) == ALC880_MIC_EVENT
)
15808 alc662_eeepc_mic_automute(codec
);
15811 static void alc662_eeepc_inithook(struct hda_codec
*codec
)
15813 alc262_hippo1_automute( codec
);
15814 alc662_eeepc_mic_automute(codec
);
15817 static void alc662_eeepc_ep20_automute(struct hda_codec
*codec
)
15820 unsigned int present
;
15822 snd_hda_codec_read(codec
, 0x14, 0, AC_VERB_SET_PIN_SENSE
, 0);
15823 present
= snd_hda_codec_read(codec
, 0x14, 0,
15824 AC_VERB_GET_PIN_SENSE
, 0);
15825 present
= (present
& 0x80000000) != 0;
15827 /* mute internal speaker */
15828 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
15829 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
15831 /* unmute internal speaker if necessary */
15832 mute
= snd_hda_codec_amp_read(codec
, 0x14, 0, HDA_OUTPUT
, 0);
15833 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
15834 HDA_AMP_MUTE
, mute
);
15838 /* unsolicited event for HP jack sensing */
15839 static void alc662_eeepc_ep20_unsol_event(struct hda_codec
*codec
,
15842 if ((res
>> 26) == ALC880_HP_EVENT
)
15843 alc662_eeepc_ep20_automute(codec
);
15846 static void alc662_eeepc_ep20_inithook(struct hda_codec
*codec
)
15848 alc662_eeepc_ep20_automute(codec
);
15851 static void alc663_m51va_speaker_automute(struct hda_codec
*codec
)
15853 unsigned int present
;
15854 unsigned char bits
;
15856 present
= snd_hda_codec_read(codec
, 0x21, 0,
15857 AC_VERB_GET_PIN_SENSE
, 0)
15858 & AC_PINSENSE_PRESENCE
;
15859 bits
= present
? HDA_AMP_MUTE
: 0;
15860 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
15861 AMP_IN_MUTE(0), bits
);
15862 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
15863 AMP_IN_MUTE(0), bits
);
15866 static void alc663_21jd_two_speaker_automute(struct hda_codec
*codec
)
15868 unsigned int present
;
15869 unsigned char bits
;
15871 present
= snd_hda_codec_read(codec
, 0x21, 0,
15872 AC_VERB_GET_PIN_SENSE
, 0)
15873 & AC_PINSENSE_PRESENCE
;
15874 bits
= present
? HDA_AMP_MUTE
: 0;
15875 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
15876 AMP_IN_MUTE(0), bits
);
15877 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
15878 AMP_IN_MUTE(0), bits
);
15879 snd_hda_codec_amp_stereo(codec
, 0x0e, HDA_INPUT
, 0,
15880 AMP_IN_MUTE(0), bits
);
15881 snd_hda_codec_amp_stereo(codec
, 0x0e, HDA_INPUT
, 1,
15882 AMP_IN_MUTE(0), bits
);
15885 static void alc663_15jd_two_speaker_automute(struct hda_codec
*codec
)
15887 unsigned int present
;
15888 unsigned char bits
;
15890 present
= snd_hda_codec_read(codec
, 0x15, 0,
15891 AC_VERB_GET_PIN_SENSE
, 0)
15892 & AC_PINSENSE_PRESENCE
;
15893 bits
= present
? HDA_AMP_MUTE
: 0;
15894 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
15895 AMP_IN_MUTE(0), bits
);
15896 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
15897 AMP_IN_MUTE(0), bits
);
15898 snd_hda_codec_amp_stereo(codec
, 0x0e, HDA_INPUT
, 0,
15899 AMP_IN_MUTE(0), bits
);
15900 snd_hda_codec_amp_stereo(codec
, 0x0e, HDA_INPUT
, 1,
15901 AMP_IN_MUTE(0), bits
);
15904 static void alc662_f5z_speaker_automute(struct hda_codec
*codec
)
15906 unsigned int present
;
15907 unsigned char bits
;
15909 present
= snd_hda_codec_read(codec
, 0x1b, 0,
15910 AC_VERB_GET_PIN_SENSE
, 0)
15911 & AC_PINSENSE_PRESENCE
;
15912 bits
= present
? 0 : PIN_OUT
;
15913 snd_hda_codec_write(codec
, 0x14, 0,
15914 AC_VERB_SET_PIN_WIDGET_CONTROL
, bits
);
15917 static void alc663_two_hp_m1_speaker_automute(struct hda_codec
*codec
)
15919 unsigned int present1
, present2
;
15921 present1
= snd_hda_codec_read(codec
, 0x21, 0,
15922 AC_VERB_GET_PIN_SENSE
, 0)
15923 & AC_PINSENSE_PRESENCE
;
15924 present2
= snd_hda_codec_read(codec
, 0x15, 0,
15925 AC_VERB_GET_PIN_SENSE
, 0)
15926 & AC_PINSENSE_PRESENCE
;
15928 if (present1
|| present2
) {
15929 snd_hda_codec_write_cache(codec
, 0x14, 0,
15930 AC_VERB_SET_PIN_WIDGET_CONTROL
, 0);
15932 snd_hda_codec_write_cache(codec
, 0x14, 0,
15933 AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
);
15937 static void alc663_two_hp_m2_speaker_automute(struct hda_codec
*codec
)
15939 unsigned int present1
, present2
;
15941 present1
= snd_hda_codec_read(codec
, 0x1b, 0,
15942 AC_VERB_GET_PIN_SENSE
, 0)
15943 & AC_PINSENSE_PRESENCE
;
15944 present2
= snd_hda_codec_read(codec
, 0x15, 0,
15945 AC_VERB_GET_PIN_SENSE
, 0)
15946 & AC_PINSENSE_PRESENCE
;
15948 if (present1
|| present2
) {
15949 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
15950 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15951 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
15952 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15954 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 0,
15955 AMP_IN_MUTE(0), 0);
15956 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_INPUT
, 1,
15957 AMP_IN_MUTE(0), 0);
15961 static void alc663_m51va_mic_automute(struct hda_codec
*codec
)
15963 unsigned int present
;
15965 present
= snd_hda_codec_read(codec
, 0x18, 0,
15966 AC_VERB_GET_PIN_SENSE
, 0)
15967 & AC_PINSENSE_PRESENCE
;
15968 snd_hda_codec_write_cache(codec
, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15969 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
15970 snd_hda_codec_write_cache(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15971 0x7000 | (0x00 << 8) | (present
? 0 : 0x80));
15972 snd_hda_codec_write_cache(codec
, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15973 0x7000 | (0x09 << 8) | (present
? 0x80 : 0));
15974 snd_hda_codec_write_cache(codec
, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
15975 0x7000 | (0x09 << 8) | (present
? 0x80 : 0));
15978 static void alc663_m51va_unsol_event(struct hda_codec
*codec
,
15981 switch (res
>> 26) {
15982 case ALC880_HP_EVENT
:
15983 alc663_m51va_speaker_automute(codec
);
15985 case ALC880_MIC_EVENT
:
15986 alc663_m51va_mic_automute(codec
);
15991 static void alc663_m51va_inithook(struct hda_codec
*codec
)
15993 alc663_m51va_speaker_automute(codec
);
15994 alc663_m51va_mic_automute(codec
);
15997 /* ***************** Mode1 ******************************/
15998 static void alc663_mode1_unsol_event(struct hda_codec
*codec
,
16001 switch (res
>> 26) {
16002 case ALC880_HP_EVENT
:
16003 alc663_m51va_speaker_automute(codec
);
16005 case ALC880_MIC_EVENT
:
16006 alc662_eeepc_mic_automute(codec
);
16011 static void alc663_mode1_inithook(struct hda_codec
*codec
)
16013 alc663_m51va_speaker_automute(codec
);
16014 alc662_eeepc_mic_automute(codec
);
16016 /* ***************** Mode2 ******************************/
16017 static void alc662_mode2_unsol_event(struct hda_codec
*codec
,
16020 switch (res
>> 26) {
16021 case ALC880_HP_EVENT
:
16022 alc662_f5z_speaker_automute(codec
);
16024 case ALC880_MIC_EVENT
:
16025 alc662_eeepc_mic_automute(codec
);
16030 static void alc662_mode2_inithook(struct hda_codec
*codec
)
16032 alc662_f5z_speaker_automute(codec
);
16033 alc662_eeepc_mic_automute(codec
);
16035 /* ***************** Mode3 ******************************/
16036 static void alc663_mode3_unsol_event(struct hda_codec
*codec
,
16039 switch (res
>> 26) {
16040 case ALC880_HP_EVENT
:
16041 alc663_two_hp_m1_speaker_automute(codec
);
16043 case ALC880_MIC_EVENT
:
16044 alc662_eeepc_mic_automute(codec
);
16049 static void alc663_mode3_inithook(struct hda_codec
*codec
)
16051 alc663_two_hp_m1_speaker_automute(codec
);
16052 alc662_eeepc_mic_automute(codec
);
16054 /* ***************** Mode4 ******************************/
16055 static void alc663_mode4_unsol_event(struct hda_codec
*codec
,
16058 switch (res
>> 26) {
16059 case ALC880_HP_EVENT
:
16060 alc663_21jd_two_speaker_automute(codec
);
16062 case ALC880_MIC_EVENT
:
16063 alc662_eeepc_mic_automute(codec
);
16068 static void alc663_mode4_inithook(struct hda_codec
*codec
)
16070 alc663_21jd_two_speaker_automute(codec
);
16071 alc662_eeepc_mic_automute(codec
);
16073 /* ***************** Mode5 ******************************/
16074 static void alc663_mode5_unsol_event(struct hda_codec
*codec
,
16077 switch (res
>> 26) {
16078 case ALC880_HP_EVENT
:
16079 alc663_15jd_two_speaker_automute(codec
);
16081 case ALC880_MIC_EVENT
:
16082 alc662_eeepc_mic_automute(codec
);
16087 static void alc663_mode5_inithook(struct hda_codec
*codec
)
16089 alc663_15jd_two_speaker_automute(codec
);
16090 alc662_eeepc_mic_automute(codec
);
16092 /* ***************** Mode6 ******************************/
16093 static void alc663_mode6_unsol_event(struct hda_codec
*codec
,
16096 switch (res
>> 26) {
16097 case ALC880_HP_EVENT
:
16098 alc663_two_hp_m2_speaker_automute(codec
);
16100 case ALC880_MIC_EVENT
:
16101 alc662_eeepc_mic_automute(codec
);
16106 static void alc663_mode6_inithook(struct hda_codec
*codec
)
16108 alc663_two_hp_m2_speaker_automute(codec
);
16109 alc662_eeepc_mic_automute(codec
);
16112 static void alc663_g71v_hp_automute(struct hda_codec
*codec
)
16114 unsigned int present
;
16115 unsigned char bits
;
16117 present
= snd_hda_codec_read(codec
, 0x21, 0,
16118 AC_VERB_GET_PIN_SENSE
, 0)
16119 & AC_PINSENSE_PRESENCE
;
16120 bits
= present
? HDA_AMP_MUTE
: 0;
16121 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
16122 HDA_AMP_MUTE
, bits
);
16123 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
16124 HDA_AMP_MUTE
, bits
);
16127 static void alc663_g71v_front_automute(struct hda_codec
*codec
)
16129 unsigned int present
;
16130 unsigned char bits
;
16132 present
= snd_hda_codec_read(codec
, 0x15, 0,
16133 AC_VERB_GET_PIN_SENSE
, 0)
16134 & AC_PINSENSE_PRESENCE
;
16135 bits
= present
? HDA_AMP_MUTE
: 0;
16136 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
16137 HDA_AMP_MUTE
, bits
);
16140 static void alc663_g71v_unsol_event(struct hda_codec
*codec
,
16143 switch (res
>> 26) {
16144 case ALC880_HP_EVENT
:
16145 alc663_g71v_hp_automute(codec
);
16147 case ALC880_FRONT_EVENT
:
16148 alc663_g71v_front_automute(codec
);
16150 case ALC880_MIC_EVENT
:
16151 alc662_eeepc_mic_automute(codec
);
16156 static void alc663_g71v_inithook(struct hda_codec
*codec
)
16158 alc663_g71v_front_automute(codec
);
16159 alc663_g71v_hp_automute(codec
);
16160 alc662_eeepc_mic_automute(codec
);
16163 static void alc663_g50v_unsol_event(struct hda_codec
*codec
,
16166 switch (res
>> 26) {
16167 case ALC880_HP_EVENT
:
16168 alc663_m51va_speaker_automute(codec
);
16170 case ALC880_MIC_EVENT
:
16171 alc662_eeepc_mic_automute(codec
);
16176 static void alc663_g50v_inithook(struct hda_codec
*codec
)
16178 alc663_m51va_speaker_automute(codec
);
16179 alc662_eeepc_mic_automute(codec
);
16182 /* bind hp and internal speaker mute (with plug check) */
16183 static int alc662_ecs_master_sw_put(struct snd_kcontrol
*kcontrol
,
16184 struct snd_ctl_elem_value
*ucontrol
)
16186 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
16187 long *valp
= ucontrol
->value
.integer
.value
;
16190 change
= snd_hda_codec_amp_update(codec
, 0x1b, 0, HDA_OUTPUT
, 0,
16192 valp
[0] ? 0 : HDA_AMP_MUTE
);
16193 change
|= snd_hda_codec_amp_update(codec
, 0x1b, 1, HDA_OUTPUT
, 0,
16195 valp
[1] ? 0 : HDA_AMP_MUTE
);
16197 alc262_hippo1_automute(codec
);
16201 static struct snd_kcontrol_new alc662_ecs_mixer
[] = {
16202 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
16204 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
16205 .name
= "Master Playback Switch",
16206 .info
= snd_hda_mixer_amp_switch_info
,
16207 .get
= snd_hda_mixer_amp_switch_get
,
16208 .put
= alc662_ecs_master_sw_put
,
16209 .private_value
= HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT
),
16212 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT
),
16213 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT
),
16214 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT
),
16216 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT
),
16217 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
16218 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
16222 #ifdef CONFIG_SND_HDA_POWER_SAVE
16223 #define alc662_loopbacks alc880_loopbacks
16227 /* pcm configuration: identiacal with ALC880 */
16228 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16229 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16230 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16231 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16234 * configuration and preset
16236 static const char *alc662_models
[ALC662_MODEL_LAST
] = {
16237 [ALC662_3ST_2ch_DIG
] = "3stack-dig",
16238 [ALC662_3ST_6ch_DIG
] = "3stack-6ch-dig",
16239 [ALC662_3ST_6ch
] = "3stack-6ch",
16240 [ALC662_5ST_DIG
] = "6stack-dig",
16241 [ALC662_LENOVO_101E
] = "lenovo-101e",
16242 [ALC662_ASUS_EEEPC_P701
] = "eeepc-p701",
16243 [ALC662_ASUS_EEEPC_EP20
] = "eeepc-ep20",
16244 [ALC662_ECS
] = "ecs",
16245 [ALC663_ASUS_M51VA
] = "m51va",
16246 [ALC663_ASUS_G71V
] = "g71v",
16247 [ALC663_ASUS_H13
] = "h13",
16248 [ALC663_ASUS_G50V
] = "g50v",
16249 [ALC663_ASUS_MODE1
] = "asus-mode1",
16250 [ALC662_ASUS_MODE2
] = "asus-mode2",
16251 [ALC663_ASUS_MODE3
] = "asus-mode3",
16252 [ALC663_ASUS_MODE4
] = "asus-mode4",
16253 [ALC663_ASUS_MODE5
] = "asus-mode5",
16254 [ALC663_ASUS_MODE6
] = "asus-mode6",
16255 [ALC662_AUTO
] = "auto",
16258 static struct snd_pci_quirk alc662_cfg_tbl
[] = {
16259 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS
),
16260 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1
),
16261 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3
),
16262 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3
),
16263 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1
),
16264 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2
),
16265 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1
),
16266 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2
),
16267 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2
),
16268 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2
),
16269 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6
),
16270 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6
),
16271 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2
),
16272 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2
),
16273 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5
),
16274 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6
),
16275 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2
),
16276 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2
),
16277 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2
),
16278 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA
),
16279 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16280 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3
),
16281 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3
),
16282 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1
),
16283 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2
),
16284 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2
),
16285 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1
),
16286 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3
),
16287 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1
),
16288 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V
),
16289 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16290 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1
),
16291 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2
),
16292 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1
),
16293 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4
),
16294 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG
),
16295 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701
),
16296 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20
),
16297 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS
),
16298 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16299 ALC662_3ST_6ch_DIG
),
16300 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16301 ALC662_3ST_6ch_DIG
),
16302 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG
),
16303 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E
),
16304 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16305 ALC662_3ST_6ch_DIG
),
16306 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16311 static struct alc_config_preset alc662_presets
[] = {
16312 [ALC662_3ST_2ch_DIG
] = {
16313 .mixers
= { alc662_3ST_2ch_mixer
},
16314 .init_verbs
= { alc662_init_verbs
},
16315 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16316 .dac_nids
= alc662_dac_nids
,
16317 .dig_out_nid
= ALC662_DIGOUT_NID
,
16318 .dig_in_nid
= ALC662_DIGIN_NID
,
16319 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16320 .channel_mode
= alc662_3ST_2ch_modes
,
16321 .input_mux
= &alc662_capture_source
,
16323 [ALC662_3ST_6ch_DIG
] = {
16324 .mixers
= { alc662_3ST_6ch_mixer
, alc662_chmode_mixer
},
16325 .init_verbs
= { alc662_init_verbs
},
16326 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16327 .dac_nids
= alc662_dac_nids
,
16328 .dig_out_nid
= ALC662_DIGOUT_NID
,
16329 .dig_in_nid
= ALC662_DIGIN_NID
,
16330 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
16331 .channel_mode
= alc662_3ST_6ch_modes
,
16333 .input_mux
= &alc662_capture_source
,
16335 [ALC662_3ST_6ch
] = {
16336 .mixers
= { alc662_3ST_6ch_mixer
, alc662_chmode_mixer
},
16337 .init_verbs
= { alc662_init_verbs
},
16338 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16339 .dac_nids
= alc662_dac_nids
,
16340 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
16341 .channel_mode
= alc662_3ST_6ch_modes
,
16343 .input_mux
= &alc662_capture_source
,
16345 [ALC662_5ST_DIG
] = {
16346 .mixers
= { alc662_base_mixer
, alc662_chmode_mixer
},
16347 .init_verbs
= { alc662_init_verbs
},
16348 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16349 .dac_nids
= alc662_dac_nids
,
16350 .dig_out_nid
= ALC662_DIGOUT_NID
,
16351 .dig_in_nid
= ALC662_DIGIN_NID
,
16352 .num_channel_mode
= ARRAY_SIZE(alc662_5stack_modes
),
16353 .channel_mode
= alc662_5stack_modes
,
16354 .input_mux
= &alc662_capture_source
,
16356 [ALC662_LENOVO_101E
] = {
16357 .mixers
= { alc662_lenovo_101e_mixer
},
16358 .init_verbs
= { alc662_init_verbs
, alc662_sue_init_verbs
},
16359 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16360 .dac_nids
= alc662_dac_nids
,
16361 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16362 .channel_mode
= alc662_3ST_2ch_modes
,
16363 .input_mux
= &alc662_lenovo_101e_capture_source
,
16364 .unsol_event
= alc662_lenovo_101e_unsol_event
,
16365 .init_hook
= alc662_lenovo_101e_all_automute
,
16367 [ALC662_ASUS_EEEPC_P701
] = {
16368 .mixers
= { alc662_eeepc_p701_mixer
},
16369 .init_verbs
= { alc662_init_verbs
,
16370 alc662_eeepc_sue_init_verbs
},
16371 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16372 .dac_nids
= alc662_dac_nids
,
16373 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16374 .channel_mode
= alc662_3ST_2ch_modes
,
16375 .input_mux
= &alc662_eeepc_capture_source
,
16376 .unsol_event
= alc662_eeepc_unsol_event
,
16377 .init_hook
= alc662_eeepc_inithook
,
16379 [ALC662_ASUS_EEEPC_EP20
] = {
16380 .mixers
= { alc662_eeepc_ep20_mixer
,
16381 alc662_chmode_mixer
},
16382 .init_verbs
= { alc662_init_verbs
,
16383 alc662_eeepc_ep20_sue_init_verbs
},
16384 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16385 .dac_nids
= alc662_dac_nids
,
16386 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
16387 .channel_mode
= alc662_3ST_6ch_modes
,
16388 .input_mux
= &alc662_lenovo_101e_capture_source
,
16389 .unsol_event
= alc662_eeepc_ep20_unsol_event
,
16390 .init_hook
= alc662_eeepc_ep20_inithook
,
16393 .mixers
= { alc662_ecs_mixer
},
16394 .init_verbs
= { alc662_init_verbs
,
16395 alc662_ecs_init_verbs
},
16396 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16397 .dac_nids
= alc662_dac_nids
,
16398 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16399 .channel_mode
= alc662_3ST_2ch_modes
,
16400 .input_mux
= &alc662_eeepc_capture_source
,
16401 .unsol_event
= alc662_eeepc_unsol_event
,
16402 .init_hook
= alc662_eeepc_inithook
,
16404 [ALC663_ASUS_M51VA
] = {
16405 .mixers
= { alc663_m51va_mixer
},
16406 .init_verbs
= { alc662_init_verbs
, alc663_m51va_init_verbs
},
16407 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16408 .dac_nids
= alc662_dac_nids
,
16409 .dig_out_nid
= ALC662_DIGOUT_NID
,
16410 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16411 .channel_mode
= alc662_3ST_2ch_modes
,
16412 .input_mux
= &alc663_m51va_capture_source
,
16413 .unsol_event
= alc663_m51va_unsol_event
,
16414 .init_hook
= alc663_m51va_inithook
,
16416 [ALC663_ASUS_G71V
] = {
16417 .mixers
= { alc663_g71v_mixer
},
16418 .init_verbs
= { alc662_init_verbs
, alc663_g71v_init_verbs
},
16419 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16420 .dac_nids
= alc662_dac_nids
,
16421 .dig_out_nid
= ALC662_DIGOUT_NID
,
16422 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16423 .channel_mode
= alc662_3ST_2ch_modes
,
16424 .input_mux
= &alc662_eeepc_capture_source
,
16425 .unsol_event
= alc663_g71v_unsol_event
,
16426 .init_hook
= alc663_g71v_inithook
,
16428 [ALC663_ASUS_H13
] = {
16429 .mixers
= { alc663_m51va_mixer
},
16430 .init_verbs
= { alc662_init_verbs
, alc663_m51va_init_verbs
},
16431 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16432 .dac_nids
= alc662_dac_nids
,
16433 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16434 .channel_mode
= alc662_3ST_2ch_modes
,
16435 .input_mux
= &alc663_m51va_capture_source
,
16436 .unsol_event
= alc663_m51va_unsol_event
,
16437 .init_hook
= alc663_m51va_inithook
,
16439 [ALC663_ASUS_G50V
] = {
16440 .mixers
= { alc663_g50v_mixer
},
16441 .init_verbs
= { alc662_init_verbs
, alc663_g50v_init_verbs
},
16442 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16443 .dac_nids
= alc662_dac_nids
,
16444 .dig_out_nid
= ALC662_DIGOUT_NID
,
16445 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
16446 .channel_mode
= alc662_3ST_6ch_modes
,
16447 .input_mux
= &alc663_capture_source
,
16448 .unsol_event
= alc663_g50v_unsol_event
,
16449 .init_hook
= alc663_g50v_inithook
,
16451 [ALC663_ASUS_MODE1
] = {
16452 .mixers
= { alc663_m51va_mixer
},
16453 .cap_mixer
= alc662_auto_capture_mixer
,
16454 .init_verbs
= { alc662_init_verbs
,
16455 alc663_21jd_amic_init_verbs
},
16456 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16458 .dac_nids
= alc662_dac_nids
,
16459 .dig_out_nid
= ALC662_DIGOUT_NID
,
16460 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16461 .channel_mode
= alc662_3ST_2ch_modes
,
16462 .input_mux
= &alc662_eeepc_capture_source
,
16463 .unsol_event
= alc663_mode1_unsol_event
,
16464 .init_hook
= alc663_mode1_inithook
,
16466 [ALC662_ASUS_MODE2
] = {
16467 .mixers
= { alc662_1bjd_mixer
},
16468 .cap_mixer
= alc662_auto_capture_mixer
,
16469 .init_verbs
= { alc662_init_verbs
,
16470 alc662_1bjd_amic_init_verbs
},
16471 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16472 .dac_nids
= alc662_dac_nids
,
16473 .dig_out_nid
= ALC662_DIGOUT_NID
,
16474 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16475 .channel_mode
= alc662_3ST_2ch_modes
,
16476 .input_mux
= &alc662_eeepc_capture_source
,
16477 .unsol_event
= alc662_mode2_unsol_event
,
16478 .init_hook
= alc662_mode2_inithook
,
16480 [ALC663_ASUS_MODE3
] = {
16481 .mixers
= { alc663_two_hp_m1_mixer
},
16482 .cap_mixer
= alc662_auto_capture_mixer
,
16483 .init_verbs
= { alc662_init_verbs
,
16484 alc663_two_hp_amic_m1_init_verbs
},
16485 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16487 .dac_nids
= alc662_dac_nids
,
16488 .dig_out_nid
= ALC662_DIGOUT_NID
,
16489 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16490 .channel_mode
= alc662_3ST_2ch_modes
,
16491 .input_mux
= &alc662_eeepc_capture_source
,
16492 .unsol_event
= alc663_mode3_unsol_event
,
16493 .init_hook
= alc663_mode3_inithook
,
16495 [ALC663_ASUS_MODE4
] = {
16496 .mixers
= { alc663_asus_21jd_clfe_mixer
},
16497 .cap_mixer
= alc662_auto_capture_mixer
,
16498 .init_verbs
= { alc662_init_verbs
,
16499 alc663_21jd_amic_init_verbs
},
16500 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16502 .dac_nids
= alc662_dac_nids
,
16503 .dig_out_nid
= ALC662_DIGOUT_NID
,
16504 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16505 .channel_mode
= alc662_3ST_2ch_modes
,
16506 .input_mux
= &alc662_eeepc_capture_source
,
16507 .unsol_event
= alc663_mode4_unsol_event
,
16508 .init_hook
= alc663_mode4_inithook
,
16510 [ALC663_ASUS_MODE5
] = {
16511 .mixers
= { alc663_asus_15jd_clfe_mixer
},
16512 .cap_mixer
= alc662_auto_capture_mixer
,
16513 .init_verbs
= { alc662_init_verbs
,
16514 alc663_15jd_amic_init_verbs
},
16515 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16517 .dac_nids
= alc662_dac_nids
,
16518 .dig_out_nid
= ALC662_DIGOUT_NID
,
16519 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16520 .channel_mode
= alc662_3ST_2ch_modes
,
16521 .input_mux
= &alc662_eeepc_capture_source
,
16522 .unsol_event
= alc663_mode5_unsol_event
,
16523 .init_hook
= alc663_mode5_inithook
,
16525 [ALC663_ASUS_MODE6
] = {
16526 .mixers
= { alc663_two_hp_m2_mixer
},
16527 .cap_mixer
= alc662_auto_capture_mixer
,
16528 .init_verbs
= { alc662_init_verbs
,
16529 alc663_two_hp_amic_m2_init_verbs
},
16530 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
16532 .dac_nids
= alc662_dac_nids
,
16533 .dig_out_nid
= ALC662_DIGOUT_NID
,
16534 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
16535 .channel_mode
= alc662_3ST_2ch_modes
,
16536 .input_mux
= &alc662_eeepc_capture_source
,
16537 .unsol_event
= alc663_mode6_unsol_event
,
16538 .init_hook
= alc663_mode6_inithook
,
16544 * BIOS auto configuration
16547 /* add playback controls from the parsed DAC table */
16548 static int alc662_auto_create_multi_out_ctls(struct alc_spec
*spec
,
16549 const struct auto_pin_cfg
*cfg
)
16552 static const char *chname
[4] = {
16553 "Front", "Surround", NULL
/*CLFE*/, "Side"
16558 for (i
= 0; i
< cfg
->line_outs
; i
++) {
16559 if (!spec
->multiout
.dac_nids
[i
])
16561 nid
= alc880_idx_to_dac(i
);
16564 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
16565 "Center Playback Volume",
16566 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
16570 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
16571 "LFE Playback Volume",
16572 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
16576 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
16577 "Center Playback Switch",
16578 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16582 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
16583 "LFE Playback Switch",
16584 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16589 sprintf(name
, "%s Playback Volume", chname
[i
]);
16590 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
16591 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
16595 sprintf(name
, "%s Playback Switch", chname
[i
]);
16596 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
16597 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i
),
16606 /* add playback controls for speaker and HP outputs */
16607 static int alc662_auto_create_extra_out(struct alc_spec
*spec
, hda_nid_t pin
,
16618 /* ALC663 has a mono output pin on 0x17 */
16619 sprintf(name
, "%s Playback Switch", pfx
);
16620 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
16621 HDA_COMPOSE_AMP_VAL(pin
, 2, 0, HDA_OUTPUT
));
16625 if (alc880_is_fixed_pin(pin
)) {
16626 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
16627 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
16628 /* specify the DAC as the extra output */
16629 if (!spec
->multiout
.hp_nid
)
16630 spec
->multiout
.hp_nid
= nid
;
16632 spec
->multiout
.extra_out_nid
[0] = nid
;
16633 /* control HP volume/switch on the output mixer amp */
16634 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
16635 sprintf(name
, "%s Playback Volume", pfx
);
16636 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
16637 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
16640 sprintf(name
, "%s Playback Switch", pfx
);
16641 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
16642 HDA_COMPOSE_AMP_VAL(nid
, 3, 2, HDA_INPUT
));
16645 } else if (alc880_is_multi_pin(pin
)) {
16646 /* set manual connection */
16647 /* we have only a switch on HP-out PIN */
16648 sprintf(name
, "%s Playback Switch", pfx
);
16649 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
16650 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
16657 /* create playback/capture controls for input pins */
16658 static int alc662_auto_create_analog_input_ctls(struct alc_spec
*spec
,
16659 const struct auto_pin_cfg
*cfg
)
16661 struct hda_input_mux
*imux
= &spec
->private_imux
[0];
16664 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
16665 if (alc880_is_input_pin(cfg
->input_pins
[i
])) {
16666 idx
= alc880_input_pin_idx(cfg
->input_pins
[i
]);
16667 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
16668 auto_pin_cfg_labels
[i
],
16672 imux
->items
[imux
->num_items
].label
=
16673 auto_pin_cfg_labels
[i
];
16674 imux
->items
[imux
->num_items
].index
=
16675 alc880_input_pin_idx(cfg
->input_pins
[i
]);
16682 static void alc662_auto_set_output_and_unmute(struct hda_codec
*codec
,
16683 hda_nid_t nid
, int pin_type
,
16686 alc_set_pin_output(codec
, nid
, pin_type
);
16687 /* need the manual connection? */
16688 if (alc880_is_multi_pin(nid
)) {
16689 struct alc_spec
*spec
= codec
->spec
;
16690 int idx
= alc880_multi_pin_idx(nid
);
16691 snd_hda_codec_write(codec
, alc880_idx_to_selector(idx
), 0,
16692 AC_VERB_SET_CONNECT_SEL
,
16693 alc880_dac_to_idx(spec
->multiout
.dac_nids
[dac_idx
]));
16697 static void alc662_auto_init_multi_out(struct hda_codec
*codec
)
16699 struct alc_spec
*spec
= codec
->spec
;
16702 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
16703 for (i
= 0; i
<= HDA_SIDE
; i
++) {
16704 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
16705 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
16707 alc662_auto_set_output_and_unmute(codec
, nid
, pin_type
,
16712 static void alc662_auto_init_hp_out(struct hda_codec
*codec
)
16714 struct alc_spec
*spec
= codec
->spec
;
16717 pin
= spec
->autocfg
.hp_pins
[0];
16718 if (pin
) /* connect to front */
16720 alc662_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
16721 pin
= spec
->autocfg
.speaker_pins
[0];
16723 alc662_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
16726 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16727 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16729 static void alc662_auto_init_analog_input(struct hda_codec
*codec
)
16731 struct alc_spec
*spec
= codec
->spec
;
16734 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
16735 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
16736 if (alc662_is_input_pin(nid
)) {
16737 snd_hda_codec_write(codec
, nid
, 0,
16738 AC_VERB_SET_PIN_WIDGET_CONTROL
,
16739 (i
<= AUTO_PIN_FRONT_MIC
?
16740 PIN_VREF80
: PIN_IN
));
16741 if (nid
!= ALC662_PIN_CD_NID
)
16742 snd_hda_codec_write(codec
, nid
, 0,
16743 AC_VERB_SET_AMP_GAIN_MUTE
,
16749 #define alc662_auto_init_input_src alc882_auto_init_input_src
16751 static int alc662_parse_auto_config(struct hda_codec
*codec
)
16753 struct alc_spec
*spec
= codec
->spec
;
16755 static hda_nid_t alc662_ignore
[] = { 0x1d, 0 };
16757 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
16761 if (!spec
->autocfg
.line_outs
)
16762 return 0; /* can't find valid BIOS pin config */
16764 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
16767 err
= alc662_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
16770 err
= alc662_auto_create_extra_out(spec
,
16771 spec
->autocfg
.speaker_pins
[0],
16775 err
= alc662_auto_create_extra_out(spec
, spec
->autocfg
.hp_pins
[0],
16779 err
= alc662_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
16783 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
16785 if (spec
->autocfg
.dig_outs
)
16786 spec
->multiout
.dig_out_nid
= ALC880_DIGOUT_NID
;
16788 if (spec
->kctls
.list
)
16789 add_mixer(spec
, spec
->kctls
.list
);
16791 spec
->num_mux_defs
= 1;
16792 spec
->input_mux
= &spec
->private_imux
[0];
16794 add_verb(spec
, alc662_auto_init_verbs
);
16795 if (codec
->vendor_id
== 0x10ec0663)
16796 add_verb(spec
, alc663_auto_init_verbs
);
16798 err
= alc_auto_add_mic_boost(codec
);
16805 /* additional initialization for auto-configuration model */
16806 static void alc662_auto_init(struct hda_codec
*codec
)
16808 struct alc_spec
*spec
= codec
->spec
;
16809 alc662_auto_init_multi_out(codec
);
16810 alc662_auto_init_hp_out(codec
);
16811 alc662_auto_init_analog_input(codec
);
16812 alc662_auto_init_input_src(codec
);
16813 if (spec
->unsol_event
)
16814 alc_inithook(codec
);
16817 static int patch_alc662(struct hda_codec
*codec
)
16819 struct alc_spec
*spec
;
16820 int err
, board_config
;
16822 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
16826 codec
->spec
= spec
;
16828 alc_fix_pll_init(codec
, 0x20, 0x04, 15);
16830 board_config
= snd_hda_check_board_config(codec
, ALC662_MODEL_LAST
,
16833 if (board_config
< 0) {
16834 printk(KERN_INFO
"hda_codec: Unknown model for ALC662, "
16835 "trying auto-probe from BIOS...\n");
16836 board_config
= ALC662_AUTO
;
16839 if (board_config
== ALC662_AUTO
) {
16840 /* automatic parse from the BIOS config */
16841 err
= alc662_parse_auto_config(codec
);
16847 "hda_codec: Cannot set up configuration "
16848 "from BIOS. Using base mode...\n");
16849 board_config
= ALC662_3ST_2ch_DIG
;
16853 err
= snd_hda_attach_beep_device(codec
, 0x1);
16859 if (board_config
!= ALC662_AUTO
)
16860 setup_preset(spec
, &alc662_presets
[board_config
]);
16862 if (codec
->vendor_id
== 0x10ec0663) {
16863 spec
->stream_name_analog
= "ALC663 Analog";
16864 spec
->stream_name_digital
= "ALC663 Digital";
16865 } else if (codec
->vendor_id
== 0x10ec0272) {
16866 spec
->stream_name_analog
= "ALC272 Analog";
16867 spec
->stream_name_digital
= "ALC272 Digital";
16869 spec
->stream_name_analog
= "ALC662 Analog";
16870 spec
->stream_name_digital
= "ALC662 Digital";
16873 spec
->stream_analog_playback
= &alc662_pcm_analog_playback
;
16874 spec
->stream_analog_capture
= &alc662_pcm_analog_capture
;
16876 spec
->stream_digital_playback
= &alc662_pcm_digital_playback
;
16877 spec
->stream_digital_capture
= &alc662_pcm_digital_capture
;
16879 spec
->adc_nids
= alc662_adc_nids
;
16880 spec
->num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
);
16881 spec
->capsrc_nids
= alc662_capsrc_nids
;
16882 spec
->capture_style
= CAPT_MIX
;
16884 if (!spec
->cap_mixer
)
16885 set_capture_mixer(spec
);
16886 set_beep_amp(spec
, 0x0b, 0x05, HDA_INPUT
);
16888 spec
->vmaster_nid
= 0x02;
16890 codec
->patch_ops
= alc_patch_ops
;
16891 if (board_config
== ALC662_AUTO
)
16892 spec
->init_hook
= alc662_auto_init
;
16893 #ifdef CONFIG_SND_HDA_POWER_SAVE
16894 if (!spec
->loopback
.amplist
)
16895 spec
->loopback
.amplist
= alc662_loopbacks
;
16897 codec
->proc_widget_hook
= print_realtek_coef
;
16905 static struct hda_codec_preset snd_hda_preset_realtek
[] = {
16906 { .id
= 0x10ec0260, .name
= "ALC260", .patch
= patch_alc260
},
16907 { .id
= 0x10ec0262, .name
= "ALC262", .patch
= patch_alc262
},
16908 { .id
= 0x10ec0267, .name
= "ALC267", .patch
= patch_alc268
},
16909 { .id
= 0x10ec0268, .name
= "ALC268", .patch
= patch_alc268
},
16910 { .id
= 0x10ec0269, .name
= "ALC269", .patch
= patch_alc269
},
16911 { .id
= 0x10ec0272, .name
= "ALC272", .patch
= patch_alc662
},
16912 { .id
= 0x10ec0861, .rev
= 0x100340, .name
= "ALC660",
16913 .patch
= patch_alc861
},
16914 { .id
= 0x10ec0660, .name
= "ALC660-VD", .patch
= patch_alc861vd
},
16915 { .id
= 0x10ec0861, .name
= "ALC861", .patch
= patch_alc861
},
16916 { .id
= 0x10ec0862, .name
= "ALC861-VD", .patch
= patch_alc861vd
},
16917 { .id
= 0x10ec0662, .rev
= 0x100002, .name
= "ALC662 rev2",
16918 .patch
= patch_alc883
},
16919 { .id
= 0x10ec0662, .rev
= 0x100101, .name
= "ALC662 rev1",
16920 .patch
= patch_alc662
},
16921 { .id
= 0x10ec0663, .name
= "ALC663", .patch
= patch_alc662
},
16922 { .id
= 0x10ec0880, .name
= "ALC880", .patch
= patch_alc880
},
16923 { .id
= 0x10ec0882, .name
= "ALC882", .patch
= patch_alc882
},
16924 { .id
= 0x10ec0883, .name
= "ALC883", .patch
= patch_alc883
},
16925 { .id
= 0x10ec0885, .rev
= 0x100101, .name
= "ALC889A",
16926 .patch
= patch_alc882
}, /* should be patch_alc883() in future */
16927 { .id
= 0x10ec0885, .rev
= 0x100103, .name
= "ALC889A",
16928 .patch
= patch_alc882
}, /* should be patch_alc883() in future */
16929 { .id
= 0x10ec0885, .name
= "ALC885", .patch
= patch_alc882
},
16930 { .id
= 0x10ec0887, .name
= "ALC887", .patch
= patch_alc883
},
16931 { .id
= 0x10ec0888, .rev
= 0x100101, .name
= "ALC1200",
16932 .patch
= patch_alc883
},
16933 { .id
= 0x10ec0888, .name
= "ALC888", .patch
= patch_alc883
},
16934 { .id
= 0x10ec0889, .name
= "ALC889", .patch
= patch_alc883
},
16935 {} /* terminator */
16938 MODULE_ALIAS("snd-hda-codec-id:10ec*");
16940 MODULE_LICENSE("GPL");
16941 MODULE_DESCRIPTION("Realtek HD-audio codec");
16943 static struct hda_codec_preset_list realtek_list
= {
16944 .preset
= snd_hda_preset_realtek
,
16945 .owner
= THIS_MODULE
,
16948 static int __init
patch_realtek_init(void)
16950 return snd_hda_add_codec_preset(&realtek_list
);
16953 static void __exit
patch_realtek_exit(void)
16955 snd_hda_delete_codec_preset(&realtek_list
);
16958 module_init(patch_realtek_init
)
16959 module_exit(patch_realtek_exit
)