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 <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #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 */
63 #ifdef CONFIG_SND_DEBUG
67 ALC880_MODEL_LAST
/* last tag */
79 #ifdef CONFIG_SND_DEBUG
83 ALC260_MODEL_LAST
/* last tag */
93 ALC262_HP_BPC_D7000_WL
,
94 ALC262_HP_BPC_D7000_WF
,
99 ALC262_MODEL_LAST
/* last tag */
106 ALC268_MODEL_LAST
/* last tag */
123 /* ALC861-VD models */
168 ALC883_TARGA_2ch_DIG
,
174 ALC883_LENOVO_101E_2ch
,
175 ALC883_LENOVO_NB0763
,
176 ALC888_LENOVO_MS7195_DIG
,
184 #define GPIO_MASK 0x03
187 /* codec parameterization */
188 struct snd_kcontrol_new
*mixers
[5]; /* mixer arrays */
189 unsigned int num_mixers
;
191 const struct hda_verb
*init_verbs
[5]; /* initialization verbs
195 unsigned int num_init_verbs
;
197 char *stream_name_analog
; /* analog PCM stream */
198 struct hda_pcm_stream
*stream_analog_playback
;
199 struct hda_pcm_stream
*stream_analog_capture
;
201 char *stream_name_digital
; /* digital PCM stream */
202 struct hda_pcm_stream
*stream_digital_playback
;
203 struct hda_pcm_stream
*stream_digital_capture
;
206 struct hda_multi_out multiout
; /* playback set-up
207 * max_channels, dacs must be set
208 * dig_out_nid and hp_nid are optional
212 unsigned int num_adc_nids
;
214 hda_nid_t dig_in_nid
; /* digital-in NID; optional */
217 unsigned int num_mux_defs
;
218 const struct hda_input_mux
*input_mux
;
219 unsigned int cur_mux
[3];
222 const struct hda_channel_mode
*channel_mode
;
223 int num_channel_mode
;
226 /* PCM information */
227 struct hda_pcm pcm_rec
[3]; /* used in alc_build_pcms() */
229 /* dynamic controls, init_verbs and input_mux */
230 struct auto_pin_cfg autocfg
;
231 unsigned int num_kctl_alloc
, num_kctl_used
;
232 struct snd_kcontrol_new
*kctl_alloc
;
233 struct hda_input_mux private_imux
;
234 hda_nid_t private_dac_nids
[5];
237 void (*init_hook
)(struct hda_codec
*codec
);
238 void (*unsol_event
)(struct hda_codec
*codec
, unsigned int res
);
240 /* for pin sensing */
241 unsigned int sense_updated
: 1;
242 unsigned int jack_present
: 1;
246 * configuration template - to be copied to the spec instance
248 struct alc_config_preset
{
249 struct snd_kcontrol_new
*mixers
[5]; /* should be identical size
252 const struct hda_verb
*init_verbs
[5];
253 unsigned int num_dacs
;
255 hda_nid_t dig_out_nid
; /* optional */
256 hda_nid_t hp_nid
; /* optional */
257 unsigned int num_adc_nids
;
259 hda_nid_t dig_in_nid
;
260 unsigned int num_channel_mode
;
261 const struct hda_channel_mode
*channel_mode
;
263 unsigned int num_mux_defs
;
264 const struct hda_input_mux
*input_mux
;
265 void (*unsol_event
)(struct hda_codec
*, unsigned int);
266 void (*init_hook
)(struct hda_codec
*);
273 static int alc_mux_enum_info(struct snd_kcontrol
*kcontrol
,
274 struct snd_ctl_elem_info
*uinfo
)
276 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
277 struct alc_spec
*spec
= codec
->spec
;
278 unsigned int mux_idx
= snd_ctl_get_ioffidx(kcontrol
, &uinfo
->id
);
279 if (mux_idx
>= spec
->num_mux_defs
)
281 return snd_hda_input_mux_info(&spec
->input_mux
[mux_idx
], uinfo
);
284 static int alc_mux_enum_get(struct snd_kcontrol
*kcontrol
,
285 struct snd_ctl_elem_value
*ucontrol
)
287 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
288 struct alc_spec
*spec
= codec
->spec
;
289 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
291 ucontrol
->value
.enumerated
.item
[0] = spec
->cur_mux
[adc_idx
];
295 static int alc_mux_enum_put(struct snd_kcontrol
*kcontrol
,
296 struct snd_ctl_elem_value
*ucontrol
)
298 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
299 struct alc_spec
*spec
= codec
->spec
;
300 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
301 unsigned int mux_idx
= adc_idx
>= spec
->num_mux_defs
? 0 : adc_idx
;
302 return snd_hda_input_mux_put(codec
, &spec
->input_mux
[mux_idx
], ucontrol
,
303 spec
->adc_nids
[adc_idx
],
304 &spec
->cur_mux
[adc_idx
]);
309 * channel mode setting
311 static int alc_ch_mode_info(struct snd_kcontrol
*kcontrol
,
312 struct snd_ctl_elem_info
*uinfo
)
314 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
315 struct alc_spec
*spec
= codec
->spec
;
316 return snd_hda_ch_mode_info(codec
, uinfo
, spec
->channel_mode
,
317 spec
->num_channel_mode
);
320 static int alc_ch_mode_get(struct snd_kcontrol
*kcontrol
,
321 struct snd_ctl_elem_value
*ucontrol
)
323 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
324 struct alc_spec
*spec
= codec
->spec
;
325 return snd_hda_ch_mode_get(codec
, ucontrol
, spec
->channel_mode
,
326 spec
->num_channel_mode
,
327 spec
->multiout
.max_channels
);
330 static int alc_ch_mode_put(struct snd_kcontrol
*kcontrol
,
331 struct snd_ctl_elem_value
*ucontrol
)
333 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
334 struct alc_spec
*spec
= codec
->spec
;
335 int err
= snd_hda_ch_mode_put(codec
, ucontrol
, spec
->channel_mode
,
336 spec
->num_channel_mode
,
337 &spec
->multiout
.max_channels
);
338 if (err
>= 0 && spec
->need_dac_fix
)
339 spec
->multiout
.num_dacs
= spec
->multiout
.max_channels
/ 2;
344 * Control the mode of pin widget settings via the mixer. "pc" is used
345 * instead of "%" to avoid consequences of accidently treating the % as
346 * being part of a format specifier. Maximum allowed length of a value is
347 * 63 characters plus NULL terminator.
349 * Note: some retasking pin complexes seem to ignore requests for input
350 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
351 * are requested. Therefore order this list so that this behaviour will not
352 * cause problems when mixer clients move through the enum sequentially.
353 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
356 static char *alc_pin_mode_names
[] = {
357 "Mic 50pc bias", "Mic 80pc bias",
358 "Line in", "Line out", "Headphone out",
360 static unsigned char alc_pin_mode_values
[] = {
361 PIN_VREF50
, PIN_VREF80
, PIN_IN
, PIN_OUT
, PIN_HP
,
363 /* The control can present all 5 options, or it can limit the options based
364 * in the pin being assumed to be exclusively an input or an output pin. In
365 * addition, "input" pins may or may not process the mic bias option
366 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
367 * accept requests for bias as of chip versions up to March 2006) and/or
368 * wiring in the computer.
370 #define ALC_PIN_DIR_IN 0x00
371 #define ALC_PIN_DIR_OUT 0x01
372 #define ALC_PIN_DIR_INOUT 0x02
373 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
374 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
376 /* Info about the pin modes supported by the different pin direction modes.
377 * For each direction the minimum and maximum values are given.
379 static signed char alc_pin_mode_dir_info
[5][2] = {
380 { 0, 2 }, /* ALC_PIN_DIR_IN */
381 { 3, 4 }, /* ALC_PIN_DIR_OUT */
382 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
383 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
384 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
386 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
387 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
388 #define alc_pin_mode_n_items(_dir) \
389 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
391 static int alc_pin_mode_info(struct snd_kcontrol
*kcontrol
,
392 struct snd_ctl_elem_info
*uinfo
)
394 unsigned int item_num
= uinfo
->value
.enumerated
.item
;
395 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
397 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
399 uinfo
->value
.enumerated
.items
= alc_pin_mode_n_items(dir
);
401 if (item_num
<alc_pin_mode_min(dir
) || item_num
>alc_pin_mode_max(dir
))
402 item_num
= alc_pin_mode_min(dir
);
403 strcpy(uinfo
->value
.enumerated
.name
, alc_pin_mode_names
[item_num
]);
407 static int alc_pin_mode_get(struct snd_kcontrol
*kcontrol
,
408 struct snd_ctl_elem_value
*ucontrol
)
411 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
412 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
413 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
414 long *valp
= ucontrol
->value
.integer
.value
;
415 unsigned int pinctl
= snd_hda_codec_read(codec
, nid
, 0,
416 AC_VERB_GET_PIN_WIDGET_CONTROL
,
419 /* Find enumerated value for current pinctl setting */
420 i
= alc_pin_mode_min(dir
);
421 while (alc_pin_mode_values
[i
] != pinctl
&& i
<= alc_pin_mode_max(dir
))
423 *valp
= i
<= alc_pin_mode_max(dir
) ? i
: alc_pin_mode_min(dir
);
427 static int alc_pin_mode_put(struct snd_kcontrol
*kcontrol
,
428 struct snd_ctl_elem_value
*ucontrol
)
431 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
432 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
433 unsigned char dir
= (kcontrol
->private_value
>> 16) & 0xff;
434 long val
= *ucontrol
->value
.integer
.value
;
435 unsigned int pinctl
= snd_hda_codec_read(codec
, nid
, 0,
436 AC_VERB_GET_PIN_WIDGET_CONTROL
,
439 if (val
< alc_pin_mode_min(dir
) || val
> alc_pin_mode_max(dir
))
440 val
= alc_pin_mode_min(dir
);
442 change
= pinctl
!= alc_pin_mode_values
[val
];
444 /* Set pin mode to that requested */
445 snd_hda_codec_write_cache(codec
, nid
, 0,
446 AC_VERB_SET_PIN_WIDGET_CONTROL
,
447 alc_pin_mode_values
[val
]);
449 /* Also enable the retasking pin's input/output as required
450 * for the requested pin mode. Enum values of 2 or less are
453 * Dynamically switching the input/output buffers probably
454 * reduces noise slightly (particularly on input) so we'll
455 * do it. However, having both input and output buffers
456 * enabled simultaneously doesn't seem to be problematic if
457 * this turns out to be necessary in the future.
460 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
461 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
462 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
, 0,
465 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
, 0,
466 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
467 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
474 #define ALC_PIN_MODE(xname, nid, dir) \
475 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
476 .info = alc_pin_mode_info, \
477 .get = alc_pin_mode_get, \
478 .put = alc_pin_mode_put, \
479 .private_value = nid | (dir<<16) }
481 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
482 * together using a mask with more than one bit set. This control is
483 * currently used only by the ALC260 test model. At this stage they are not
484 * needed for any "production" models.
486 #ifdef CONFIG_SND_DEBUG
487 #define alc_gpio_data_info snd_ctl_boolean_mono_info
489 static int alc_gpio_data_get(struct snd_kcontrol
*kcontrol
,
490 struct snd_ctl_elem_value
*ucontrol
)
492 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
493 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
494 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
495 long *valp
= ucontrol
->value
.integer
.value
;
496 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
497 AC_VERB_GET_GPIO_DATA
, 0x00);
499 *valp
= (val
& mask
) != 0;
502 static int alc_gpio_data_put(struct snd_kcontrol
*kcontrol
,
503 struct snd_ctl_elem_value
*ucontrol
)
506 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
507 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
508 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
509 long val
= *ucontrol
->value
.integer
.value
;
510 unsigned int gpio_data
= snd_hda_codec_read(codec
, nid
, 0,
511 AC_VERB_GET_GPIO_DATA
,
514 /* Set/unset the masked GPIO bit(s) as needed */
515 change
= (val
== 0 ? 0 : mask
) != (gpio_data
& mask
);
520 snd_hda_codec_write_cache(codec
, nid
, 0,
521 AC_VERB_SET_GPIO_DATA
, gpio_data
);
525 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
526 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
527 .info = alc_gpio_data_info, \
528 .get = alc_gpio_data_get, \
529 .put = alc_gpio_data_put, \
530 .private_value = nid | (mask<<16) }
531 #endif /* CONFIG_SND_DEBUG */
533 /* A switch control to allow the enabling of the digital IO pins on the
534 * ALC260. This is incredibly simplistic; the intention of this control is
535 * to provide something in the test model allowing digital outputs to be
536 * identified if present. If models are found which can utilise these
537 * outputs a more complete mixer control can be devised for those models if
540 #ifdef CONFIG_SND_DEBUG
541 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
543 static int alc_spdif_ctrl_get(struct snd_kcontrol
*kcontrol
,
544 struct snd_ctl_elem_value
*ucontrol
)
546 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
547 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
548 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
549 long *valp
= ucontrol
->value
.integer
.value
;
550 unsigned int val
= snd_hda_codec_read(codec
, nid
, 0,
551 AC_VERB_GET_DIGI_CONVERT
, 0x00);
553 *valp
= (val
& mask
) != 0;
556 static int alc_spdif_ctrl_put(struct snd_kcontrol
*kcontrol
,
557 struct snd_ctl_elem_value
*ucontrol
)
560 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
561 hda_nid_t nid
= kcontrol
->private_value
& 0xffff;
562 unsigned char mask
= (kcontrol
->private_value
>> 16) & 0xff;
563 long val
= *ucontrol
->value
.integer
.value
;
564 unsigned int ctrl_data
= snd_hda_codec_read(codec
, nid
, 0,
565 AC_VERB_GET_DIGI_CONVERT
,
568 /* Set/unset the masked control bit(s) as needed */
569 change
= (val
== 0 ? 0 : mask
) != (ctrl_data
& mask
);
574 snd_hda_codec_write_cache(codec
, nid
, 0, AC_VERB_SET_DIGI_CONVERT_1
,
579 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
580 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
581 .info = alc_spdif_ctrl_info, \
582 .get = alc_spdif_ctrl_get, \
583 .put = alc_spdif_ctrl_put, \
584 .private_value = nid | (mask<<16) }
585 #endif /* CONFIG_SND_DEBUG */
588 * set up from the preset table
590 static void setup_preset(struct alc_spec
*spec
,
591 const struct alc_config_preset
*preset
)
595 for (i
= 0; i
< ARRAY_SIZE(preset
->mixers
) && preset
->mixers
[i
]; i
++)
596 spec
->mixers
[spec
->num_mixers
++] = preset
->mixers
[i
];
597 for (i
= 0; i
< ARRAY_SIZE(preset
->init_verbs
) && preset
->init_verbs
[i
];
599 spec
->init_verbs
[spec
->num_init_verbs
++] =
600 preset
->init_verbs
[i
];
602 spec
->channel_mode
= preset
->channel_mode
;
603 spec
->num_channel_mode
= preset
->num_channel_mode
;
604 spec
->need_dac_fix
= preset
->need_dac_fix
;
606 spec
->multiout
.max_channels
= spec
->channel_mode
[0].channels
;
608 spec
->multiout
.num_dacs
= preset
->num_dacs
;
609 spec
->multiout
.dac_nids
= preset
->dac_nids
;
610 spec
->multiout
.dig_out_nid
= preset
->dig_out_nid
;
611 spec
->multiout
.hp_nid
= preset
->hp_nid
;
613 spec
->num_mux_defs
= preset
->num_mux_defs
;
614 if (!spec
->num_mux_defs
)
615 spec
->num_mux_defs
= 1;
616 spec
->input_mux
= preset
->input_mux
;
618 spec
->num_adc_nids
= preset
->num_adc_nids
;
619 spec
->adc_nids
= preset
->adc_nids
;
620 spec
->dig_in_nid
= preset
->dig_in_nid
;
622 spec
->unsol_event
= preset
->unsol_event
;
623 spec
->init_hook
= preset
->init_hook
;
626 /* Enable GPIO mask and set output */
627 static struct hda_verb alc_gpio1_init_verbs
[] = {
628 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
629 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
630 {0x01, AC_VERB_SET_GPIO_DATA
, 0x01},
634 static struct hda_verb alc_gpio2_init_verbs
[] = {
635 {0x01, AC_VERB_SET_GPIO_MASK
, 0x02},
636 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x02},
637 {0x01, AC_VERB_SET_GPIO_DATA
, 0x02},
641 static struct hda_verb alc_gpio3_init_verbs
[] = {
642 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
643 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
644 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
648 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
649 * 31 ~ 16 : Manufacture ID
651 * 7 ~ 0 : Assembly ID
652 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
654 static void alc_subsystem_id(struct hda_codec
*codec
,
655 unsigned int porta
, unsigned int porte
,
658 unsigned int ass
, tmp
;
660 ass
= codec
->subsystem_id
;
665 tmp
= (ass
& 0x38) >> 3; /* external Amp control */
668 snd_hda_sequence_write(codec
, alc_gpio1_init_verbs
);
671 snd_hda_sequence_write(codec
, alc_gpio2_init_verbs
);
674 snd_hda_sequence_write(codec
, alc_gpio3_init_verbs
);
677 switch (codec
->vendor_id
) {
683 snd_hda_codec_write(codec
, 0x14, 0,
684 AC_VERB_SET_EAPD_BTLENABLE
, 2);
685 snd_hda_codec_write(codec
, 0x15, 0,
686 AC_VERB_SET_EAPD_BTLENABLE
, 2);
690 if (ass
& 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */
692 tmp
= (ass
& 0x1800) >> 11;
694 case 0: port
= porta
; break;
695 case 1: port
= porte
; break;
696 case 2: port
= portd
; break;
699 snd_hda_codec_write(codec
, port
, 0,
700 AC_VERB_SET_EAPD_BTLENABLE
,
703 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_COEF_INDEX
, 7);
704 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_PROC_COEF
,
705 (tmp
== 5 ? 0x3040 : 0x3050));
711 * Fix-up pin default configurations
719 static void alc_fix_pincfg(struct hda_codec
*codec
,
720 const struct snd_pci_quirk
*quirk
,
721 const struct alc_pincfg
**pinfix
)
723 const struct alc_pincfg
*cfg
;
725 quirk
= snd_pci_quirk_lookup(codec
->bus
->pci
, quirk
);
729 cfg
= pinfix
[quirk
->value
];
730 for (; cfg
->nid
; cfg
++) {
733 for (i
= 0; i
< 4; i
++) {
734 snd_hda_codec_write(codec
, cfg
->nid
, 0,
735 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0
+ i
,
743 * ALC880 3-stack model
745 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
746 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
747 * F-Mic = 0x1b, HP = 0x19
750 static hda_nid_t alc880_dac_nids
[4] = {
751 /* front, rear, clfe, rear_surr */
752 0x02, 0x05, 0x04, 0x03
755 static hda_nid_t alc880_adc_nids
[3] = {
760 /* The datasheet says the node 0x07 is connected from inputs,
761 * but it shows zero connection in the real implementation on some devices.
762 * Note: this is a 915GAV bug, fixed on 915GLV
764 static hda_nid_t alc880_adc_nids_alt
[2] = {
769 #define ALC880_DIGOUT_NID 0x06
770 #define ALC880_DIGIN_NID 0x0a
772 static struct hda_input_mux alc880_capture_source
= {
776 { "Front Mic", 0x3 },
782 /* channel source setting (2/6 channel selection for 3-stack) */
784 static struct hda_verb alc880_threestack_ch2_init
[] = {
785 /* set line-in to input, mute it */
786 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
787 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
788 /* set mic-in to input vref 80%, mute it */
789 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
790 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
795 static struct hda_verb alc880_threestack_ch6_init
[] = {
796 /* set line-in to output, unmute it */
797 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
798 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
799 /* set mic-in to output, unmute it */
800 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
801 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
805 static struct hda_channel_mode alc880_threestack_modes
[2] = {
806 { 2, alc880_threestack_ch2_init
},
807 { 6, alc880_threestack_ch6_init
},
810 static struct snd_kcontrol_new alc880_three_stack_mixer
[] = {
811 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
812 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
813 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
814 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT
),
815 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
816 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
817 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
818 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
819 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
820 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
823 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
824 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
825 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT
),
826 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT
),
827 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
828 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
829 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT
),
831 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
832 .name
= "Channel Mode",
833 .info
= alc_ch_mode_info
,
834 .get
= alc_ch_mode_get
,
835 .put
= alc_ch_mode_put
,
840 /* capture mixer elements */
841 static struct snd_kcontrol_new alc880_capture_mixer
[] = {
842 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT
),
843 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT
),
844 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT
),
845 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT
),
846 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT
),
847 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT
),
849 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
850 /* The multiple "Capture Source" controls confuse alsamixer
851 * So call somewhat different..
852 * FIXME: the controls appear in the "playback" view!
854 /* .name = "Capture Source", */
855 .name
= "Input Source",
857 .info
= alc_mux_enum_info
,
858 .get
= alc_mux_enum_get
,
859 .put
= alc_mux_enum_put
,
864 /* capture mixer elements (in case NID 0x07 not available) */
865 static struct snd_kcontrol_new alc880_capture_alt_mixer
[] = {
866 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
867 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
868 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
869 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
871 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
872 /* The multiple "Capture Source" controls confuse alsamixer
873 * So call somewhat different..
874 * FIXME: the controls appear in the "playback" view!
876 /* .name = "Capture Source", */
877 .name
= "Input Source",
879 .info
= alc_mux_enum_info
,
880 .get
= alc_mux_enum_get
,
881 .put
= alc_mux_enum_put
,
889 * ALC880 5-stack model
891 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
893 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
894 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
897 /* additional mixers to alc880_three_stack_mixer */
898 static struct snd_kcontrol_new alc880_five_stack_mixer
[] = {
899 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
900 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT
),
904 /* channel source setting (6/8 channel selection for 5-stack) */
906 static struct hda_verb alc880_fivestack_ch6_init
[] = {
907 /* set line-in to input, mute it */
908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
914 static struct hda_verb alc880_fivestack_ch8_init
[] = {
915 /* set line-in to output, unmute it */
916 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
917 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
921 static struct hda_channel_mode alc880_fivestack_modes
[2] = {
922 { 6, alc880_fivestack_ch6_init
},
923 { 8, alc880_fivestack_ch8_init
},
928 * ALC880 6-stack model
930 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
932 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
933 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
936 static hda_nid_t alc880_6st_dac_nids
[4] = {
937 /* front, rear, clfe, rear_surr */
938 0x02, 0x03, 0x04, 0x05
941 static struct hda_input_mux alc880_6stack_capture_source
= {
945 { "Front Mic", 0x1 },
951 /* fixed 8-channels */
952 static struct hda_channel_mode alc880_sixstack_modes
[1] = {
956 static struct snd_kcontrol_new alc880_six_stack_mixer
[] = {
957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
965 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
975 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
976 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
978 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
979 .name
= "Channel Mode",
980 .info
= alc_ch_mode_info
,
981 .get
= alc_ch_mode_get
,
982 .put
= alc_ch_mode_put
,
991 * W810 has rear IO for:
994 * Center/LFE (DAC 04)
997 * The system also has a pair of internal speakers, and a headphone jack.
998 * These are both connected to Line2 on the codec, hence to DAC 02.
1000 * There is a variable resistor to control the speaker or headphone
1001 * volume. This is a hardware-only device without a software API.
1003 * Plugging headphones in will disable the internal speakers. This is
1004 * implemented in hardware, not via the driver using jack sense. In
1005 * a similar fashion, plugging into the rear socket marked "front" will
1006 * disable both the speakers and headphones.
1008 * For input, there's a microphone jack, and an "audio in" jack.
1009 * These may not do anything useful with this driver yet, because I
1010 * haven't setup any initialization verbs for these yet...
1013 static hda_nid_t alc880_w810_dac_nids
[3] = {
1014 /* front, rear/surround, clfe */
1018 /* fixed 6 channels */
1019 static struct hda_channel_mode alc880_w810_modes
[1] = {
1023 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1024 static struct snd_kcontrol_new alc880_w810_base_mixer
[] = {
1025 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1026 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1027 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1028 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1029 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1030 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1031 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1032 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1033 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
1041 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1042 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1046 static hda_nid_t alc880_z71v_dac_nids
[1] = {
1049 #define ALC880_Z71V_HP_DAC 0x03
1051 /* fixed 2 channels */
1052 static struct hda_channel_mode alc880_2_jack_modes
[1] = {
1056 static struct snd_kcontrol_new alc880_z71v_mixer
[] = {
1057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1059 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1060 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT
),
1061 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1062 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1071 * ALC880 F1734 model
1073 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1074 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1077 static hda_nid_t alc880_f1734_dac_nids
[1] = {
1080 #define ALC880_F1734_HP_DAC 0x02
1082 static struct snd_kcontrol_new alc880_f1734_mixer
[] = {
1083 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1084 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1085 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1086 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1099 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1100 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1101 * Mic = 0x18, Line = 0x1a
1104 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1105 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1107 static struct snd_kcontrol_new alc880_asus_mixer
[] = {
1108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1109 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1110 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1111 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
1112 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1113 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1114 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1115 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1116 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1117 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1118 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1119 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1120 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1121 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1123 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1124 .name
= "Channel Mode",
1125 .info
= alc_ch_mode_info
,
1126 .get
= alc_ch_mode_get
,
1127 .put
= alc_ch_mode_put
,
1134 * ALC880 ASUS W1V model
1136 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1137 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1138 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1141 /* additional mixers to alc880_asus_mixer */
1142 static struct snd_kcontrol_new alc880_asus_w1v_mixer
[] = {
1143 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT
),
1144 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT
),
1148 /* additional mixers to alc880_asus_mixer */
1149 static struct snd_kcontrol_new alc880_pcbeep_mixer
[] = {
1150 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
1151 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
1156 static struct snd_kcontrol_new alc880_tcl_s700_mixer
[] = {
1157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1158 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
1159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
1160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT
),
1161 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT
),
1162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT
),
1163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT
),
1164 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
1165 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
1167 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1168 /* The multiple "Capture Source" controls confuse alsamixer
1169 * So call somewhat different..
1170 * FIXME: the controls appear in the "playback" view!
1172 /* .name = "Capture Source", */
1173 .name
= "Input Source",
1175 .info
= alc_mux_enum_info
,
1176 .get
= alc_mux_enum_get
,
1177 .put
= alc_mux_enum_put
,
1183 static struct snd_kcontrol_new alc880_uniwill_mixer
[] = {
1184 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1185 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT
),
1186 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1187 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1188 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1189 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1190 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1191 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1192 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1193 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1194 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1195 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1200 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
1201 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
1203 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1204 .name
= "Channel Mode",
1205 .info
= alc_ch_mode_info
,
1206 .get
= alc_ch_mode_get
,
1207 .put
= alc_ch_mode_put
,
1212 static struct snd_kcontrol_new alc880_fujitsu_mixer
[] = {
1213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1214 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT
),
1215 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1216 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1217 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
1218 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
1219 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1220 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1221 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1222 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1226 static struct snd_kcontrol_new alc880_uniwill_p53_mixer
[] = {
1227 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1228 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT
),
1229 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
1230 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT
),
1231 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1237 * build control elements
1239 static int alc_build_controls(struct hda_codec
*codec
)
1241 struct alc_spec
*spec
= codec
->spec
;
1245 for (i
= 0; i
< spec
->num_mixers
; i
++) {
1246 err
= snd_hda_add_new_ctls(codec
, spec
->mixers
[i
]);
1251 if (spec
->multiout
.dig_out_nid
) {
1252 err
= snd_hda_create_spdif_out_ctls(codec
,
1253 spec
->multiout
.dig_out_nid
);
1257 if (spec
->dig_in_nid
) {
1258 err
= snd_hda_create_spdif_in_ctls(codec
, spec
->dig_in_nid
);
1267 * initialize the codec volumes, etc
1271 * generic initialization of ADC, input mixers and output mixers
1273 static struct hda_verb alc880_volume_init_verbs
[] = {
1275 * Unmute ADC0-2 and set the default input to mic-in
1277 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
1278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1279 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
1280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1281 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
1282 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1284 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1286 * Note: PASD motherboards uses the Line In 2 as the input for front
1289 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
1292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
1293 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
1294 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
1297 * Set up output mixers (0x0c - 0x0f)
1299 /* set vol=0 to output mixers */
1300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1301 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1302 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1303 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
1304 /* set up input amps for analog loopback */
1305 /* Amp Indices: DAC = 0, mixer = 1 */
1306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
1308 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1309 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
1310 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1311 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
1312 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
1313 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
1319 * 3-stack pin configuration:
1320 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1322 static struct hda_verb alc880_pin_3stack_init_verbs
[] = {
1324 * preset connection lists of input pins
1325 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1327 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
1328 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1329 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x03}, /* line/surround */
1332 * Set pin mode and muting
1334 /* set front pin widgets 0x14 for output */
1335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1337 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1338 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1339 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1340 /* Mic2 (as headphone out) for HP output */
1341 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1342 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1343 /* Line In pin widget for input */
1344 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1345 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1346 /* Line2 (as front mic) pin widget for input and vref at 80% */
1347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1348 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1349 /* CD pin widget for input */
1350 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1356 * 5-stack pin configuration:
1357 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1358 * line-in/side = 0x1a, f-mic = 0x1b
1360 static struct hda_verb alc880_pin_5stack_init_verbs
[] = {
1362 * preset connection lists of input pins
1363 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1365 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1366 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/side */
1369 * Set pin mode and muting
1371 /* set pin widgets 0x14-0x17 for output */
1372 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1374 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1375 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1376 /* unmute pins for output (no gain on this amp) */
1377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1378 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1379 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1382 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1383 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1385 /* Mic2 (as headphone out) for HP output */
1386 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1387 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1388 /* Line In pin widget for input */
1389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1390 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1391 /* Line2 (as front mic) pin widget for input and vref at 80% */
1392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1394 /* CD pin widget for input */
1395 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1401 * W810 pin configuration:
1402 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1404 static struct hda_verb alc880_pin_w810_init_verbs
[] = {
1405 /* hphone/speaker input selector: front DAC */
1406 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x0},
1408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1409 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1410 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1411 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1413 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1415 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1416 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1422 * Z71V pin configuration:
1423 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1425 static struct hda_verb alc880_pin_z71v_init_verbs
[] = {
1426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1427 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1432 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1434 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1440 * 6-stack pin configuration:
1441 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1442 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1444 static struct hda_verb alc880_pin_6stack_init_verbs
[] = {
1445 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1447 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1449 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1451 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1452 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1453 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1454 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1456 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1457 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1462 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1463 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1464 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1470 * Uniwill pin configuration:
1471 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1474 static struct hda_verb alc880_uniwill_init_verbs
[] = {
1475 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1480 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1482 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1483 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1484 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1485 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1492 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1493 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1494 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1496 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1497 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1498 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1499 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1500 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1502 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
1503 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
1510 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1512 static struct hda_verb alc880_uniwill_p53_init_verbs
[] = {
1513 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1516 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1519 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1520 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1521 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1522 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1523 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1524 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1525 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
1526 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
1528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1529 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1531 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1535 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
1536 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_DCVOL_EVENT
},
1541 static struct hda_verb alc880_beep_init_verbs
[] = {
1542 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5) },
1546 /* toggle speaker-output according to the hp-jack state */
1547 static void alc880_uniwill_hp_automute(struct hda_codec
*codec
)
1549 unsigned int present
;
1552 present
= snd_hda_codec_read(codec
, 0x14, 0,
1553 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1554 bits
= present
? HDA_AMP_MUTE
: 0;
1555 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
1556 HDA_AMP_MUTE
, bits
);
1557 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_OUTPUT
, 0,
1558 HDA_AMP_MUTE
, bits
);
1561 /* auto-toggle front mic */
1562 static void alc880_uniwill_mic_automute(struct hda_codec
*codec
)
1564 unsigned int present
;
1567 present
= snd_hda_codec_read(codec
, 0x18, 0,
1568 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1569 bits
= present
? HDA_AMP_MUTE
: 0;
1570 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, 1, HDA_AMP_MUTE
, bits
);
1573 static void alc880_uniwill_automute(struct hda_codec
*codec
)
1575 alc880_uniwill_hp_automute(codec
);
1576 alc880_uniwill_mic_automute(codec
);
1579 static void alc880_uniwill_unsol_event(struct hda_codec
*codec
,
1582 /* Looks like the unsol event is incompatible with the standard
1583 * definition. 4bit tag is placed at 28 bit!
1585 switch (res
>> 28) {
1586 case ALC880_HP_EVENT
:
1587 alc880_uniwill_hp_automute(codec
);
1589 case ALC880_MIC_EVENT
:
1590 alc880_uniwill_mic_automute(codec
);
1595 static void alc880_uniwill_p53_hp_automute(struct hda_codec
*codec
)
1597 unsigned int present
;
1600 present
= snd_hda_codec_read(codec
, 0x14, 0,
1601 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1602 bits
= present
? HDA_AMP_MUTE
: 0;
1603 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_INPUT
, 0, HDA_AMP_MUTE
, bits
);
1606 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec
*codec
)
1608 unsigned int present
;
1610 present
= snd_hda_codec_read(codec
, 0x21, 0,
1611 AC_VERB_GET_VOLUME_KNOB_CONTROL
, 0);
1612 present
&= HDA_AMP_VOLMASK
;
1613 snd_hda_codec_amp_stereo(codec
, 0x0c, HDA_OUTPUT
, 0,
1614 HDA_AMP_VOLMASK
, present
);
1615 snd_hda_codec_amp_stereo(codec
, 0x0d, HDA_OUTPUT
, 0,
1616 HDA_AMP_VOLMASK
, present
);
1619 static void alc880_uniwill_p53_unsol_event(struct hda_codec
*codec
,
1622 /* Looks like the unsol event is incompatible with the standard
1623 * definition. 4bit tag is placed at 28 bit!
1625 if ((res
>> 28) == ALC880_HP_EVENT
)
1626 alc880_uniwill_p53_hp_automute(codec
);
1627 if ((res
>> 28) == ALC880_DCVOL_EVENT
)
1628 alc880_uniwill_p53_dcvol_automute(codec
);
1633 * F1734 pin configuration:
1634 * HP = 0x14, speaker-out = 0x15, mic = 0x18
1636 static struct hda_verb alc880_pin_f1734_init_verbs
[] = {
1637 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02},
1638 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00},
1639 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01},
1640 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00},
1642 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1647 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1649 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1650 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1651 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1653 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1654 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1655 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1662 * ASUS pin configuration:
1663 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1665 static struct hda_verb alc880_pin_asus_init_verbs
[] = {
1666 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02},
1667 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x00},
1668 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x01},
1669 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00},
1671 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1672 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1673 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1674 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1675 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1676 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1677 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1678 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1680 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1681 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1682 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1683 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1684 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
1686 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1687 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1688 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1693 /* Enable GPIO mask and set output */
1694 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1695 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1697 /* Clevo m520g init */
1698 static struct hda_verb alc880_pin_clevo_init_verbs
[] = {
1699 /* headphone output */
1700 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x01},
1702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1705 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1706 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1708 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1709 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1710 /* Mic1 (rear panel) */
1711 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1712 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1713 /* Mic2 (front panel) */
1714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1715 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1717 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1719 /* change to EAPD mode */
1720 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
1721 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
1726 static struct hda_verb alc880_pin_tcl_S700_init_verbs
[] = {
1727 /* change to EAPD mode */
1728 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
1729 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
1731 /* Headphone output */
1732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
1735 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
1737 /* Line In pin widget for input */
1738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1739 /* CD pin widget for input */
1740 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1741 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1742 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1744 /* change to EAPD mode */
1745 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
1746 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
1752 * LG m1 express dual
1755 * Rear Line-In/Out (blue): 0x14
1756 * Build-in Mic-In: 0x15
1758 * HP-Out (green): 0x1b
1759 * Mic-In/Out (red): 0x19
1763 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1764 static hda_nid_t alc880_lg_dac_nids
[3] = {
1768 /* seems analog CD is not working */
1769 static struct hda_input_mux alc880_lg_capture_source
= {
1774 { "Internal Mic", 0x6 },
1778 /* 2,4,6 channel modes */
1779 static struct hda_verb alc880_lg_ch2_init
[] = {
1780 /* set line-in and mic-in to input */
1781 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1782 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1786 static struct hda_verb alc880_lg_ch4_init
[] = {
1787 /* set line-in to out and mic-in to input */
1788 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1789 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1793 static struct hda_verb alc880_lg_ch6_init
[] = {
1794 /* set line-in and mic-in to output */
1795 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1796 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1800 static struct hda_channel_mode alc880_lg_ch_modes
[3] = {
1801 { 2, alc880_lg_ch2_init
},
1802 { 4, alc880_lg_ch4_init
},
1803 { 6, alc880_lg_ch6_init
},
1806 static struct snd_kcontrol_new alc880_lg_mixer
[] = {
1807 /* FIXME: it's not really "master" but front channels */
1808 HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
1809 HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT
),
1810 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1811 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT
),
1812 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT
),
1813 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT
),
1814 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT
),
1815 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT
),
1816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
1817 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
1818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT
),
1819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT
),
1820 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT
),
1821 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT
),
1823 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1824 .name
= "Channel Mode",
1825 .info
= alc_ch_mode_info
,
1826 .get
= alc_ch_mode_get
,
1827 .put
= alc_ch_mode_put
,
1832 static struct hda_verb alc880_lg_init_verbs
[] = {
1833 /* set capture source to mic-in */
1834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
1835 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
1836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
1837 /* mute all amp mixer inputs */
1838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5)},
1839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(6)},
1840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(7)},
1841 /* line-in to input */
1842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
1843 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1848 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1849 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1850 /* mic-in to input */
1851 {0x11, AC_VERB_SET_CONNECT_SEL
, 0x01},
1852 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1855 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x03},
1856 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1857 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1859 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| 0x1},
1863 /* toggle speaker-output according to the hp-jack state */
1864 static void alc880_lg_automute(struct hda_codec
*codec
)
1866 unsigned int present
;
1869 present
= snd_hda_codec_read(codec
, 0x1b, 0,
1870 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1871 bits
= present
? HDA_AMP_MUTE
: 0;
1872 snd_hda_codec_amp_stereo(codec
, 0x17, HDA_OUTPUT
, 0,
1873 HDA_AMP_MUTE
, bits
);
1876 static void alc880_lg_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1878 /* Looks like the unsol event is incompatible with the standard
1879 * definition. 4bit tag is placed at 28 bit!
1881 if ((res
>> 28) == 0x01)
1882 alc880_lg_automute(codec
);
1891 * Built-in Mic-In: 0x19
1897 static struct hda_input_mux alc880_lg_lw_capture_source
= {
1901 { "Internal Mic", 0x1 },
1906 #define alc880_lg_lw_modes alc880_threestack_modes
1908 static struct snd_kcontrol_new alc880_lg_lw_mixer
[] = {
1909 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
1910 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
1911 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
1912 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT
),
1913 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
1914 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
1915 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
1916 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
1917 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
1918 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
1919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
1920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
1921 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
1922 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
1924 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
1925 .name
= "Channel Mode",
1926 .info
= alc_ch_mode_info
,
1927 .get
= alc_ch_mode_get
,
1928 .put
= alc_ch_mode_put
,
1933 static struct hda_verb alc880_lg_lw_init_verbs
[] = {
1934 {0x13, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
1935 {0x10, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
1936 {0x12, AC_VERB_SET_CONNECT_SEL
, 0x03}, /* line/surround */
1938 /* set capture source to mic-in */
1939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1940 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1941 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
1942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(7)},
1944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1945 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1947 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
1948 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1949 /* mic-in to input */
1950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1951 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1953 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
1954 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
1956 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| 0x1},
1960 /* toggle speaker-output according to the hp-jack state */
1961 static void alc880_lg_lw_automute(struct hda_codec
*codec
)
1963 unsigned int present
;
1966 present
= snd_hda_codec_read(codec
, 0x1b, 0,
1967 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
1968 bits
= present
? HDA_AMP_MUTE
: 0;
1969 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
1970 HDA_AMP_MUTE
, bits
);
1973 static void alc880_lg_lw_unsol_event(struct hda_codec
*codec
, unsigned int res
)
1975 /* Looks like the unsol event is incompatible with the standard
1976 * definition. 4bit tag is placed at 28 bit!
1978 if ((res
>> 28) == 0x01)
1979 alc880_lg_lw_automute(codec
);
1986 static int alc_init(struct hda_codec
*codec
)
1988 struct alc_spec
*spec
= codec
->spec
;
1991 for (i
= 0; i
< spec
->num_init_verbs
; i
++)
1992 snd_hda_sequence_write(codec
, spec
->init_verbs
[i
]);
1994 if (spec
->init_hook
)
1995 spec
->init_hook(codec
);
2000 static void alc_unsol_event(struct hda_codec
*codec
, unsigned int res
)
2002 struct alc_spec
*spec
= codec
->spec
;
2004 if (spec
->unsol_event
)
2005 spec
->unsol_event(codec
, res
);
2009 * Analog playback callbacks
2011 static int alc880_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
2012 struct hda_codec
*codec
,
2013 struct snd_pcm_substream
*substream
)
2015 struct alc_spec
*spec
= codec
->spec
;
2016 return snd_hda_multi_out_analog_open(codec
, &spec
->multiout
, substream
);
2019 static int alc880_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2020 struct hda_codec
*codec
,
2021 unsigned int stream_tag
,
2022 unsigned int format
,
2023 struct snd_pcm_substream
*substream
)
2025 struct alc_spec
*spec
= codec
->spec
;
2026 return snd_hda_multi_out_analog_prepare(codec
, &spec
->multiout
,
2027 stream_tag
, format
, substream
);
2030 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
2031 struct hda_codec
*codec
,
2032 struct snd_pcm_substream
*substream
)
2034 struct alc_spec
*spec
= codec
->spec
;
2035 return snd_hda_multi_out_analog_cleanup(codec
, &spec
->multiout
);
2041 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream
*hinfo
,
2042 struct hda_codec
*codec
,
2043 struct snd_pcm_substream
*substream
)
2045 struct alc_spec
*spec
= codec
->spec
;
2046 return snd_hda_multi_out_dig_open(codec
, &spec
->multiout
);
2049 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2050 struct hda_codec
*codec
,
2051 unsigned int stream_tag
,
2052 unsigned int format
,
2053 struct snd_pcm_substream
*substream
)
2055 struct alc_spec
*spec
= codec
->spec
;
2056 return snd_hda_multi_out_dig_prepare(codec
, &spec
->multiout
,
2057 stream_tag
, format
, substream
);
2060 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream
*hinfo
,
2061 struct hda_codec
*codec
,
2062 struct snd_pcm_substream
*substream
)
2064 struct alc_spec
*spec
= codec
->spec
;
2065 return snd_hda_multi_out_dig_close(codec
, &spec
->multiout
);
2071 static int alc880_capture_pcm_prepare(struct hda_pcm_stream
*hinfo
,
2072 struct hda_codec
*codec
,
2073 unsigned int stream_tag
,
2074 unsigned int format
,
2075 struct snd_pcm_substream
*substream
)
2077 struct alc_spec
*spec
= codec
->spec
;
2079 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
2080 stream_tag
, 0, format
);
2084 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream
*hinfo
,
2085 struct hda_codec
*codec
,
2086 struct snd_pcm_substream
*substream
)
2088 struct alc_spec
*spec
= codec
->spec
;
2090 snd_hda_codec_setup_stream(codec
, spec
->adc_nids
[substream
->number
],
2098 static struct hda_pcm_stream alc880_pcm_analog_playback
= {
2102 /* NID is set in alc_build_pcms */
2104 .open
= alc880_playback_pcm_open
,
2105 .prepare
= alc880_playback_pcm_prepare
,
2106 .cleanup
= alc880_playback_pcm_cleanup
2110 static struct hda_pcm_stream alc880_pcm_analog_capture
= {
2114 /* NID is set in alc_build_pcms */
2116 .prepare
= alc880_capture_pcm_prepare
,
2117 .cleanup
= alc880_capture_pcm_cleanup
2121 static struct hda_pcm_stream alc880_pcm_digital_playback
= {
2125 /* NID is set in alc_build_pcms */
2127 .open
= alc880_dig_playback_pcm_open
,
2128 .close
= alc880_dig_playback_pcm_close
,
2129 .prepare
= alc880_dig_playback_pcm_prepare
2133 static struct hda_pcm_stream alc880_pcm_digital_capture
= {
2137 /* NID is set in alc_build_pcms */
2140 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2141 static struct hda_pcm_stream alc_pcm_null_playback
= {
2147 static int alc_build_pcms(struct hda_codec
*codec
)
2149 struct alc_spec
*spec
= codec
->spec
;
2150 struct hda_pcm
*info
= spec
->pcm_rec
;
2153 codec
->num_pcms
= 1;
2154 codec
->pcm_info
= info
;
2156 info
->name
= spec
->stream_name_analog
;
2157 if (spec
->stream_analog_playback
) {
2158 snd_assert(spec
->multiout
.dac_nids
, return -EINVAL
);
2159 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = *(spec
->stream_analog_playback
);
2160 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dac_nids
[0];
2162 if (spec
->stream_analog_capture
) {
2163 snd_assert(spec
->adc_nids
, return -EINVAL
);
2164 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_analog_capture
);
2165 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[0];
2168 if (spec
->channel_mode
) {
2169 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
= 0;
2170 for (i
= 0; i
< spec
->num_channel_mode
; i
++) {
2171 if (spec
->channel_mode
[i
].channels
> info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
) {
2172 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].channels_max
= spec
->channel_mode
[i
].channels
;
2177 /* SPDIF for stream index #1 */
2178 if (spec
->multiout
.dig_out_nid
|| spec
->dig_in_nid
) {
2179 codec
->num_pcms
= 2;
2180 info
= spec
->pcm_rec
+ 1;
2181 info
->name
= spec
->stream_name_digital
;
2182 if (spec
->multiout
.dig_out_nid
&&
2183 spec
->stream_digital_playback
) {
2184 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = *(spec
->stream_digital_playback
);
2185 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= spec
->multiout
.dig_out_nid
;
2187 if (spec
->dig_in_nid
&&
2188 spec
->stream_digital_capture
) {
2189 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_digital_capture
);
2190 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->dig_in_nid
;
2194 /* If the use of more than one ADC is requested for the current
2195 * model, configure a second analog capture-only PCM.
2197 /* Additional Analaog capture for index #2 */
2198 if (spec
->num_adc_nids
> 1 && spec
->stream_analog_capture
&&
2200 codec
->num_pcms
= 3;
2201 info
= spec
->pcm_rec
+ 2;
2202 info
->name
= spec
->stream_name_analog
;
2203 /* No playback stream for second PCM */
2204 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
] = alc_pcm_null_playback
;
2205 info
->stream
[SNDRV_PCM_STREAM_PLAYBACK
].nid
= 0;
2206 if (spec
->stream_analog_capture
) {
2207 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
] = *(spec
->stream_analog_capture
);
2208 info
->stream
[SNDRV_PCM_STREAM_CAPTURE
].nid
= spec
->adc_nids
[1];
2215 static void alc_free(struct hda_codec
*codec
)
2217 struct alc_spec
*spec
= codec
->spec
;
2223 if (spec
->kctl_alloc
) {
2224 for (i
= 0; i
< spec
->num_kctl_used
; i
++)
2225 kfree(spec
->kctl_alloc
[i
].name
);
2226 kfree(spec
->kctl_alloc
);
2233 static struct hda_codec_ops alc_patch_ops
= {
2234 .build_controls
= alc_build_controls
,
2235 .build_pcms
= alc_build_pcms
,
2238 .unsol_event
= alc_unsol_event
,
2243 * Test configuration for debugging
2245 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2248 #ifdef CONFIG_SND_DEBUG
2249 static hda_nid_t alc880_test_dac_nids
[4] = {
2250 0x02, 0x03, 0x04, 0x05
2253 static struct hda_input_mux alc880_test_capture_source
= {
2262 { "Surround", 0x6 },
2266 static struct hda_channel_mode alc880_test_modes
[4] = {
2273 static int alc_test_pin_ctl_info(struct snd_kcontrol
*kcontrol
,
2274 struct snd_ctl_elem_info
*uinfo
)
2276 static char *texts
[] = {
2277 "N/A", "Line Out", "HP Out",
2278 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2280 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2282 uinfo
->value
.enumerated
.items
= 8;
2283 if (uinfo
->value
.enumerated
.item
>= 8)
2284 uinfo
->value
.enumerated
.item
= 7;
2285 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
2289 static int alc_test_pin_ctl_get(struct snd_kcontrol
*kcontrol
,
2290 struct snd_ctl_elem_value
*ucontrol
)
2292 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
2293 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
2294 unsigned int pin_ctl
, item
= 0;
2296 pin_ctl
= snd_hda_codec_read(codec
, nid
, 0,
2297 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
2298 if (pin_ctl
& AC_PINCTL_OUT_EN
) {
2299 if (pin_ctl
& AC_PINCTL_HP_EN
)
2303 } else if (pin_ctl
& AC_PINCTL_IN_EN
) {
2304 switch (pin_ctl
& AC_PINCTL_VREFEN
) {
2305 case AC_PINCTL_VREF_HIZ
: item
= 3; break;
2306 case AC_PINCTL_VREF_50
: item
= 4; break;
2307 case AC_PINCTL_VREF_GRD
: item
= 5; break;
2308 case AC_PINCTL_VREF_80
: item
= 6; break;
2309 case AC_PINCTL_VREF_100
: item
= 7; break;
2312 ucontrol
->value
.enumerated
.item
[0] = item
;
2316 static int alc_test_pin_ctl_put(struct snd_kcontrol
*kcontrol
,
2317 struct snd_ctl_elem_value
*ucontrol
)
2319 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
2320 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
2321 static unsigned int ctls
[] = {
2322 0, AC_PINCTL_OUT_EN
, AC_PINCTL_OUT_EN
| AC_PINCTL_HP_EN
,
2323 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_HIZ
,
2324 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_50
,
2325 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_GRD
,
2326 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_80
,
2327 AC_PINCTL_IN_EN
| AC_PINCTL_VREF_100
,
2329 unsigned int old_ctl
, new_ctl
;
2331 old_ctl
= snd_hda_codec_read(codec
, nid
, 0,
2332 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
2333 new_ctl
= ctls
[ucontrol
->value
.enumerated
.item
[0]];
2334 if (old_ctl
!= new_ctl
) {
2336 snd_hda_codec_write_cache(codec
, nid
, 0,
2337 AC_VERB_SET_PIN_WIDGET_CONTROL
,
2339 val
= ucontrol
->value
.enumerated
.item
[0] >= 3 ?
2341 snd_hda_codec_amp_stereo(codec
, nid
, HDA_OUTPUT
, 0,
2348 static int alc_test_pin_src_info(struct snd_kcontrol
*kcontrol
,
2349 struct snd_ctl_elem_info
*uinfo
)
2351 static char *texts
[] = {
2352 "Front", "Surround", "CLFE", "Side"
2354 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
2356 uinfo
->value
.enumerated
.items
= 4;
2357 if (uinfo
->value
.enumerated
.item
>= 4)
2358 uinfo
->value
.enumerated
.item
= 3;
2359 strcpy(uinfo
->value
.enumerated
.name
, texts
[uinfo
->value
.enumerated
.item
]);
2363 static int alc_test_pin_src_get(struct snd_kcontrol
*kcontrol
,
2364 struct snd_ctl_elem_value
*ucontrol
)
2366 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
2367 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
2370 sel
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONNECT_SEL
, 0);
2371 ucontrol
->value
.enumerated
.item
[0] = sel
& 3;
2375 static int alc_test_pin_src_put(struct snd_kcontrol
*kcontrol
,
2376 struct snd_ctl_elem_value
*ucontrol
)
2378 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
2379 hda_nid_t nid
= (hda_nid_t
)kcontrol
->private_value
;
2382 sel
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONNECT_SEL
, 0) & 3;
2383 if (ucontrol
->value
.enumerated
.item
[0] != sel
) {
2384 sel
= ucontrol
->value
.enumerated
.item
[0] & 3;
2385 snd_hda_codec_write_cache(codec
, nid
, 0,
2386 AC_VERB_SET_CONNECT_SEL
, sel
);
2392 #define PIN_CTL_TEST(xname,nid) { \
2393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2395 .info = alc_test_pin_ctl_info, \
2396 .get = alc_test_pin_ctl_get, \
2397 .put = alc_test_pin_ctl_put, \
2398 .private_value = nid \
2401 #define PIN_SRC_TEST(xname,nid) { \
2402 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2404 .info = alc_test_pin_src_info, \
2405 .get = alc_test_pin_src_get, \
2406 .put = alc_test_pin_src_put, \
2407 .private_value = nid \
2410 static struct snd_kcontrol_new alc880_test_mixer
[] = {
2411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
2412 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
2413 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
2414 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
2415 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
2416 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
2417 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT
),
2418 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
2419 PIN_CTL_TEST("Front Pin Mode", 0x14),
2420 PIN_CTL_TEST("Surround Pin Mode", 0x15),
2421 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2422 PIN_CTL_TEST("Side Pin Mode", 0x17),
2423 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2424 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2425 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2426 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2427 PIN_SRC_TEST("In-1 Pin Source", 0x18),
2428 PIN_SRC_TEST("In-2 Pin Source", 0x19),
2429 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2430 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2431 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT
),
2432 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT
),
2433 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT
),
2434 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT
),
2435 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT
),
2436 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT
),
2437 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT
),
2438 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT
),
2439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT
),
2440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT
),
2442 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
2443 .name
= "Channel Mode",
2444 .info
= alc_ch_mode_info
,
2445 .get
= alc_ch_mode_get
,
2446 .put
= alc_ch_mode_put
,
2451 static struct hda_verb alc880_test_init_verbs
[] = {
2452 /* Unmute inputs of 0x0c - 0x0f */
2453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2455 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2456 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2457 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2459 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
2460 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
2461 /* Vol output for 0x0c-0x0f */
2462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
2466 /* Set output pins 0x14-0x17 */
2467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2468 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2469 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2470 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
2471 /* Unmute output pins 0x14-0x17 */
2472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2473 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2474 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2475 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
2476 /* Set input pins 0x18-0x1c */
2477 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
2479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2480 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2481 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
2482 /* Mute input pins 0x18-0x1b */
2483 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2484 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2485 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2486 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
2488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2489 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
2490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2491 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
2492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2493 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
2494 /* Analog input/passthru */
2495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
2496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
2497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
2498 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
2499 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
2507 static const char *alc880_models
[ALC880_MODEL_LAST
] = {
2508 [ALC880_3ST
] = "3stack",
2509 [ALC880_TCL_S700
] = "tcl",
2510 [ALC880_3ST_DIG
] = "3stack-digout",
2511 [ALC880_CLEVO
] = "clevo",
2512 [ALC880_5ST
] = "5stack",
2513 [ALC880_5ST_DIG
] = "5stack-digout",
2514 [ALC880_W810
] = "w810",
2515 [ALC880_Z71V
] = "z71v",
2516 [ALC880_6ST
] = "6stack",
2517 [ALC880_6ST_DIG
] = "6stack-digout",
2518 [ALC880_ASUS
] = "asus",
2519 [ALC880_ASUS_W1V
] = "asus-w1v",
2520 [ALC880_ASUS_DIG
] = "asus-dig",
2521 [ALC880_ASUS_DIG2
] = "asus-dig2",
2522 [ALC880_UNIWILL_DIG
] = "uniwill",
2523 [ALC880_UNIWILL_P53
] = "uniwill-p53",
2524 [ALC880_FUJITSU
] = "fujitsu",
2525 [ALC880_F1734
] = "F1734",
2527 [ALC880_LG_LW
] = "lg-lw",
2528 #ifdef CONFIG_SND_DEBUG
2529 [ALC880_TEST
] = "test",
2531 [ALC880_AUTO
] = "auto",
2534 static struct snd_pci_quirk alc880_cfg_tbl
[] = {
2535 /* Broken BIOS configuration */
2536 SND_PCI_QUIRK(0x2668, 0x8086, NULL
, ALC880_6ST_DIG
),
2537 SND_PCI_QUIRK(0x8086, 0x2668, NULL
, ALC880_6ST_DIG
),
2539 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG
),
2540 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST
),
2541 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810
),
2542 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG
),
2543 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG
),
2544 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG
),
2545 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG
),
2546 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG
),
2547 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST
),
2549 SND_PCI_QUIRK(0x1039, 0x1234, NULL
, ALC880_6ST_DIG
),
2550 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST
),
2552 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V
),
2553 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG
),
2554 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG
),
2555 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG
),
2556 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG
),
2557 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG
),
2558 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V
),
2559 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2560 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG
),
2561 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG
),
2562 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS
),
2563 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG
),
2564 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST
),
2565 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST
),
2566 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS
),
2568 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST
),
2569 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST
),
2570 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST
),
2571 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST
),
2572 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST
),
2573 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO
),
2574 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO
),
2575 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG
),
2576 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810
),
2577 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG
),
2578 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700
),
2579 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG
),
2580 SND_PCI_QUIRK(0xe803, 0x1019, NULL
, ALC880_6ST_DIG
),
2581 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG
),
2582 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG
),
2583 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG
),
2584 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG
),
2585 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2
),
2587 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG
),
2588 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL
),
2589 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53
),
2590 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734
),
2592 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG
),
2593 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL
),
2594 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734
),
2595 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU
),
2597 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG
),
2598 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG
),
2599 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW
),
2600 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW
),
2602 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG
),
2603 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG
),
2604 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG
),
2605 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG
),
2606 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG
),
2607 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG
),
2608 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG
),
2609 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG
),
2610 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG
),
2611 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG
),
2612 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST
),
2618 * ALC880 codec presets
2620 static struct alc_config_preset alc880_presets
[] = {
2622 .mixers
= { alc880_three_stack_mixer
},
2623 .init_verbs
= { alc880_volume_init_verbs
,
2624 alc880_pin_3stack_init_verbs
},
2625 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2626 .dac_nids
= alc880_dac_nids
,
2627 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
2628 .channel_mode
= alc880_threestack_modes
,
2630 .input_mux
= &alc880_capture_source
,
2632 [ALC880_3ST_DIG
] = {
2633 .mixers
= { alc880_three_stack_mixer
},
2634 .init_verbs
= { alc880_volume_init_verbs
,
2635 alc880_pin_3stack_init_verbs
},
2636 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2637 .dac_nids
= alc880_dac_nids
,
2638 .dig_out_nid
= ALC880_DIGOUT_NID
,
2639 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
2640 .channel_mode
= alc880_threestack_modes
,
2642 .input_mux
= &alc880_capture_source
,
2644 [ALC880_TCL_S700
] = {
2645 .mixers
= { alc880_tcl_s700_mixer
},
2646 .init_verbs
= { alc880_volume_init_verbs
,
2647 alc880_pin_tcl_S700_init_verbs
,
2648 alc880_gpio2_init_verbs
},
2649 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2650 .dac_nids
= alc880_dac_nids
,
2652 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
2653 .channel_mode
= alc880_2_jack_modes
,
2654 .input_mux
= &alc880_capture_source
,
2657 .mixers
= { alc880_three_stack_mixer
,
2658 alc880_five_stack_mixer
},
2659 .init_verbs
= { alc880_volume_init_verbs
,
2660 alc880_pin_5stack_init_verbs
},
2661 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2662 .dac_nids
= alc880_dac_nids
,
2663 .num_channel_mode
= ARRAY_SIZE(alc880_fivestack_modes
),
2664 .channel_mode
= alc880_fivestack_modes
,
2665 .input_mux
= &alc880_capture_source
,
2667 [ALC880_5ST_DIG
] = {
2668 .mixers
= { alc880_three_stack_mixer
,
2669 alc880_five_stack_mixer
},
2670 .init_verbs
= { alc880_volume_init_verbs
,
2671 alc880_pin_5stack_init_verbs
},
2672 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2673 .dac_nids
= alc880_dac_nids
,
2674 .dig_out_nid
= ALC880_DIGOUT_NID
,
2675 .num_channel_mode
= ARRAY_SIZE(alc880_fivestack_modes
),
2676 .channel_mode
= alc880_fivestack_modes
,
2677 .input_mux
= &alc880_capture_source
,
2680 .mixers
= { alc880_six_stack_mixer
},
2681 .init_verbs
= { alc880_volume_init_verbs
,
2682 alc880_pin_6stack_init_verbs
},
2683 .num_dacs
= ARRAY_SIZE(alc880_6st_dac_nids
),
2684 .dac_nids
= alc880_6st_dac_nids
,
2685 .num_channel_mode
= ARRAY_SIZE(alc880_sixstack_modes
),
2686 .channel_mode
= alc880_sixstack_modes
,
2687 .input_mux
= &alc880_6stack_capture_source
,
2689 [ALC880_6ST_DIG
] = {
2690 .mixers
= { alc880_six_stack_mixer
},
2691 .init_verbs
= { alc880_volume_init_verbs
,
2692 alc880_pin_6stack_init_verbs
},
2693 .num_dacs
= ARRAY_SIZE(alc880_6st_dac_nids
),
2694 .dac_nids
= alc880_6st_dac_nids
,
2695 .dig_out_nid
= ALC880_DIGOUT_NID
,
2696 .num_channel_mode
= ARRAY_SIZE(alc880_sixstack_modes
),
2697 .channel_mode
= alc880_sixstack_modes
,
2698 .input_mux
= &alc880_6stack_capture_source
,
2701 .mixers
= { alc880_w810_base_mixer
},
2702 .init_verbs
= { alc880_volume_init_verbs
,
2703 alc880_pin_w810_init_verbs
,
2704 alc880_gpio2_init_verbs
},
2705 .num_dacs
= ARRAY_SIZE(alc880_w810_dac_nids
),
2706 .dac_nids
= alc880_w810_dac_nids
,
2707 .dig_out_nid
= ALC880_DIGOUT_NID
,
2708 .num_channel_mode
= ARRAY_SIZE(alc880_w810_modes
),
2709 .channel_mode
= alc880_w810_modes
,
2710 .input_mux
= &alc880_capture_source
,
2713 .mixers
= { alc880_z71v_mixer
},
2714 .init_verbs
= { alc880_volume_init_verbs
,
2715 alc880_pin_z71v_init_verbs
},
2716 .num_dacs
= ARRAY_SIZE(alc880_z71v_dac_nids
),
2717 .dac_nids
= alc880_z71v_dac_nids
,
2718 .dig_out_nid
= ALC880_DIGOUT_NID
,
2720 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
2721 .channel_mode
= alc880_2_jack_modes
,
2722 .input_mux
= &alc880_capture_source
,
2725 .mixers
= { alc880_f1734_mixer
},
2726 .init_verbs
= { alc880_volume_init_verbs
,
2727 alc880_pin_f1734_init_verbs
},
2728 .num_dacs
= ARRAY_SIZE(alc880_f1734_dac_nids
),
2729 .dac_nids
= alc880_f1734_dac_nids
,
2731 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
2732 .channel_mode
= alc880_2_jack_modes
,
2733 .input_mux
= &alc880_capture_source
,
2736 .mixers
= { alc880_asus_mixer
},
2737 .init_verbs
= { alc880_volume_init_verbs
,
2738 alc880_pin_asus_init_verbs
,
2739 alc880_gpio1_init_verbs
},
2740 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2741 .dac_nids
= alc880_asus_dac_nids
,
2742 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
2743 .channel_mode
= alc880_asus_modes
,
2745 .input_mux
= &alc880_capture_source
,
2747 [ALC880_ASUS_DIG
] = {
2748 .mixers
= { alc880_asus_mixer
},
2749 .init_verbs
= { alc880_volume_init_verbs
,
2750 alc880_pin_asus_init_verbs
,
2751 alc880_gpio1_init_verbs
},
2752 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2753 .dac_nids
= alc880_asus_dac_nids
,
2754 .dig_out_nid
= ALC880_DIGOUT_NID
,
2755 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
2756 .channel_mode
= alc880_asus_modes
,
2758 .input_mux
= &alc880_capture_source
,
2760 [ALC880_ASUS_DIG2
] = {
2761 .mixers
= { alc880_asus_mixer
},
2762 .init_verbs
= { alc880_volume_init_verbs
,
2763 alc880_pin_asus_init_verbs
,
2764 alc880_gpio2_init_verbs
}, /* use GPIO2 */
2765 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2766 .dac_nids
= alc880_asus_dac_nids
,
2767 .dig_out_nid
= ALC880_DIGOUT_NID
,
2768 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
2769 .channel_mode
= alc880_asus_modes
,
2771 .input_mux
= &alc880_capture_source
,
2773 [ALC880_ASUS_W1V
] = {
2774 .mixers
= { alc880_asus_mixer
, alc880_asus_w1v_mixer
},
2775 .init_verbs
= { alc880_volume_init_verbs
,
2776 alc880_pin_asus_init_verbs
,
2777 alc880_gpio1_init_verbs
},
2778 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2779 .dac_nids
= alc880_asus_dac_nids
,
2780 .dig_out_nid
= ALC880_DIGOUT_NID
,
2781 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
2782 .channel_mode
= alc880_asus_modes
,
2784 .input_mux
= &alc880_capture_source
,
2786 [ALC880_UNIWILL_DIG
] = {
2787 .mixers
= { alc880_asus_mixer
, alc880_pcbeep_mixer
},
2788 .init_verbs
= { alc880_volume_init_verbs
,
2789 alc880_pin_asus_init_verbs
},
2790 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2791 .dac_nids
= alc880_asus_dac_nids
,
2792 .dig_out_nid
= ALC880_DIGOUT_NID
,
2793 .num_channel_mode
= ARRAY_SIZE(alc880_asus_modes
),
2794 .channel_mode
= alc880_asus_modes
,
2796 .input_mux
= &alc880_capture_source
,
2798 [ALC880_UNIWILL
] = {
2799 .mixers
= { alc880_uniwill_mixer
},
2800 .init_verbs
= { alc880_volume_init_verbs
,
2801 alc880_uniwill_init_verbs
},
2802 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2803 .dac_nids
= alc880_asus_dac_nids
,
2804 .dig_out_nid
= ALC880_DIGOUT_NID
,
2805 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
2806 .channel_mode
= alc880_threestack_modes
,
2808 .input_mux
= &alc880_capture_source
,
2809 .unsol_event
= alc880_uniwill_unsol_event
,
2810 .init_hook
= alc880_uniwill_automute
,
2812 [ALC880_UNIWILL_P53
] = {
2813 .mixers
= { alc880_uniwill_p53_mixer
},
2814 .init_verbs
= { alc880_volume_init_verbs
,
2815 alc880_uniwill_p53_init_verbs
},
2816 .num_dacs
= ARRAY_SIZE(alc880_asus_dac_nids
),
2817 .dac_nids
= alc880_asus_dac_nids
,
2818 .num_channel_mode
= ARRAY_SIZE(alc880_w810_modes
),
2819 .channel_mode
= alc880_threestack_modes
,
2820 .input_mux
= &alc880_capture_source
,
2821 .unsol_event
= alc880_uniwill_p53_unsol_event
,
2822 .init_hook
= alc880_uniwill_p53_hp_automute
,
2824 [ALC880_FUJITSU
] = {
2825 .mixers
= { alc880_fujitsu_mixer
,
2826 alc880_pcbeep_mixer
, },
2827 .init_verbs
= { alc880_volume_init_verbs
,
2828 alc880_uniwill_p53_init_verbs
,
2829 alc880_beep_init_verbs
},
2830 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2831 .dac_nids
= alc880_dac_nids
,
2832 .num_channel_mode
= ARRAY_SIZE(alc880_2_jack_modes
),
2833 .channel_mode
= alc880_2_jack_modes
,
2834 .input_mux
= &alc880_capture_source
,
2835 .unsol_event
= alc880_uniwill_p53_unsol_event
,
2836 .init_hook
= alc880_uniwill_p53_hp_automute
,
2839 .mixers
= { alc880_three_stack_mixer
},
2840 .init_verbs
= { alc880_volume_init_verbs
,
2841 alc880_pin_clevo_init_verbs
},
2842 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2843 .dac_nids
= alc880_dac_nids
,
2845 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
2846 .channel_mode
= alc880_threestack_modes
,
2848 .input_mux
= &alc880_capture_source
,
2851 .mixers
= { alc880_lg_mixer
},
2852 .init_verbs
= { alc880_volume_init_verbs
,
2853 alc880_lg_init_verbs
},
2854 .num_dacs
= ARRAY_SIZE(alc880_lg_dac_nids
),
2855 .dac_nids
= alc880_lg_dac_nids
,
2856 .dig_out_nid
= ALC880_DIGOUT_NID
,
2857 .num_channel_mode
= ARRAY_SIZE(alc880_lg_ch_modes
),
2858 .channel_mode
= alc880_lg_ch_modes
,
2860 .input_mux
= &alc880_lg_capture_source
,
2861 .unsol_event
= alc880_lg_unsol_event
,
2862 .init_hook
= alc880_lg_automute
,
2865 .mixers
= { alc880_lg_lw_mixer
},
2866 .init_verbs
= { alc880_volume_init_verbs
,
2867 alc880_lg_lw_init_verbs
},
2868 .num_dacs
= ARRAY_SIZE(alc880_dac_nids
),
2869 .dac_nids
= alc880_dac_nids
,
2870 .dig_out_nid
= ALC880_DIGOUT_NID
,
2871 .num_channel_mode
= ARRAY_SIZE(alc880_lg_lw_modes
),
2872 .channel_mode
= alc880_lg_lw_modes
,
2873 .input_mux
= &alc880_lg_lw_capture_source
,
2874 .unsol_event
= alc880_lg_lw_unsol_event
,
2875 .init_hook
= alc880_lg_lw_automute
,
2877 #ifdef CONFIG_SND_DEBUG
2879 .mixers
= { alc880_test_mixer
},
2880 .init_verbs
= { alc880_test_init_verbs
},
2881 .num_dacs
= ARRAY_SIZE(alc880_test_dac_nids
),
2882 .dac_nids
= alc880_test_dac_nids
,
2883 .dig_out_nid
= ALC880_DIGOUT_NID
,
2884 .num_channel_mode
= ARRAY_SIZE(alc880_test_modes
),
2885 .channel_mode
= alc880_test_modes
,
2886 .input_mux
= &alc880_test_capture_source
,
2892 * Automatic parse of I/O pins from the BIOS configuration
2895 #define NUM_CONTROL_ALLOC 32
2896 #define NUM_VERB_ALLOC 32
2900 ALC_CTL_WIDGET_MUTE
,
2903 static struct snd_kcontrol_new alc880_control_templates
[] = {
2904 HDA_CODEC_VOLUME(NULL
, 0, 0, 0),
2905 HDA_CODEC_MUTE(NULL
, 0, 0, 0),
2906 HDA_BIND_MUTE(NULL
, 0, 0, 0),
2909 /* add dynamic controls */
2910 static int add_control(struct alc_spec
*spec
, int type
, const char *name
,
2913 struct snd_kcontrol_new
*knew
;
2915 if (spec
->num_kctl_used
>= spec
->num_kctl_alloc
) {
2916 int num
= spec
->num_kctl_alloc
+ NUM_CONTROL_ALLOC
;
2918 /* array + terminator */
2919 knew
= kcalloc(num
+ 1, sizeof(*knew
), GFP_KERNEL
);
2922 if (spec
->kctl_alloc
) {
2923 memcpy(knew
, spec
->kctl_alloc
,
2924 sizeof(*knew
) * spec
->num_kctl_alloc
);
2925 kfree(spec
->kctl_alloc
);
2927 spec
->kctl_alloc
= knew
;
2928 spec
->num_kctl_alloc
= num
;
2931 knew
= &spec
->kctl_alloc
[spec
->num_kctl_used
];
2932 *knew
= alc880_control_templates
[type
];
2933 knew
->name
= kstrdup(name
, GFP_KERNEL
);
2936 knew
->private_value
= val
;
2937 spec
->num_kctl_used
++;
2941 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
2942 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
2943 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
2944 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
2945 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
2946 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
2947 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
2948 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
2949 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
2950 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
2951 #define ALC880_PIN_CD_NID 0x1c
2953 /* fill in the dac_nids table from the parsed pin configuration */
2954 static int alc880_auto_fill_dac_nids(struct alc_spec
*spec
,
2955 const struct auto_pin_cfg
*cfg
)
2961 memset(assigned
, 0, sizeof(assigned
));
2962 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
2964 /* check the pins hardwired to audio widget */
2965 for (i
= 0; i
< cfg
->line_outs
; i
++) {
2966 nid
= cfg
->line_out_pins
[i
];
2967 if (alc880_is_fixed_pin(nid
)) {
2968 int idx
= alc880_fixed_pin_idx(nid
);
2969 spec
->multiout
.dac_nids
[i
] = alc880_idx_to_dac(idx
);
2973 /* left pins can be connect to any audio widget */
2974 for (i
= 0; i
< cfg
->line_outs
; i
++) {
2975 nid
= cfg
->line_out_pins
[i
];
2976 if (alc880_is_fixed_pin(nid
))
2978 /* search for an empty channel */
2979 for (j
= 0; j
< cfg
->line_outs
; j
++) {
2981 spec
->multiout
.dac_nids
[i
] =
2982 alc880_idx_to_dac(j
);
2988 spec
->multiout
.num_dacs
= cfg
->line_outs
;
2992 /* add playback controls from the parsed DAC table */
2993 static int alc880_auto_create_multi_out_ctls(struct alc_spec
*spec
,
2994 const struct auto_pin_cfg
*cfg
)
2997 static const char *chname
[4] = {
2998 "Front", "Surround", NULL
/*CLFE*/, "Side"
3003 for (i
= 0; i
< cfg
->line_outs
; i
++) {
3004 if (!spec
->multiout
.dac_nids
[i
])
3006 nid
= alc880_idx_to_mixer(alc880_dac_to_idx(spec
->multiout
.dac_nids
[i
]));
3009 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
3010 "Center Playback Volume",
3011 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
3015 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
3016 "LFE Playback Volume",
3017 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
3021 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
3022 "Center Playback Switch",
3023 HDA_COMPOSE_AMP_VAL(nid
, 1, 2,
3027 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
3028 "LFE Playback Switch",
3029 HDA_COMPOSE_AMP_VAL(nid
, 2, 2,
3034 sprintf(name
, "%s Playback Volume", chname
[i
]);
3035 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
3036 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
3040 sprintf(name
, "%s Playback Switch", chname
[i
]);
3041 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
3042 HDA_COMPOSE_AMP_VAL(nid
, 3, 2,
3051 /* add playback controls for speaker and HP outputs */
3052 static int alc880_auto_create_extra_out(struct alc_spec
*spec
, hda_nid_t pin
,
3062 if (alc880_is_fixed_pin(pin
)) {
3063 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
3064 /* specify the DAC as the extra output */
3065 if (!spec
->multiout
.hp_nid
)
3066 spec
->multiout
.hp_nid
= nid
;
3068 spec
->multiout
.extra_out_nid
[0] = nid
;
3069 /* control HP volume/switch on the output mixer amp */
3070 nid
= alc880_idx_to_mixer(alc880_fixed_pin_idx(pin
));
3071 sprintf(name
, "%s Playback Volume", pfx
);
3072 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
3073 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
3076 sprintf(name
, "%s Playback Switch", pfx
);
3077 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
3078 HDA_COMPOSE_AMP_VAL(nid
, 3, 2, HDA_INPUT
));
3081 } else if (alc880_is_multi_pin(pin
)) {
3082 /* set manual connection */
3083 /* we have only a switch on HP-out PIN */
3084 sprintf(name
, "%s Playback Switch", pfx
);
3085 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
3086 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
3093 /* create input playback/capture controls for the given pin */
3094 static int new_analog_input(struct alc_spec
*spec
, hda_nid_t pin
,
3095 const char *ctlname
,
3096 int idx
, hda_nid_t mix_nid
)
3101 sprintf(name
, "%s Playback Volume", ctlname
);
3102 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
3103 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
3106 sprintf(name
, "%s Playback Switch", ctlname
);
3107 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
3108 HDA_COMPOSE_AMP_VAL(mix_nid
, 3, idx
, HDA_INPUT
));
3114 /* create playback/capture controls for input pins */
3115 static int alc880_auto_create_analog_input_ctls(struct alc_spec
*spec
,
3116 const struct auto_pin_cfg
*cfg
)
3118 struct hda_input_mux
*imux
= &spec
->private_imux
;
3121 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
3122 if (alc880_is_input_pin(cfg
->input_pins
[i
])) {
3123 idx
= alc880_input_pin_idx(cfg
->input_pins
[i
]);
3124 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
3125 auto_pin_cfg_labels
[i
],
3129 imux
->items
[imux
->num_items
].label
=
3130 auto_pin_cfg_labels
[i
];
3131 imux
->items
[imux
->num_items
].index
=
3132 alc880_input_pin_idx(cfg
->input_pins
[i
]);
3139 static void alc880_auto_set_output_and_unmute(struct hda_codec
*codec
,
3140 hda_nid_t nid
, int pin_type
,
3144 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
3146 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
3148 /* need the manual connection? */
3149 if (alc880_is_multi_pin(nid
)) {
3150 struct alc_spec
*spec
= codec
->spec
;
3151 int idx
= alc880_multi_pin_idx(nid
);
3152 snd_hda_codec_write(codec
, alc880_idx_to_selector(idx
), 0,
3153 AC_VERB_SET_CONNECT_SEL
,
3154 alc880_dac_to_idx(spec
->multiout
.dac_nids
[dac_idx
]));
3158 static int get_pin_type(int line_out_type
)
3160 if (line_out_type
== AUTO_PIN_HP_OUT
)
3166 static void alc880_auto_init_multi_out(struct hda_codec
*codec
)
3168 struct alc_spec
*spec
= codec
->spec
;
3171 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
3172 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
3173 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
3174 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
3175 alc880_auto_set_output_and_unmute(codec
, nid
, pin_type
, i
);
3179 static void alc880_auto_init_extra_out(struct hda_codec
*codec
)
3181 struct alc_spec
*spec
= codec
->spec
;
3184 pin
= spec
->autocfg
.speaker_pins
[0];
3185 if (pin
) /* connect to front */
3186 alc880_auto_set_output_and_unmute(codec
, pin
, PIN_OUT
, 0);
3187 pin
= spec
->autocfg
.hp_pins
[0];
3188 if (pin
) /* connect to front */
3189 alc880_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
3192 static void alc880_auto_init_analog_input(struct hda_codec
*codec
)
3194 struct alc_spec
*spec
= codec
->spec
;
3197 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
3198 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
3199 if (alc880_is_input_pin(nid
)) {
3200 snd_hda_codec_write(codec
, nid
, 0,
3201 AC_VERB_SET_PIN_WIDGET_CONTROL
,
3202 i
<= AUTO_PIN_FRONT_MIC
?
3203 PIN_VREF80
: PIN_IN
);
3204 if (nid
!= ALC880_PIN_CD_NID
)
3205 snd_hda_codec_write(codec
, nid
, 0,
3206 AC_VERB_SET_AMP_GAIN_MUTE
,
3212 /* parse the BIOS configuration and set up the alc_spec */
3213 /* return 1 if successful, 0 if the proper config is not found,
3214 * or a negative error code
3216 static int alc880_parse_auto_config(struct hda_codec
*codec
)
3218 struct alc_spec
*spec
= codec
->spec
;
3220 static hda_nid_t alc880_ignore
[] = { 0x1d, 0 };
3222 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
3226 if (!spec
->autocfg
.line_outs
)
3227 return 0; /* can't find valid BIOS pin config */
3229 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
3232 err
= alc880_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
3235 err
= alc880_auto_create_extra_out(spec
,
3236 spec
->autocfg
.speaker_pins
[0],
3240 err
= alc880_auto_create_extra_out(spec
, spec
->autocfg
.hp_pins
[0],
3244 err
= alc880_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
3248 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
3250 if (spec
->autocfg
.dig_out_pin
)
3251 spec
->multiout
.dig_out_nid
= ALC880_DIGOUT_NID
;
3252 if (spec
->autocfg
.dig_in_pin
)
3253 spec
->dig_in_nid
= ALC880_DIGIN_NID
;
3255 if (spec
->kctl_alloc
)
3256 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
3258 spec
->init_verbs
[spec
->num_init_verbs
++] = alc880_volume_init_verbs
;
3260 spec
->num_mux_defs
= 1;
3261 spec
->input_mux
= &spec
->private_imux
;
3266 /* additional initialization for auto-configuration model */
3267 static void alc880_auto_init(struct hda_codec
*codec
)
3269 alc880_auto_init_multi_out(codec
);
3270 alc880_auto_init_extra_out(codec
);
3271 alc880_auto_init_analog_input(codec
);
3275 * OK, here we have finally the patch for ALC880
3278 static int patch_alc880(struct hda_codec
*codec
)
3280 struct alc_spec
*spec
;
3284 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
3290 board_config
= snd_hda_check_board_config(codec
, ALC880_MODEL_LAST
,
3293 if (board_config
< 0) {
3294 printk(KERN_INFO
"hda_codec: Unknown model for ALC880, "
3295 "trying auto-probe from BIOS...\n");
3296 board_config
= ALC880_AUTO
;
3299 if (board_config
== ALC880_AUTO
) {
3300 /* automatic parse from the BIOS config */
3301 err
= alc880_parse_auto_config(codec
);
3307 "hda_codec: Cannot set up configuration "
3308 "from BIOS. Using 3-stack mode...\n");
3309 board_config
= ALC880_3ST
;
3313 if (board_config
!= ALC880_AUTO
)
3314 setup_preset(spec
, &alc880_presets
[board_config
]);
3316 spec
->stream_name_analog
= "ALC880 Analog";
3317 spec
->stream_analog_playback
= &alc880_pcm_analog_playback
;
3318 spec
->stream_analog_capture
= &alc880_pcm_analog_capture
;
3320 spec
->stream_name_digital
= "ALC880 Digital";
3321 spec
->stream_digital_playback
= &alc880_pcm_digital_playback
;
3322 spec
->stream_digital_capture
= &alc880_pcm_digital_capture
;
3324 if (!spec
->adc_nids
&& spec
->input_mux
) {
3325 /* check whether NID 0x07 is valid */
3326 unsigned int wcap
= get_wcaps(codec
, alc880_adc_nids
[0]);
3328 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
3329 if (wcap
!= AC_WID_AUD_IN
) {
3330 spec
->adc_nids
= alc880_adc_nids_alt
;
3331 spec
->num_adc_nids
= ARRAY_SIZE(alc880_adc_nids_alt
);
3332 spec
->mixers
[spec
->num_mixers
] =
3333 alc880_capture_alt_mixer
;
3336 spec
->adc_nids
= alc880_adc_nids
;
3337 spec
->num_adc_nids
= ARRAY_SIZE(alc880_adc_nids
);
3338 spec
->mixers
[spec
->num_mixers
] = alc880_capture_mixer
;
3343 codec
->patch_ops
= alc_patch_ops
;
3344 if (board_config
== ALC880_AUTO
)
3345 spec
->init_hook
= alc880_auto_init
;
3355 static hda_nid_t alc260_dac_nids
[1] = {
3360 static hda_nid_t alc260_adc_nids
[1] = {
3365 static hda_nid_t alc260_adc_nids_alt
[1] = {
3370 static hda_nid_t alc260_hp_adc_nids
[2] = {
3375 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
3376 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3378 static hda_nid_t alc260_dual_adc_nids
[2] = {
3383 #define ALC260_DIGOUT_NID 0x03
3384 #define ALC260_DIGIN_NID 0x06
3386 static struct hda_input_mux alc260_capture_source
= {
3390 { "Front Mic", 0x1 },
3396 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3397 * headphone jack and the internal CD lines since these are the only pins at
3398 * which audio can appear. For flexibility, also allow the option of
3399 * recording the mixer output on the second ADC (ADC0 doesn't have a
3400 * connection to the mixer output).
3402 static struct hda_input_mux alc260_fujitsu_capture_sources
[2] = {
3406 { "Mic/Line", 0x0 },
3408 { "Headphone", 0x2 },
3414 { "Mic/Line", 0x0 },
3416 { "Headphone", 0x2 },
3423 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3424 * the Fujitsu S702x, but jacks are marked differently.
3426 static struct hda_input_mux alc260_acer_capture_sources
[2] = {
3433 { "Headphone", 0x5 },
3442 { "Headphone", 0x6 },
3448 * This is just place-holder, so there's something for alc_build_pcms to look
3449 * at when it calculates the maximum number of channels. ALC260 has no mixer
3450 * element which allows changing the channel mode, so the verb list is
3453 static struct hda_channel_mode alc260_modes
[1] = {
3458 /* Mixer combinations
3460 * basic: base_output + input + pc_beep + capture
3461 * HP: base_output + input + capture_alt
3462 * HP_3013: hp_3013 + input + capture
3463 * fujitsu: fujitsu + capture
3464 * acer: acer + capture
3467 static struct snd_kcontrol_new alc260_base_output_mixer
[] = {
3468 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3469 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT
),
3470 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
3471 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT
),
3472 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
3473 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT
),
3477 static struct snd_kcontrol_new alc260_input_mixer
[] = {
3478 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
3479 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
3480 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
3481 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
3482 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
3483 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
3484 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT
),
3485 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT
),
3489 static struct snd_kcontrol_new alc260_pc_beep_mixer
[] = {
3490 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT
),
3491 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT
),
3495 static struct snd_kcontrol_new alc260_hp_3013_mixer
[] = {
3496 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
3497 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT
),
3498 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT
),
3499 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT
),
3500 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3501 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
3502 HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
3503 HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT
),
3507 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
3508 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
3510 static struct snd_kcontrol_new alc260_fujitsu_mixer
[] = {
3511 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3512 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT
),
3513 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
3514 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
3515 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
3516 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT
),
3517 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT
),
3518 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN
),
3519 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT
),
3520 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT
),
3521 HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
3522 HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT
),
3526 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
3527 * versions of the ALC260 don't act on requests to enable mic bias from NID
3528 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
3529 * datasheet doesn't mention this restriction. At this stage it's not clear
3530 * whether this behaviour is intentional or is a hardware bug in chip
3531 * revisions available in early 2006. Therefore for now allow the
3532 * "Headphone Jack Mode" control to span all choices, but if it turns out
3533 * that the lack of mic bias for this NID is intentional we could change the
3534 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3536 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3537 * don't appear to make the mic bias available from the "line" jack, even
3538 * though the NID used for this jack (0x14) can supply it. The theory is
3539 * that perhaps Acer have included blocking capacitors between the ALC260
3540 * and the output jack. If this turns out to be the case for all such
3541 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3542 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3544 * The C20x Tablet series have a mono internal speaker which is controlled
3545 * via the chip's Mono sum widget and pin complex, so include the necessary
3546 * controls for such models. On models without a "mono speaker" the control
3547 * won't do anything.
3549 static struct snd_kcontrol_new alc260_acer_mixer
[] = {
3550 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3551 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT
),
3552 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT
),
3553 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3555 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3557 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
3558 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
3559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
3560 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
3561 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
3562 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
3563 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
3564 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
3565 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT
),
3566 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT
),
3570 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3571 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
3573 static struct snd_kcontrol_new alc260_will_mixer
[] = {
3574 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3575 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT
),
3576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
3577 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
3578 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
3579 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
3580 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
3581 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
3582 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
3583 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
3584 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT
),
3585 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT
),
3589 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3590 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3592 static struct snd_kcontrol_new alc260_replacer_672v_mixer
[] = {
3593 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
3594 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT
),
3595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT
),
3596 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT
),
3597 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN
),
3598 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT
),
3599 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT
),
3600 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT
),
3601 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT
),
3602 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT
),
3606 /* capture mixer elements */
3607 static struct snd_kcontrol_new alc260_capture_mixer
[] = {
3608 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT
),
3609 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT
),
3610 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT
),
3611 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT
),
3613 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3614 /* The multiple "Capture Source" controls confuse alsamixer
3615 * So call somewhat different..
3616 * FIXME: the controls appear in the "playback" view!
3618 /* .name = "Capture Source", */
3619 .name
= "Input Source",
3621 .info
= alc_mux_enum_info
,
3622 .get
= alc_mux_enum_get
,
3623 .put
= alc_mux_enum_put
,
3628 static struct snd_kcontrol_new alc260_capture_alt_mixer
[] = {
3629 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT
),
3630 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT
),
3632 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
3633 /* The multiple "Capture Source" controls confuse alsamixer
3634 * So call somewhat different..
3635 * FIXME: the controls appear in the "playback" view!
3637 /* .name = "Capture Source", */
3638 .name
= "Input Source",
3640 .info
= alc_mux_enum_info
,
3641 .get
= alc_mux_enum_get
,
3642 .put
= alc_mux_enum_put
,
3648 * initialization verbs
3650 static struct hda_verb alc260_init_verbs
[] = {
3651 /* Line In pin widget for input */
3652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3653 /* CD pin widget for input */
3654 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3655 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3656 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
3657 /* Mic2 (front panel) pin widget for input and vref at 80% */
3658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
3659 /* LINE-2 is used for line-out in rear */
3660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3661 /* select line-out */
3662 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00},
3664 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3666 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
3668 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3669 /* mute capture amp left and right */
3670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3671 /* set connection select to line in (default select for this ADC) */
3672 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
3673 /* mute capture amp left and right */
3674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3675 /* set connection select to line in (default select for this ADC) */
3676 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x02},
3677 /* set vol=0 Line-Out mixer amp left and right */
3678 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3679 /* unmute pin widget amp left and right (no gain on this amp) */
3680 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3681 /* set vol=0 HP mixer amp left and right */
3682 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3683 /* unmute pin widget amp left and right (no gain on this amp) */
3684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3685 /* set vol=0 Mono mixer amp left and right */
3686 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3687 /* unmute pin widget amp left and right (no gain on this amp) */
3688 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3689 /* unmute LINE-2 out pin */
3690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3691 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
3697 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
3699 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3700 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3701 /* mute Front out path */
3702 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3704 /* mute Headphone out path */
3705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3707 /* mute Mono out path */
3708 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3713 #if 0 /* should be identical with alc260_init_verbs? */
3714 static struct hda_verb alc260_hp_init_verbs
[] = {
3715 /* Headphone and output */
3716 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
3718 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
3719 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3720 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
3721 /* Mic2 (front panel) pin widget for input and vref at 80% */
3722 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
3723 /* Line In pin widget for input */
3724 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
3725 /* Line-2 pin widget for output */
3726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
3727 /* CD pin widget for input */
3728 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
3729 /* unmute amp left and right */
3730 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000},
3731 /* set connection select to line in (default select for this ADC) */
3732 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
3733 /* unmute Line-Out mixer amp left and right (volume = 0) */
3734 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
3735 /* mute pin widget amp left and right (no gain on this amp) */
3736 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
3737 /* unmute HP mixer amp left and right (volume = 0) */
3738 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
3739 /* mute pin widget amp left and right (no gain on this amp) */
3740 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
3741 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
3746 /* unmute Line In */
3747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
3749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3750 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3751 /* Unmute Front out path */
3752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3754 /* Unmute Headphone out path */
3755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3757 /* Unmute Mono out path */
3758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3764 static struct hda_verb alc260_hp_3013_init_verbs
[] = {
3765 /* Line out and output */
3766 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
3768 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
3769 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3770 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
3771 /* Mic2 (front panel) pin widget for input and vref at 80% */
3772 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
3773 /* Line In pin widget for input */
3774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
3775 /* Headphone pin widget for output */
3776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
3777 /* CD pin widget for input */
3778 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
3779 /* unmute amp left and right */
3780 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000},
3781 /* set connection select to line in (default select for this ADC) */
3782 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x02},
3783 /* unmute Line-Out mixer amp left and right (volume = 0) */
3784 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
3785 /* mute pin widget amp left and right (no gain on this amp) */
3786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
3787 /* unmute HP mixer amp left and right (volume = 0) */
3788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb000},
3789 /* mute pin widget amp left and right (no gain on this amp) */
3790 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
3791 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3795 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
3796 /* unmute Line In */
3797 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
3799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3800 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3801 /* Unmute Front out path */
3802 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3803 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3804 /* Unmute Headphone out path */
3805 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3806 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3807 /* Unmute Mono out path */
3808 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
3809 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
3813 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
3814 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
3815 * audio = 0x16, internal speaker = 0x10.
3817 static struct hda_verb alc260_fujitsu_init_verbs
[] = {
3818 /* Disable all GPIOs */
3819 {0x01, AC_VERB_SET_GPIO_MASK
, 0},
3820 /* Internal speaker is connected to headphone pin */
3821 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
3822 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
3823 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
3824 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
3825 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3826 /* Ensure all other unused pins are disabled and muted. */
3827 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3828 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3829 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3830 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3831 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3832 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3834 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3836 /* Disable digital (SPDIF) pins */
3837 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
3838 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
3840 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
3841 * when acting as an output.
3843 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
3845 /* Start with output sum widgets muted and their output gains at min */
3846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3847 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3848 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3849 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3850 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3851 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3852 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3853 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3854 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3856 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
3857 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3858 /* Unmute Line1 pin widget output buffer since it starts as an output.
3859 * If the pin mode is changed by the user the pin mode control will
3860 * take care of enabling the pin's input/output buffers as needed.
3861 * Therefore there's no need to enable the input buffer at this
3864 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3865 /* Unmute input buffer of pin widget used for Line-in (no equiv
3868 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3870 /* Mute capture amp left and right */
3871 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3872 /* Set ADC connection select to match default mixer setting - line
3875 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
3877 /* Do the same for the second ADC: mute capture input amp and
3878 * set ADC connection to line in (on mic1 pin)
3880 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3881 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
3883 /* Mute all inputs to mixer widget (even unconnected ones) */
3884 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
3885 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
3886 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
3887 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
3888 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
3889 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3890 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
3891 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
3896 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
3897 * similar laptops (adapted from Fujitsu init verbs).
3899 static struct hda_verb alc260_acer_init_verbs
[] = {
3900 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
3901 * the headphone jack. Turn this on and rely on the standard mute
3902 * methods whenever the user wants to turn these outputs off.
3904 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
3905 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
3906 {0x01, AC_VERB_SET_GPIO_DATA
, 0x01},
3907 /* Internal speaker/Headphone jack is connected to Line-out pin */
3908 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
3909 /* Internal microphone/Mic jack is connected to Mic1 pin */
3910 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
3911 /* Line In jack is connected to Line1 pin */
3912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
3913 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3914 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
3915 /* Ensure all other unused pins are disabled and muted. */
3916 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3917 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3918 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3919 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3920 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0},
3921 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3922 /* Disable digital (SPDIF) pins */
3923 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
3924 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
3926 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
3927 * bus when acting as outputs.
3929 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0},
3930 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
3932 /* Start with output sum widgets muted and their output gains at min */
3933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3934 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3935 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3937 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3938 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3939 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3940 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
3941 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
3943 /* Unmute Line-out pin widget amp left and right
3944 * (no equiv mixer ctrl)
3946 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3947 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3948 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
3949 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3950 * inputs. If the pin mode is changed by the user the pin mode control
3951 * will take care of enabling the pin's input/output buffers as needed.
3952 * Therefore there's no need to enable the input buffer at this
3955 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
3958 /* Mute capture amp left and right */
3959 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3960 /* Set ADC connection select to match default mixer setting - mic
3963 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
3965 /* Do similar with the second ADC: mute capture input amp and
3966 * set ADC connection to mic to match ALSA's default state.
3968 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
3969 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
3971 /* Mute all inputs to mixer widget (even unconnected ones) */
3972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
3973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
3974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
3975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
3976 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
3977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
3978 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
3979 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
3984 static struct hda_verb alc260_will_verbs
[] = {
3985 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
3986 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00},
3987 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00},
3988 {0x0f, AC_VERB_SET_EAPD_BTLENABLE
, 0x02},
3989 {0x1a, AC_VERB_SET_COEF_INDEX
, 0x07},
3990 {0x1a, AC_VERB_SET_PROC_COEF
, 0x3040},
3994 static struct hda_verb alc260_replacer_672v_verbs
[] = {
3995 {0x0f, AC_VERB_SET_EAPD_BTLENABLE
, 0x02},
3996 {0x1a, AC_VERB_SET_COEF_INDEX
, 0x07},
3997 {0x1a, AC_VERB_SET_PROC_COEF
, 0x3050},
3999 {0x01, AC_VERB_SET_GPIO_MASK
, 0x01},
4000 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x01},
4001 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
4003 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
4007 /* toggle speaker-output according to the hp-jack state */
4008 static void alc260_replacer_672v_automute(struct hda_codec
*codec
)
4010 unsigned int present
;
4012 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4013 present
= snd_hda_codec_read(codec
, 0x0f, 0,
4014 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
4016 snd_hda_codec_write_cache(codec
, 0x01, 0,
4017 AC_VERB_SET_GPIO_DATA
, 1);
4018 snd_hda_codec_write_cache(codec
, 0x0f, 0,
4019 AC_VERB_SET_PIN_WIDGET_CONTROL
,
4022 snd_hda_codec_write_cache(codec
, 0x01, 0,
4023 AC_VERB_SET_GPIO_DATA
, 0);
4024 snd_hda_codec_write_cache(codec
, 0x0f, 0,
4025 AC_VERB_SET_PIN_WIDGET_CONTROL
,
4030 static void alc260_replacer_672v_unsol_event(struct hda_codec
*codec
,
4033 if ((res
>> 26) == ALC880_HP_EVENT
)
4034 alc260_replacer_672v_automute(codec
);
4037 /* Test configuration for debugging, modelled after the ALC880 test
4040 #ifdef CONFIG_SND_DEBUG
4041 static hda_nid_t alc260_test_dac_nids
[1] = {
4044 static hda_nid_t alc260_test_adc_nids
[2] = {
4047 /* For testing the ALC260, each input MUX needs its own definition since
4048 * the signal assignments are different. This assumes that the first ADC
4051 static struct hda_input_mux alc260_test_capture_sources
[2] = {
4055 { "MIC1 pin", 0x0 },
4056 { "MIC2 pin", 0x1 },
4057 { "LINE1 pin", 0x2 },
4058 { "LINE2 pin", 0x3 },
4060 { "LINE-OUT pin", 0x5 },
4061 { "HP-OUT pin", 0x6 },
4067 { "MIC1 pin", 0x0 },
4068 { "MIC2 pin", 0x1 },
4069 { "LINE1 pin", 0x2 },
4070 { "LINE2 pin", 0x3 },
4073 { "LINE-OUT pin", 0x6 },
4074 { "HP-OUT pin", 0x7 },
4078 static struct snd_kcontrol_new alc260_test_mixer
[] = {
4079 /* Output driver widgets */
4080 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT
),
4081 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT
),
4082 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT
),
4083 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT
),
4084 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT
),
4085 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT
),
4087 /* Modes for retasking pin widgets
4088 * Note: the ALC260 doesn't seem to act on requests to enable mic
4089 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4090 * mention this restriction. At this stage it's not clear whether
4091 * this behaviour is intentional or is a hardware bug in chip
4092 * revisions available at least up until early 2006. Therefore for
4093 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4094 * choices, but if it turns out that the lack of mic bias for these
4095 * NIDs is intentional we could change their modes from
4096 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4098 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT
),
4099 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT
),
4100 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT
),
4101 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT
),
4102 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT
),
4103 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT
),
4105 /* Loopback mixer controls */
4106 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT
),
4107 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT
),
4108 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT
),
4109 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT
),
4110 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT
),
4111 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT
),
4112 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT
),
4113 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT
),
4114 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT
),
4115 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT
),
4116 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT
),
4117 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT
),
4118 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT
),
4119 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT
),
4120 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT
),
4121 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT
),
4123 /* Controls for GPIO pins, assuming they are configured as outputs */
4124 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4125 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4126 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4127 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4129 /* Switches to allow the digital IO pins to be enabled. The datasheet
4130 * is ambigious as to which NID is which; testing on laptops which
4131 * make this output available should provide clarification.
4133 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4134 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4138 static struct hda_verb alc260_test_init_verbs
[] = {
4139 /* Enable all GPIOs as outputs with an initial value of 0 */
4140 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x0f},
4141 {0x01, AC_VERB_SET_GPIO_DATA
, 0x00},
4142 {0x01, AC_VERB_SET_GPIO_MASK
, 0x0f},
4144 /* Enable retasking pins as output, initially without power amp */
4145 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4146 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4149 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4150 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4152 /* Disable digital (SPDIF) pins initially, but users can enable
4153 * them via a mixer switch. In the case of SPDIF-out, this initverb
4154 * payload also sets the generation to 0, output to be in "consumer"
4155 * PCM format, copyright asserted, no pre-emphasis and no validity
4158 {0x03, AC_VERB_SET_DIGI_CONVERT_1
, 0},
4159 {0x06, AC_VERB_SET_DIGI_CONVERT_1
, 0},
4161 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
4162 * OUT1 sum bus when acting as an output.
4164 {0x0b, AC_VERB_SET_CONNECT_SEL
, 0},
4165 {0x0c, AC_VERB_SET_CONNECT_SEL
, 0},
4166 {0x0d, AC_VERB_SET_CONNECT_SEL
, 0},
4167 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0},
4169 /* Start with output sum widgets muted and their output gains at min */
4170 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4171 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4173 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4174 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4176 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4177 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4178 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4180 /* Unmute retasking pin widget output buffers since the default
4181 * state appears to be output. As the pin mode is changed by the
4182 * user the pin mode control will take care of enabling the pin's
4183 * input/output buffers as needed.
4185 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4186 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4189 {0x13, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4190 {0x12, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4191 /* Also unmute the mono-out pin widget */
4192 {0x11, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4194 /* Mute capture amp left and right */
4195 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4196 /* Set ADC connection select to match default mixer setting (mic1
4199 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
4201 /* Do the same for the second ADC: mute capture input amp and
4202 * set ADC connection to mic1 pin
4204 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4205 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
4207 /* Mute all inputs to mixer widget (even unconnected ones) */
4208 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)}, /* mic1 pin */
4209 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)}, /* mic2 pin */
4210 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)}, /* line1 pin */
4211 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)}, /* line2 pin */
4212 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)}, /* CD pin */
4213 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(6)}, /* Line-out pin */
4215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(7)}, /* HP-pin pin */
4221 static struct hda_pcm_stream alc260_pcm_analog_playback
= {
4227 static struct hda_pcm_stream alc260_pcm_analog_capture
= {
4233 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
4234 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
4237 * for BIOS auto-configuration
4240 static int alc260_add_playback_controls(struct alc_spec
*spec
, hda_nid_t nid
,
4244 unsigned long vol_val
, sw_val
;
4248 if (nid
>= 0x0f && nid
< 0x11) {
4249 nid_vol
= nid
- 0x7;
4250 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
);
4251 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
);
4252 } else if (nid
== 0x11) {
4253 nid_vol
= nid
- 0x7;
4254 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 2, 0, HDA_OUTPUT
);
4255 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_OUTPUT
);
4256 } else if (nid
>= 0x12 && nid
<= 0x15) {
4258 vol_val
= HDA_COMPOSE_AMP_VAL(nid_vol
, 3, 0, HDA_OUTPUT
);
4259 sw_val
= HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
);
4263 snprintf(name
, sizeof(name
), "%s Playback Volume", pfx
);
4264 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
, vol_val
);
4267 snprintf(name
, sizeof(name
), "%s Playback Switch", pfx
);
4268 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
, sw_val
);
4274 /* add playback controls from the parsed DAC table */
4275 static int alc260_auto_create_multi_out_ctls(struct alc_spec
*spec
,
4276 const struct auto_pin_cfg
*cfg
)
4281 spec
->multiout
.num_dacs
= 1;
4282 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
4283 spec
->multiout
.dac_nids
[0] = 0x02;
4285 nid
= cfg
->line_out_pins
[0];
4287 err
= alc260_add_playback_controls(spec
, nid
, "Front");
4292 nid
= cfg
->speaker_pins
[0];
4294 err
= alc260_add_playback_controls(spec
, nid
, "Speaker");
4299 nid
= cfg
->hp_pins
[0];
4301 err
= alc260_add_playback_controls(spec
, nid
, "Headphone");
4308 /* create playback/capture controls for input pins */
4309 static int alc260_auto_create_analog_input_ctls(struct alc_spec
*spec
,
4310 const struct auto_pin_cfg
*cfg
)
4312 struct hda_input_mux
*imux
= &spec
->private_imux
;
4315 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
4316 if (cfg
->input_pins
[i
] >= 0x12) {
4317 idx
= cfg
->input_pins
[i
] - 0x12;
4318 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
4319 auto_pin_cfg_labels
[i
], idx
,
4323 imux
->items
[imux
->num_items
].label
=
4324 auto_pin_cfg_labels
[i
];
4325 imux
->items
[imux
->num_items
].index
= idx
;
4328 if (cfg
->input_pins
[i
] >= 0x0f && cfg
->input_pins
[i
] <= 0x10){
4329 idx
= cfg
->input_pins
[i
] - 0x09;
4330 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
4331 auto_pin_cfg_labels
[i
], idx
,
4335 imux
->items
[imux
->num_items
].label
=
4336 auto_pin_cfg_labels
[i
];
4337 imux
->items
[imux
->num_items
].index
= idx
;
4344 static void alc260_auto_set_output_and_unmute(struct hda_codec
*codec
,
4345 hda_nid_t nid
, int pin_type
,
4349 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
4351 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
4353 /* need the manual connection? */
4355 int idx
= nid
- 0x12;
4356 snd_hda_codec_write(codec
, idx
+ 0x0b, 0,
4357 AC_VERB_SET_CONNECT_SEL
, sel_idx
);
4361 static void alc260_auto_init_multi_out(struct hda_codec
*codec
)
4363 struct alc_spec
*spec
= codec
->spec
;
4366 alc_subsystem_id(codec
, 0x10, 0x15, 0x0f);
4367 nid
= spec
->autocfg
.line_out_pins
[0];
4369 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
4370 alc260_auto_set_output_and_unmute(codec
, nid
, pin_type
, 0);
4373 nid
= spec
->autocfg
.speaker_pins
[0];
4375 alc260_auto_set_output_and_unmute(codec
, nid
, PIN_OUT
, 0);
4377 nid
= spec
->autocfg
.hp_pins
[0];
4379 alc260_auto_set_output_and_unmute(codec
, nid
, PIN_HP
, 0);
4382 #define ALC260_PIN_CD_NID 0x16
4383 static void alc260_auto_init_analog_input(struct hda_codec
*codec
)
4385 struct alc_spec
*spec
= codec
->spec
;
4388 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
4389 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
4391 snd_hda_codec_write(codec
, nid
, 0,
4392 AC_VERB_SET_PIN_WIDGET_CONTROL
,
4393 i
<= AUTO_PIN_FRONT_MIC
?
4394 PIN_VREF80
: PIN_IN
);
4395 if (nid
!= ALC260_PIN_CD_NID
)
4396 snd_hda_codec_write(codec
, nid
, 0,
4397 AC_VERB_SET_AMP_GAIN_MUTE
,
4404 * generic initialization of ADC, input mixers and output mixers
4406 static struct hda_verb alc260_volume_init_verbs
[] = {
4408 * Unmute ADC0-1 and set the default input to mic-in
4410 {0x04, AC_VERB_SET_CONNECT_SEL
, 0x00},
4411 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4412 {0x05, AC_VERB_SET_CONNECT_SEL
, 0x00},
4413 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4415 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4417 * Note: PASD motherboards uses the Line In 2 as the input for
4418 * front panel mic (mic 2)
4420 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4421 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4422 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
4423 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
4424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
4425 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
4428 * Set up output mixers (0x08 - 0x0a)
4430 /* set vol=0 to output mixers */
4431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4433 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4434 /* set up input amps for analog loopback */
4435 /* Amp Indices: DAC = 0, mixer = 1 */
4436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4437 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
4438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4439 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
4440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4441 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
4446 static int alc260_parse_auto_config(struct hda_codec
*codec
)
4448 struct alc_spec
*spec
= codec
->spec
;
4451 static hda_nid_t alc260_ignore
[] = { 0x17, 0 };
4453 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
4457 err
= alc260_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
4460 if (!spec
->kctl_alloc
)
4461 return 0; /* can't find valid BIOS pin config */
4462 err
= alc260_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
4466 spec
->multiout
.max_channels
= 2;
4468 if (spec
->autocfg
.dig_out_pin
)
4469 spec
->multiout
.dig_out_nid
= ALC260_DIGOUT_NID
;
4470 if (spec
->kctl_alloc
)
4471 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
4473 spec
->init_verbs
[spec
->num_init_verbs
++] = alc260_volume_init_verbs
;
4475 spec
->num_mux_defs
= 1;
4476 spec
->input_mux
= &spec
->private_imux
;
4478 /* check whether NID 0x04 is valid */
4479 wcap
= get_wcaps(codec
, 0x04);
4480 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
; /* get type */
4481 if (wcap
!= AC_WID_AUD_IN
) {
4482 spec
->adc_nids
= alc260_adc_nids_alt
;
4483 spec
->num_adc_nids
= ARRAY_SIZE(alc260_adc_nids_alt
);
4484 spec
->mixers
[spec
->num_mixers
] = alc260_capture_alt_mixer
;
4486 spec
->adc_nids
= alc260_adc_nids
;
4487 spec
->num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
);
4488 spec
->mixers
[spec
->num_mixers
] = alc260_capture_mixer
;
4495 /* additional initialization for auto-configuration model */
4496 static void alc260_auto_init(struct hda_codec
*codec
)
4498 alc260_auto_init_multi_out(codec
);
4499 alc260_auto_init_analog_input(codec
);
4503 * ALC260 configurations
4505 static const char *alc260_models
[ALC260_MODEL_LAST
] = {
4506 [ALC260_BASIC
] = "basic",
4508 [ALC260_HP_3013
] = "hp-3013",
4509 [ALC260_FUJITSU_S702X
] = "fujitsu",
4510 [ALC260_ACER
] = "acer",
4511 [ALC260_WILL
] = "will",
4512 [ALC260_REPLACER_672V
] = "replacer",
4513 #ifdef CONFIG_SND_DEBUG
4514 [ALC260_TEST
] = "test",
4516 [ALC260_AUTO
] = "auto",
4519 static struct snd_pci_quirk alc260_cfg_tbl
[] = {
4520 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER
),
4521 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER
),
4522 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013
),
4523 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013
),
4524 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013
),
4525 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP
),
4526 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013
),
4527 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013
),
4528 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP
),
4529 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP
),
4530 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP
),
4531 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC
),
4532 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC
),
4533 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC
),
4534 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X
),
4535 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC
),
4536 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL
),
4537 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V
),
4541 static struct alc_config_preset alc260_presets
[] = {
4543 .mixers
= { alc260_base_output_mixer
,
4545 alc260_pc_beep_mixer
,
4546 alc260_capture_mixer
},
4547 .init_verbs
= { alc260_init_verbs
},
4548 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4549 .dac_nids
= alc260_dac_nids
,
4550 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
),
4551 .adc_nids
= alc260_adc_nids
,
4552 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4553 .channel_mode
= alc260_modes
,
4554 .input_mux
= &alc260_capture_source
,
4557 .mixers
= { alc260_base_output_mixer
,
4559 alc260_capture_alt_mixer
},
4560 .init_verbs
= { alc260_init_verbs
},
4561 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4562 .dac_nids
= alc260_dac_nids
,
4563 .num_adc_nids
= ARRAY_SIZE(alc260_hp_adc_nids
),
4564 .adc_nids
= alc260_hp_adc_nids
,
4565 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4566 .channel_mode
= alc260_modes
,
4567 .input_mux
= &alc260_capture_source
,
4569 [ALC260_HP_3013
] = {
4570 .mixers
= { alc260_hp_3013_mixer
,
4572 alc260_capture_alt_mixer
},
4573 .init_verbs
= { alc260_hp_3013_init_verbs
},
4574 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4575 .dac_nids
= alc260_dac_nids
,
4576 .num_adc_nids
= ARRAY_SIZE(alc260_hp_adc_nids
),
4577 .adc_nids
= alc260_hp_adc_nids
,
4578 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4579 .channel_mode
= alc260_modes
,
4580 .input_mux
= &alc260_capture_source
,
4582 [ALC260_FUJITSU_S702X
] = {
4583 .mixers
= { alc260_fujitsu_mixer
,
4584 alc260_capture_mixer
},
4585 .init_verbs
= { alc260_fujitsu_init_verbs
},
4586 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4587 .dac_nids
= alc260_dac_nids
,
4588 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
4589 .adc_nids
= alc260_dual_adc_nids
,
4590 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4591 .channel_mode
= alc260_modes
,
4592 .num_mux_defs
= ARRAY_SIZE(alc260_fujitsu_capture_sources
),
4593 .input_mux
= alc260_fujitsu_capture_sources
,
4596 .mixers
= { alc260_acer_mixer
,
4597 alc260_capture_mixer
},
4598 .init_verbs
= { alc260_acer_init_verbs
},
4599 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4600 .dac_nids
= alc260_dac_nids
,
4601 .num_adc_nids
= ARRAY_SIZE(alc260_dual_adc_nids
),
4602 .adc_nids
= alc260_dual_adc_nids
,
4603 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4604 .channel_mode
= alc260_modes
,
4605 .num_mux_defs
= ARRAY_SIZE(alc260_acer_capture_sources
),
4606 .input_mux
= alc260_acer_capture_sources
,
4609 .mixers
= { alc260_will_mixer
,
4610 alc260_capture_mixer
},
4611 .init_verbs
= { alc260_init_verbs
, alc260_will_verbs
},
4612 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4613 .dac_nids
= alc260_dac_nids
,
4614 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
),
4615 .adc_nids
= alc260_adc_nids
,
4616 .dig_out_nid
= ALC260_DIGOUT_NID
,
4617 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4618 .channel_mode
= alc260_modes
,
4619 .input_mux
= &alc260_capture_source
,
4621 [ALC260_REPLACER_672V
] = {
4622 .mixers
= { alc260_replacer_672v_mixer
,
4623 alc260_capture_mixer
},
4624 .init_verbs
= { alc260_init_verbs
, alc260_replacer_672v_verbs
},
4625 .num_dacs
= ARRAY_SIZE(alc260_dac_nids
),
4626 .dac_nids
= alc260_dac_nids
,
4627 .num_adc_nids
= ARRAY_SIZE(alc260_adc_nids
),
4628 .adc_nids
= alc260_adc_nids
,
4629 .dig_out_nid
= ALC260_DIGOUT_NID
,
4630 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4631 .channel_mode
= alc260_modes
,
4632 .input_mux
= &alc260_capture_source
,
4633 .unsol_event
= alc260_replacer_672v_unsol_event
,
4634 .init_hook
= alc260_replacer_672v_automute
,
4636 #ifdef CONFIG_SND_DEBUG
4638 .mixers
= { alc260_test_mixer
,
4639 alc260_capture_mixer
},
4640 .init_verbs
= { alc260_test_init_verbs
},
4641 .num_dacs
= ARRAY_SIZE(alc260_test_dac_nids
),
4642 .dac_nids
= alc260_test_dac_nids
,
4643 .num_adc_nids
= ARRAY_SIZE(alc260_test_adc_nids
),
4644 .adc_nids
= alc260_test_adc_nids
,
4645 .num_channel_mode
= ARRAY_SIZE(alc260_modes
),
4646 .channel_mode
= alc260_modes
,
4647 .num_mux_defs
= ARRAY_SIZE(alc260_test_capture_sources
),
4648 .input_mux
= alc260_test_capture_sources
,
4653 static int patch_alc260(struct hda_codec
*codec
)
4655 struct alc_spec
*spec
;
4656 int err
, board_config
;
4658 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
4664 board_config
= snd_hda_check_board_config(codec
, ALC260_MODEL_LAST
,
4667 if (board_config
< 0) {
4668 snd_printd(KERN_INFO
"hda_codec: Unknown model for ALC260, "
4669 "trying auto-probe from BIOS...\n");
4670 board_config
= ALC260_AUTO
;
4673 if (board_config
== ALC260_AUTO
) {
4674 /* automatic parse from the BIOS config */
4675 err
= alc260_parse_auto_config(codec
);
4681 "hda_codec: Cannot set up configuration "
4682 "from BIOS. Using base mode...\n");
4683 board_config
= ALC260_BASIC
;
4687 if (board_config
!= ALC260_AUTO
)
4688 setup_preset(spec
, &alc260_presets
[board_config
]);
4690 spec
->stream_name_analog
= "ALC260 Analog";
4691 spec
->stream_analog_playback
= &alc260_pcm_analog_playback
;
4692 spec
->stream_analog_capture
= &alc260_pcm_analog_capture
;
4694 spec
->stream_name_digital
= "ALC260 Digital";
4695 spec
->stream_digital_playback
= &alc260_pcm_digital_playback
;
4696 spec
->stream_digital_capture
= &alc260_pcm_digital_capture
;
4698 codec
->patch_ops
= alc_patch_ops
;
4699 if (board_config
== ALC260_AUTO
)
4700 spec
->init_hook
= alc260_auto_init
;
4709 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4710 * configuration. Each pin widget can choose any input DACs and a mixer.
4711 * Each ADC is connected from a mixer of all inputs. This makes possible
4712 * 6-channel independent captures.
4714 * In addition, an independent DAC for the multi-playback (not used in this
4717 #define ALC882_DIGOUT_NID 0x06
4718 #define ALC882_DIGIN_NID 0x0a
4720 static struct hda_channel_mode alc882_ch_modes
[1] = {
4724 static hda_nid_t alc882_dac_nids
[4] = {
4725 /* front, rear, clfe, rear_surr */
4726 0x02, 0x03, 0x04, 0x05
4729 /* identical with ALC880 */
4730 #define alc882_adc_nids alc880_adc_nids
4731 #define alc882_adc_nids_alt alc880_adc_nids_alt
4734 /* FIXME: should be a matrix-type input source selection */
4736 static struct hda_input_mux alc882_capture_source
= {
4740 { "Front Mic", 0x1 },
4745 #define alc882_mux_enum_info alc_mux_enum_info
4746 #define alc882_mux_enum_get alc_mux_enum_get
4748 static int alc882_mux_enum_put(struct snd_kcontrol
*kcontrol
,
4749 struct snd_ctl_elem_value
*ucontrol
)
4751 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
4752 struct alc_spec
*spec
= codec
->spec
;
4753 const struct hda_input_mux
*imux
= spec
->input_mux
;
4754 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
4755 static hda_nid_t capture_mixers
[3] = { 0x24, 0x23, 0x22 };
4756 hda_nid_t nid
= capture_mixers
[adc_idx
];
4757 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
4758 unsigned int i
, idx
;
4760 idx
= ucontrol
->value
.enumerated
.item
[0];
4761 if (idx
>= imux
->num_items
)
4762 idx
= imux
->num_items
- 1;
4763 if (*cur_val
== idx
)
4765 for (i
= 0; i
< imux
->num_items
; i
++) {
4766 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
4767 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
4768 imux
->items
[i
].index
,
4778 static struct hda_verb alc882_3ST_ch2_init
[] = {
4779 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
4780 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
4781 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
4782 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
4789 static struct hda_verb alc882_3ST_ch6_init
[] = {
4790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4792 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
4793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4795 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
4799 static struct hda_channel_mode alc882_3ST_6ch_modes
[2] = {
4800 { 2, alc882_3ST_ch2_init
},
4801 { 6, alc882_3ST_ch6_init
},
4807 static struct hda_verb alc882_sixstack_ch6_init
[] = {
4808 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
4809 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4810 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4811 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4818 static struct hda_verb alc882_sixstack_ch8_init
[] = {
4819 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4820 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4821 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4822 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4826 static struct hda_channel_mode alc882_sixstack_modes
[2] = {
4827 { 6, alc882_sixstack_ch6_init
},
4828 { 8, alc882_sixstack_ch8_init
},
4831 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4832 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4834 static struct snd_kcontrol_new alc882_base_mixer
[] = {
4835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
4836 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
4837 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
4838 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
4839 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
4840 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
4841 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
4842 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
4843 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
4844 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
4845 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
4846 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
4847 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
4848 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
4849 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
4850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
4851 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
4852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
4853 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
4854 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
4855 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
4856 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
4857 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
4861 static struct snd_kcontrol_new alc882_w2jc_mixer
[] = {
4862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
4863 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
4864 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
4865 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
4866 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
4867 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
4868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
4869 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
4870 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
4871 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
4872 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
4876 static struct snd_kcontrol_new alc882_targa_mixer
[] = {
4877 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
4878 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
4879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
4880 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
4881 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
4882 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
4883 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
4884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
4885 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
4886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
4887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
4891 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
4892 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
4894 static struct snd_kcontrol_new alc882_asus_a7j_mixer
[] = {
4895 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
4896 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
4897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
4898 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT
),
4899 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
4900 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
4901 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
4902 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
4903 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT
),
4904 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT
),
4905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
4906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
4910 static struct snd_kcontrol_new alc882_chmode_mixer
[] = {
4912 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
4913 .name
= "Channel Mode",
4914 .info
= alc_ch_mode_info
,
4915 .get
= alc_ch_mode_get
,
4916 .put
= alc_ch_mode_put
,
4921 static struct hda_verb alc882_init_verbs
[] = {
4922 /* Front mixer: unmute input/output amp left and right (volume = 0) */
4923 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4924 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4925 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4927 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4928 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4929 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4932 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4933 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4935 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
4936 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
4939 /* Front Pin: output 0 (0x0c) */
4940 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4941 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4942 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
4943 /* Rear Pin: output 1 (0x0d) */
4944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4945 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4946 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
4947 /* CLFE Pin: output 2 (0x0e) */
4948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4949 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4950 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
4951 /* Side Pin: output 3 (0x0f) */
4952 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
4953 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4954 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
4955 /* Mic (rear) pin: input vref at 80% */
4956 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
4957 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
4958 /* Front Mic pin: input vref at 80% */
4959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
4960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
4961 /* Line In pin: input */
4962 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
4963 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
4964 /* Line-2 In: Headphone output (output 0 - 0x0c) */
4965 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
4966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
4967 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
4968 /* CD pin widget for input */
4969 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
4971 /* FIXME: use matrix-type input source selection */
4972 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4973 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4977 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
4985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
4986 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
4987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
4988 /* ADC1: mute amp left and right */
4989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4990 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
4991 /* ADC2: mute amp left and right */
4992 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4993 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
4994 /* ADC3: mute amp left and right */
4995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
4996 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
5001 static struct hda_verb alc882_eapd_verbs
[] = {
5002 /* change to EAPD mode */
5003 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
5004 {0x20, AC_VERB_SET_PROC_COEF
, 0x3060},
5009 static struct snd_kcontrol_new alc882_macpro_mixer
[] = {
5010 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5011 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
5012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT
),
5013 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT
),
5014 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT
),
5015 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5016 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5020 static struct hda_verb alc882_macpro_init_verbs
[] = {
5021 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5022 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5023 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
5025 /* Front Pin: output 0 (0x0c) */
5026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5028 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
5029 /* Front Mic pin: input vref at 80% */
5030 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
5031 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
5032 /* Speaker: output */
5033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5034 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5035 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x04},
5036 /* Headphone output (output 0 - 0x0c) */
5037 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5038 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5039 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x00},
5041 /* FIXME: use matrix-type input source selection */
5042 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5043 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5044 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
5046 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
5047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
5049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
5051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
5052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
5054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
5056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
5057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
5058 /* ADC1: mute amp left and right */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5060 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
5061 /* ADC2: mute amp left and right */
5062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5063 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
5064 /* ADC3: mute amp left and right */
5065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
5066 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
5071 /* iMac 24 mixer. */
5072 static struct snd_kcontrol_new alc885_imac24_mixer
[] = {
5073 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT
),
5074 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT
),
5078 /* iMac 24 init verbs. */
5079 static struct hda_verb alc885_imac24_init_verbs
[] = {
5080 /* Internal speakers: output 0 (0x0c) */
5081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5083 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x00},
5084 /* Internal speakers: output 0 (0x0c) */
5085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5087 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x00},
5088 /* Headphone: output 0 (0x0c) */
5089 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5090 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5091 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
5092 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
5093 /* Front Mic: input vref at 80% */
5094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
5095 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
5099 /* Toggle speaker-output according to the hp-jack state */
5100 static void alc885_imac24_automute(struct hda_codec
*codec
)
5102 unsigned int present
;
5104 present
= snd_hda_codec_read(codec
, 0x14, 0,
5105 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
5106 snd_hda_codec_amp_stereo(codec
, 0x18, HDA_OUTPUT
, 0,
5107 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
5108 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_OUTPUT
, 0,
5109 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
5112 /* Processes unsolicited events. */
5113 static void alc885_imac24_unsol_event(struct hda_codec
*codec
,
5116 /* Headphone insertion or removal. */
5117 if ((res
>> 26) == ALC880_HP_EVENT
)
5118 alc885_imac24_automute(codec
);
5121 static struct hda_verb alc882_targa_verbs
[] = {
5122 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5123 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5125 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5126 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5128 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
5129 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
5130 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
5132 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
5133 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
5134 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
5135 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
5139 /* toggle speaker-output according to the hp-jack state */
5140 static void alc882_targa_automute(struct hda_codec
*codec
)
5142 unsigned int present
;
5144 present
= snd_hda_codec_read(codec
, 0x14, 0,
5145 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
5146 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
5147 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
5148 snd_hda_codec_write_cache(codec
, 1, 0, AC_VERB_SET_GPIO_DATA
,
5152 static void alc882_targa_unsol_event(struct hda_codec
*codec
, unsigned int res
)
5154 /* Looks like the unsol event is incompatible with the standard
5155 * definition. 4bit tag is placed at 26 bit!
5157 if (((res
>> 26) == ALC880_HP_EVENT
)) {
5158 alc882_targa_automute(codec
);
5162 static struct hda_verb alc882_asus_a7j_verbs
[] = {
5163 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5164 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5166 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
5167 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5168 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5170 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
5171 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
5172 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front */
5174 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
5175 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
5176 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
5180 static void alc882_gpio_mute(struct hda_codec
*codec
, int pin
, int muted
)
5182 unsigned int gpiostate
, gpiomask
, gpiodir
;
5184 gpiostate
= snd_hda_codec_read(codec
, codec
->afg
, 0,
5185 AC_VERB_GET_GPIO_DATA
, 0);
5188 gpiostate
|= (1 << pin
);
5190 gpiostate
&= ~(1 << pin
);
5192 gpiomask
= snd_hda_codec_read(codec
, codec
->afg
, 0,
5193 AC_VERB_GET_GPIO_MASK
, 0);
5194 gpiomask
|= (1 << pin
);
5196 gpiodir
= snd_hda_codec_read(codec
, codec
->afg
, 0,
5197 AC_VERB_GET_GPIO_DIRECTION
, 0);
5198 gpiodir
|= (1 << pin
);
5201 snd_hda_codec_write(codec
, codec
->afg
, 0,
5202 AC_VERB_SET_GPIO_MASK
, gpiomask
);
5203 snd_hda_codec_write(codec
, codec
->afg
, 0,
5204 AC_VERB_SET_GPIO_DIRECTION
, gpiodir
);
5208 snd_hda_codec_write(codec
, codec
->afg
, 0,
5209 AC_VERB_SET_GPIO_DATA
, gpiostate
);
5213 * generic initialization of ADC, input mixers and output mixers
5215 static struct hda_verb alc882_auto_init_verbs
[] = {
5217 * Unmute ADC0-2 and set the default input to mic-in
5219 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
5220 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5221 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
5222 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5223 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
5224 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5226 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5228 * Note: PASD motherboards uses the Line In 2 as the input for
5229 * front panel mic (mic 2)
5231 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5232 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5233 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5234 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
5235 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
5236 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
5239 * Set up output mixers (0x0c - 0x0f)
5241 /* set vol=0 to output mixers */
5242 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5243 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5244 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5245 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
5246 /* set up input amps for analog loopback */
5247 /* Amp Indices: DAC = 0, mixer = 1 */
5248 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5253 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5254 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5255 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5256 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
5257 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
5259 /* FIXME: use matrix-type input source selection */
5260 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5261 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5262 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
5263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
5264 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
5265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
5267 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
5268 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
5269 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
5270 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
5272 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
5273 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
5274 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
5275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
5280 /* capture mixer elements */
5281 static struct snd_kcontrol_new alc882_capture_alt_mixer
[] = {
5282 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5283 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5284 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
5285 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
5287 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5288 /* The multiple "Capture Source" controls confuse alsamixer
5289 * So call somewhat different..
5290 * FIXME: the controls appear in the "playback" view!
5292 /* .name = "Capture Source", */
5293 .name
= "Input Source",
5295 .info
= alc882_mux_enum_info
,
5296 .get
= alc882_mux_enum_get
,
5297 .put
= alc882_mux_enum_put
,
5302 static struct snd_kcontrol_new alc882_capture_mixer
[] = {
5303 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT
),
5304 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT
),
5305 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT
),
5306 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT
),
5307 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT
),
5308 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT
),
5310 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5311 /* The multiple "Capture Source" controls confuse alsamixer
5312 * So call somewhat different..
5313 * FIXME: the controls appear in the "playback" view!
5315 /* .name = "Capture Source", */
5316 .name
= "Input Source",
5318 .info
= alc882_mux_enum_info
,
5319 .get
= alc882_mux_enum_get
,
5320 .put
= alc882_mux_enum_put
,
5325 /* pcm configuration: identiacal with ALC880 */
5326 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
5327 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
5328 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
5329 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
5332 * configuration and preset
5334 static const char *alc882_models
[ALC882_MODEL_LAST
] = {
5335 [ALC882_3ST_DIG
] = "3stack-dig",
5336 [ALC882_6ST_DIG
] = "6stack-dig",
5337 [ALC882_ARIMA
] = "arima",
5338 [ALC882_W2JC
] = "w2jc",
5339 [ALC885_MACPRO
] = "macpro",
5340 [ALC885_IMAC24
] = "imac24",
5341 [ALC882_AUTO
] = "auto",
5344 static struct snd_pci_quirk alc882_cfg_tbl
[] = {
5345 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG
),
5346 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG
),
5347 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG
),
5348 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA
), /* MSI-1049 T8 */
5349 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA
),
5350 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J
),
5351 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG
),
5352 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG
),
5353 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC
),
5357 static struct alc_config_preset alc882_presets
[] = {
5358 [ALC882_3ST_DIG
] = {
5359 .mixers
= { alc882_base_mixer
},
5360 .init_verbs
= { alc882_init_verbs
},
5361 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5362 .dac_nids
= alc882_dac_nids
,
5363 .dig_out_nid
= ALC882_DIGOUT_NID
,
5364 .dig_in_nid
= ALC882_DIGIN_NID
,
5365 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
5366 .channel_mode
= alc882_ch_modes
,
5368 .input_mux
= &alc882_capture_source
,
5370 [ALC882_6ST_DIG
] = {
5371 .mixers
= { alc882_base_mixer
, alc882_chmode_mixer
},
5372 .init_verbs
= { alc882_init_verbs
},
5373 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5374 .dac_nids
= alc882_dac_nids
,
5375 .dig_out_nid
= ALC882_DIGOUT_NID
,
5376 .dig_in_nid
= ALC882_DIGIN_NID
,
5377 .num_channel_mode
= ARRAY_SIZE(alc882_sixstack_modes
),
5378 .channel_mode
= alc882_sixstack_modes
,
5379 .input_mux
= &alc882_capture_source
,
5382 .mixers
= { alc882_base_mixer
, alc882_chmode_mixer
},
5383 .init_verbs
= { alc882_init_verbs
, alc882_eapd_verbs
},
5384 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5385 .dac_nids
= alc882_dac_nids
,
5386 .num_channel_mode
= ARRAY_SIZE(alc882_sixstack_modes
),
5387 .channel_mode
= alc882_sixstack_modes
,
5388 .input_mux
= &alc882_capture_source
,
5391 .mixers
= { alc882_w2jc_mixer
, alc882_chmode_mixer
},
5392 .init_verbs
= { alc882_init_verbs
, alc882_eapd_verbs
,
5393 alc880_gpio1_init_verbs
},
5394 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5395 .dac_nids
= alc882_dac_nids
,
5396 .num_channel_mode
= ARRAY_SIZE(alc880_threestack_modes
),
5397 .channel_mode
= alc880_threestack_modes
,
5399 .input_mux
= &alc882_capture_source
,
5400 .dig_out_nid
= ALC882_DIGOUT_NID
,
5403 .mixers
= { alc882_macpro_mixer
},
5404 .init_verbs
= { alc882_macpro_init_verbs
},
5405 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5406 .dac_nids
= alc882_dac_nids
,
5407 .dig_out_nid
= ALC882_DIGOUT_NID
,
5408 .dig_in_nid
= ALC882_DIGIN_NID
,
5409 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
5410 .channel_mode
= alc882_ch_modes
,
5411 .input_mux
= &alc882_capture_source
,
5414 .mixers
= { alc885_imac24_mixer
},
5415 .init_verbs
= { alc885_imac24_init_verbs
},
5416 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5417 .dac_nids
= alc882_dac_nids
,
5418 .dig_out_nid
= ALC882_DIGOUT_NID
,
5419 .dig_in_nid
= ALC882_DIGIN_NID
,
5420 .num_channel_mode
= ARRAY_SIZE(alc882_ch_modes
),
5421 .channel_mode
= alc882_ch_modes
,
5422 .input_mux
= &alc882_capture_source
,
5423 .unsol_event
= alc885_imac24_unsol_event
,
5424 .init_hook
= alc885_imac24_automute
,
5427 .mixers
= { alc882_targa_mixer
, alc882_chmode_mixer
,
5428 alc882_capture_mixer
},
5429 .init_verbs
= { alc882_init_verbs
, alc882_targa_verbs
},
5430 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5431 .dac_nids
= alc882_dac_nids
,
5432 .dig_out_nid
= ALC882_DIGOUT_NID
,
5433 .num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
),
5434 .adc_nids
= alc882_adc_nids
,
5435 .num_channel_mode
= ARRAY_SIZE(alc882_3ST_6ch_modes
),
5436 .channel_mode
= alc882_3ST_6ch_modes
,
5438 .input_mux
= &alc882_capture_source
,
5439 .unsol_event
= alc882_targa_unsol_event
,
5440 .init_hook
= alc882_targa_automute
,
5442 [ALC882_ASUS_A7J
] = {
5443 .mixers
= { alc882_asus_a7j_mixer
, alc882_chmode_mixer
,
5444 alc882_capture_mixer
},
5445 .init_verbs
= { alc882_init_verbs
, alc882_asus_a7j_verbs
},
5446 .num_dacs
= ARRAY_SIZE(alc882_dac_nids
),
5447 .dac_nids
= alc882_dac_nids
,
5448 .dig_out_nid
= ALC882_DIGOUT_NID
,
5449 .num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
),
5450 .adc_nids
= alc882_adc_nids
,
5451 .num_channel_mode
= ARRAY_SIZE(alc882_3ST_6ch_modes
),
5452 .channel_mode
= alc882_3ST_6ch_modes
,
5454 .input_mux
= &alc882_capture_source
,
5463 PINFIX_ABIT_AW9D_MAX
5466 static struct alc_pincfg alc882_abit_aw9d_pinfix
[] = {
5467 { 0x15, 0x01080104 }, /* side */
5468 { 0x16, 0x01011012 }, /* rear */
5469 { 0x17, 0x01016011 }, /* clfe */
5473 static const struct alc_pincfg
*alc882_pin_fixes
[] = {
5474 [PINFIX_ABIT_AW9D_MAX
] = alc882_abit_aw9d_pinfix
,
5477 static struct snd_pci_quirk alc882_pinfix_tbl
[] = {
5478 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX
),
5483 * BIOS auto configuration
5485 static void alc882_auto_set_output_and_unmute(struct hda_codec
*codec
,
5486 hda_nid_t nid
, int pin_type
,
5490 struct alc_spec
*spec
= codec
->spec
;
5493 if (spec
->multiout
.dac_nids
[dac_idx
] == 0x25)
5496 idx
= spec
->multiout
.dac_nids
[dac_idx
] - 2;
5498 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
5500 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
5502 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_CONNECT_SEL
, idx
);
5506 static void alc882_auto_init_multi_out(struct hda_codec
*codec
)
5508 struct alc_spec
*spec
= codec
->spec
;
5511 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
5512 for (i
= 0; i
<= HDA_SIDE
; i
++) {
5513 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
5514 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
5516 alc882_auto_set_output_and_unmute(codec
, nid
, pin_type
,
5521 static void alc882_auto_init_hp_out(struct hda_codec
*codec
)
5523 struct alc_spec
*spec
= codec
->spec
;
5526 pin
= spec
->autocfg
.hp_pins
[0];
5527 if (pin
) /* connect to front */
5529 alc882_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
5532 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
5533 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
5535 static void alc882_auto_init_analog_input(struct hda_codec
*codec
)
5537 struct alc_spec
*spec
= codec
->spec
;
5540 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
5541 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
5542 if (alc882_is_input_pin(nid
)) {
5543 snd_hda_codec_write(codec
, nid
, 0,
5544 AC_VERB_SET_PIN_WIDGET_CONTROL
,
5545 i
<= AUTO_PIN_FRONT_MIC
?
5546 PIN_VREF80
: PIN_IN
);
5547 if (nid
!= ALC882_PIN_CD_NID
)
5548 snd_hda_codec_write(codec
, nid
, 0,
5549 AC_VERB_SET_AMP_GAIN_MUTE
,
5555 /* almost identical with ALC880 parser... */
5556 static int alc882_parse_auto_config(struct hda_codec
*codec
)
5558 struct alc_spec
*spec
= codec
->spec
;
5559 int err
= alc880_parse_auto_config(codec
);
5564 /* hack - override the init verbs */
5565 spec
->init_verbs
[0] = alc882_auto_init_verbs
;
5569 /* additional initialization for auto-configuration model */
5570 static void alc882_auto_init(struct hda_codec
*codec
)
5572 alc882_auto_init_multi_out(codec
);
5573 alc882_auto_init_hp_out(codec
);
5574 alc882_auto_init_analog_input(codec
);
5577 static int patch_alc882(struct hda_codec
*codec
)
5579 struct alc_spec
*spec
;
5580 int err
, board_config
;
5582 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
5588 board_config
= snd_hda_check_board_config(codec
, ALC882_MODEL_LAST
,
5592 if (board_config
< 0 || board_config
>= ALC882_MODEL_LAST
) {
5593 /* Pick up systems that don't supply PCI SSID */
5594 switch (codec
->subsystem_id
) {
5595 case 0x106b0c00: /* Mac Pro */
5596 board_config
= ALC885_MACPRO
;
5598 case 0x106b1000: /* iMac 24 */
5599 board_config
= ALC885_IMAC24
;
5602 printk(KERN_INFO
"hda_codec: Unknown model for ALC882, "
5603 "trying auto-probe from BIOS...\n");
5604 board_config
= ALC882_AUTO
;
5608 alc_fix_pincfg(codec
, alc882_pinfix_tbl
, alc882_pin_fixes
);
5610 if (board_config
== ALC882_AUTO
) {
5611 /* automatic parse from the BIOS config */
5612 err
= alc882_parse_auto_config(codec
);
5618 "hda_codec: Cannot set up configuration "
5619 "from BIOS. Using base mode...\n");
5620 board_config
= ALC882_3ST_DIG
;
5624 if (board_config
!= ALC882_AUTO
)
5625 setup_preset(spec
, &alc882_presets
[board_config
]);
5627 if (board_config
== ALC885_MACPRO
|| board_config
== ALC885_IMAC24
) {
5628 alc882_gpio_mute(codec
, 0, 0);
5629 alc882_gpio_mute(codec
, 1, 0);
5632 spec
->stream_name_analog
= "ALC882 Analog";
5633 spec
->stream_analog_playback
= &alc882_pcm_analog_playback
;
5634 spec
->stream_analog_capture
= &alc882_pcm_analog_capture
;
5636 spec
->stream_name_digital
= "ALC882 Digital";
5637 spec
->stream_digital_playback
= &alc882_pcm_digital_playback
;
5638 spec
->stream_digital_capture
= &alc882_pcm_digital_capture
;
5640 if (!spec
->adc_nids
&& spec
->input_mux
) {
5641 /* check whether NID 0x07 is valid */
5642 unsigned int wcap
= get_wcaps(codec
, 0x07);
5644 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
5645 if (wcap
!= AC_WID_AUD_IN
) {
5646 spec
->adc_nids
= alc882_adc_nids_alt
;
5647 spec
->num_adc_nids
= ARRAY_SIZE(alc882_adc_nids_alt
);
5648 spec
->mixers
[spec
->num_mixers
] =
5649 alc882_capture_alt_mixer
;
5652 spec
->adc_nids
= alc882_adc_nids
;
5653 spec
->num_adc_nids
= ARRAY_SIZE(alc882_adc_nids
);
5654 spec
->mixers
[spec
->num_mixers
] = alc882_capture_mixer
;
5659 codec
->patch_ops
= alc_patch_ops
;
5660 if (board_config
== ALC882_AUTO
)
5661 spec
->init_hook
= alc882_auto_init
;
5669 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
5670 * configuration. Each pin widget can choose any input DACs and a mixer.
5671 * Each ADC is connected from a mixer of all inputs. This makes possible
5672 * 6-channel independent captures.
5674 * In addition, an independent DAC for the multi-playback (not used in this
5677 #define ALC883_DIGOUT_NID 0x06
5678 #define ALC883_DIGIN_NID 0x0a
5680 static hda_nid_t alc883_dac_nids
[4] = {
5681 /* front, rear, clfe, rear_surr */
5682 0x02, 0x04, 0x03, 0x05
5685 static hda_nid_t alc883_adc_nids
[2] = {
5691 /* FIXME: should be a matrix-type input source selection */
5693 static struct hda_input_mux alc883_capture_source
= {
5697 { "Front Mic", 0x1 },
5703 static struct hda_input_mux alc883_lenovo_101e_capture_source
= {
5711 static struct hda_input_mux alc883_lenovo_nb0763_capture_source
= {
5721 #define alc883_mux_enum_info alc_mux_enum_info
5722 #define alc883_mux_enum_get alc_mux_enum_get
5724 static int alc883_mux_enum_put(struct snd_kcontrol
*kcontrol
,
5725 struct snd_ctl_elem_value
*ucontrol
)
5727 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
5728 struct alc_spec
*spec
= codec
->spec
;
5729 const struct hda_input_mux
*imux
= spec
->input_mux
;
5730 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
5731 static hda_nid_t capture_mixers
[3] = { 0x24, 0x23, 0x22 };
5732 hda_nid_t nid
= capture_mixers
[adc_idx
];
5733 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
5734 unsigned int i
, idx
;
5736 idx
= ucontrol
->value
.enumerated
.item
[0];
5737 if (idx
>= imux
->num_items
)
5738 idx
= imux
->num_items
- 1;
5739 if (*cur_val
== idx
)
5741 for (i
= 0; i
< imux
->num_items
; i
++) {
5742 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
5743 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
5744 imux
->items
[i
].index
,
5754 static struct hda_channel_mode alc883_3ST_2ch_modes
[1] = {
5761 static struct hda_verb alc883_3ST_ch2_init
[] = {
5762 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
5763 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
5764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
5765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
5772 static struct hda_verb alc883_3ST_ch6_init
[] = {
5773 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5774 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5775 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
5776 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5777 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
5778 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
5782 static struct hda_channel_mode alc883_3ST_6ch_modes
[2] = {
5783 { 2, alc883_3ST_ch2_init
},
5784 { 6, alc883_3ST_ch6_init
},
5790 static struct hda_verb alc883_sixstack_ch6_init
[] = {
5791 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
5792 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5793 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5794 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5801 static struct hda_verb alc883_sixstack_ch8_init
[] = {
5802 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5803 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5804 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5805 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
5809 static struct hda_channel_mode alc883_sixstack_modes
[2] = {
5810 { 6, alc883_sixstack_ch6_init
},
5811 { 8, alc883_sixstack_ch8_init
},
5814 static struct hda_verb alc883_medion_eapd_verbs
[] = {
5815 /* eanable EAPD on medion laptop */
5816 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
5817 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
5821 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5822 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5825 static struct snd_kcontrol_new alc883_base_mixer
[] = {
5826 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5827 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
5828 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
5829 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
5830 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
5831 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
5832 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
5833 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
5834 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
5835 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
5836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
5837 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
5838 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
5839 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5840 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
5842 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
5843 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
5844 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
5845 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
5846 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
5847 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
5848 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
5849 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5850 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5851 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
5852 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
5854 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5855 /* .name = "Capture Source", */
5856 .name
= "Input Source",
5858 .info
= alc883_mux_enum_info
,
5859 .get
= alc883_mux_enum_get
,
5860 .put
= alc883_mux_enum_put
,
5865 static struct snd_kcontrol_new alc883_3ST_2ch_mixer
[] = {
5866 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5867 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
5868 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
5869 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
5870 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
5871 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5872 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
5874 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
5875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
5876 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
5877 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
5878 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
5879 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
5880 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
5881 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5882 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5883 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
5884 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
5886 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5887 /* .name = "Capture Source", */
5888 .name
= "Input Source",
5890 .info
= alc883_mux_enum_info
,
5891 .get
= alc883_mux_enum_get
,
5892 .put
= alc883_mux_enum_put
,
5897 static struct snd_kcontrol_new alc883_3ST_6ch_mixer
[] = {
5898 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5899 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
5900 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
5901 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
5902 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
5903 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
5904 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
5905 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
5906 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
5907 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
5908 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
5909 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5910 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
5912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
5913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
5914 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
5915 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
5916 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
5917 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
5918 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
5919 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5920 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5921 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
5922 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
5924 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5925 /* .name = "Capture Source", */
5926 .name
= "Input Source",
5928 .info
= alc883_mux_enum_info
,
5929 .get
= alc883_mux_enum_get
,
5930 .put
= alc883_mux_enum_put
,
5935 static struct snd_kcontrol_new alc883_fivestack_mixer
[] = {
5936 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5937 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
5938 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
5939 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
5940 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
5941 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
5942 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT
),
5943 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
5944 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
5945 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
5946 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
5947 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5948 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5949 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
5950 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
5951 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
5952 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
5953 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
5954 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
5955 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
5956 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
5957 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5958 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5961 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5962 /* .name = "Capture Source", */
5963 .name
= "Input Source",
5965 .info
= alc883_mux_enum_info
,
5966 .get
= alc883_mux_enum_get
,
5967 .put
= alc883_mux_enum_put
,
5972 static struct snd_kcontrol_new alc883_tagra_mixer
[] = {
5973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
5974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
5975 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
5976 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
5977 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
5978 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT
),
5979 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
5980 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
5981 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
5982 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
5983 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
5984 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
5985 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
5986 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
5987 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
5988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
5989 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
5990 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
5991 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
5992 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
5994 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
5995 /* .name = "Capture Source", */
5996 .name
= "Input Source",
5998 .info
= alc883_mux_enum_info
,
5999 .get
= alc883_mux_enum_get
,
6000 .put
= alc883_mux_enum_put
,
6005 static struct snd_kcontrol_new alc883_tagra_2ch_mixer
[] = {
6006 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
6008 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6012 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6013 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6014 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6015 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6016 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6017 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6019 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6020 /* .name = "Capture Source", */
6021 .name
= "Input Source",
6023 .info
= alc883_mux_enum_info
,
6024 .get
= alc883_mux_enum_get
,
6025 .put
= alc883_mux_enum_put
,
6030 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer
[] = {
6031 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6032 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6033 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
6034 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT
),
6035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6037 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6039 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6040 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6042 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6043 /* .name = "Capture Source", */
6044 .name
= "Input Source",
6046 .info
= alc883_mux_enum_info
,
6047 .get
= alc883_mux_enum_get
,
6048 .put
= alc883_mux_enum_put
,
6053 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer
[] = {
6054 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6055 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT
),
6056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
6057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6060 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6061 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6062 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6063 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6064 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6065 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6066 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6068 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6069 /* .name = "Capture Source", */
6070 .name
= "Input Source",
6072 .info
= alc883_mux_enum_info
,
6073 .get
= alc883_mux_enum_get
,
6074 .put
= alc883_mux_enum_put
,
6079 static struct snd_kcontrol_new alc883_medion_md2_mixer
[] = {
6080 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
6082 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
6083 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6084 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6085 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6086 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6087 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6088 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6089 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6090 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6091 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6092 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6094 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6095 /* .name = "Capture Source", */
6096 .name
= "Input Source",
6098 .info
= alc883_mux_enum_info
,
6099 .get
= alc883_mux_enum_get
,
6100 .put
= alc883_mux_enum_put
,
6105 static struct snd_kcontrol_new alc888_6st_hp_mixer
[] = {
6106 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6107 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6108 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
6109 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT
),
6110 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT
),
6111 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT
),
6112 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT
),
6113 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT
),
6114 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT
),
6115 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
6116 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6117 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6118 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6122 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6124 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6125 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
6126 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6127 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
6128 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
6129 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6130 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6131 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6132 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6134 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6135 /* .name = "Capture Source", */
6136 .name
= "Input Source",
6138 .info
= alc883_mux_enum_info
,
6139 .get
= alc883_mux_enum_get
,
6140 .put
= alc883_mux_enum_put
,
6145 static struct snd_kcontrol_new alc888_3st_hp_mixer
[] = {
6146 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6147 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
6148 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT
),
6149 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT
),
6150 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT
),
6151 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT
),
6152 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT
),
6153 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT
),
6154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
6155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6157 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6158 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6159 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6160 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
6161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6162 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
6163 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
6164 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
6165 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
6166 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
6167 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6168 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6169 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6170 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6172 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6173 /* .name = "Capture Source", */
6174 .name
= "Input Source",
6176 .info
= alc883_mux_enum_info
,
6177 .get
= alc883_mux_enum_get
,
6178 .put
= alc883_mux_enum_put
,
6183 static struct snd_kcontrol_new alc883_acer_aspire_mixer
[] = {
6184 HDA_CODEC_VOLUME("Front Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
6185 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
6186 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
6187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
6188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
6189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
6190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
6191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
6192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
6193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
6194 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6195 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6196 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6197 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6199 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6200 /* .name = "Capture Source", */
6201 .name
= "Input Source",
6203 .info
= alc883_mux_enum_info
,
6204 .get
= alc883_mux_enum_get
,
6205 .put
= alc883_mux_enum_put
,
6210 static struct snd_kcontrol_new alc883_chmode_mixer
[] = {
6212 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6213 .name
= "Channel Mode",
6214 .info
= alc_ch_mode_info
,
6215 .get
= alc_ch_mode_get
,
6216 .put
= alc_ch_mode_put
,
6221 static struct hda_verb alc883_init_verbs
[] = {
6222 /* ADC1: mute amp left and right */
6223 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6224 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6225 /* ADC2: mute amp left and right */
6226 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6227 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6228 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6229 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6230 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6233 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6234 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6235 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6237 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6238 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6239 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6242 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
6243 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
6245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
6249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6251 /* Front Pin: output 0 (0x0c) */
6252 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6253 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6254 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
6255 /* Rear Pin: output 1 (0x0d) */
6256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6258 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
6259 /* CLFE Pin: output 2 (0x0e) */
6260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6262 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
6263 /* Side Pin: output 3 (0x0f) */
6264 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6265 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6266 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
6267 /* Mic (rear) pin: input vref at 80% */
6268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6270 /* Front Mic pin: input vref at 80% */
6271 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6272 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6273 /* Line In pin: input */
6274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6276 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6278 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6279 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
6280 /* CD pin widget for input */
6281 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6283 /* FIXME: use matrix-type input source selection */
6284 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6298 static struct hda_verb alc883_tagra_verbs
[] = {
6299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6305 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* mic/clfe */
6306 {0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* line/surround */
6307 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* HP */
6309 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6310 {0x01, AC_VERB_SET_GPIO_MASK
, 0x03},
6311 {0x01, AC_VERB_SET_GPIO_DIRECTION
, 0x03},
6312 {0x01, AC_VERB_SET_GPIO_DATA
, 0x03},
6317 static struct hda_verb alc883_lenovo_101e_verbs
[] = {
6318 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
6319 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_FRONT_EVENT
|AC_USRSP_EN
},
6320 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
|AC_USRSP_EN
},
6324 static struct hda_verb alc883_lenovo_nb0763_verbs
[] = {
6325 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
6326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6327 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6332 static struct hda_verb alc888_lenovo_ms7195_verbs
[] = {
6333 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6334 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6335 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
6336 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_FRONT_EVENT
| AC_USRSP_EN
},
6337 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6341 static struct hda_verb alc888_6st_hp_verbs
[] = {
6342 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front: output 0 (0x0c) */
6343 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* Rear : output 2 (0x0e) */
6344 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* CLFE : output 1 (0x0d) */
6345 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03}, /* Side : output 3 (0x0f) */
6349 static struct hda_verb alc888_3st_hp_verbs
[] = {
6350 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* Front: output 0 (0x0c) */
6351 {0x18, AC_VERB_SET_CONNECT_SEL
, 0x01}, /* Rear : output 1 (0x0d) */
6352 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02}, /* CLFE : output 2 (0x0e) */
6356 static struct hda_verb alc888_3st_hp_2ch_init
[] = {
6357 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
6358 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6359 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
6360 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
6364 static struct hda_verb alc888_3st_hp_6ch_init
[] = {
6365 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6366 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6367 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
6368 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
6372 static struct hda_channel_mode alc888_3st_hp_modes
[2] = {
6373 { 2, alc888_3st_hp_2ch_init
},
6374 { 6, alc888_3st_hp_6ch_init
},
6377 /* toggle front-jack and RCA according to the hp-jack state */
6378 static void alc888_lenovo_ms7195_front_automute(struct hda_codec
*codec
)
6380 unsigned int present
;
6382 present
= snd_hda_codec_read(codec
, 0x1b, 0,
6383 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6384 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
6385 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6386 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6387 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6390 /* toggle RCA according to the front-jack state */
6391 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec
*codec
)
6393 unsigned int present
;
6395 present
= snd_hda_codec_read(codec
, 0x14, 0,
6396 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6397 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6398 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6401 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec
*codec
,
6404 if ((res
>> 26) == ALC880_HP_EVENT
)
6405 alc888_lenovo_ms7195_front_automute(codec
);
6406 if ((res
>> 26) == ALC880_FRONT_EVENT
)
6407 alc888_lenovo_ms7195_rca_automute(codec
);
6410 static struct hda_verb alc883_medion_md2_verbs
[] = {
6411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6414 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6416 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6420 static struct hda_verb alc883_acer_aspire_verbs
[] = {
6421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
6428 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, ALC880_HP_EVENT
| AC_USRSP_EN
},
6432 /* toggle speaker-output according to the hp-jack state */
6433 static void alc883_medion_md2_automute(struct hda_codec
*codec
)
6435 unsigned int present
;
6437 present
= snd_hda_codec_read(codec
, 0x14, 0,
6438 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6439 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6440 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
6443 static void alc883_medion_md2_unsol_event(struct hda_codec
*codec
,
6446 if ((res
>> 26) == ALC880_HP_EVENT
)
6447 alc883_medion_md2_automute(codec
);
6450 /* toggle speaker-output according to the hp-jack state */
6451 static void alc883_tagra_automute(struct hda_codec
*codec
)
6453 unsigned int present
;
6456 present
= snd_hda_codec_read(codec
, 0x14, 0,
6457 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6458 bits
= present
? HDA_AMP_MUTE
: 0;
6459 snd_hda_codec_amp_stereo(codec
, 0x1b, HDA_OUTPUT
, 0,
6460 HDA_AMP_MUTE
, bits
);
6461 snd_hda_codec_write_cache(codec
, 1, 0, AC_VERB_SET_GPIO_DATA
,
6465 static void alc883_tagra_unsol_event(struct hda_codec
*codec
, unsigned int res
)
6467 if ((res
>> 26) == ALC880_HP_EVENT
)
6468 alc883_tagra_automute(codec
);
6471 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec
*codec
)
6473 unsigned int present
;
6476 present
= snd_hda_codec_read(codec
, 0x14, 0,
6477 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6478 bits
= present
? HDA_AMP_MUTE
: 0;
6479 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6480 HDA_AMP_MUTE
, bits
);
6483 static void alc883_lenovo_101e_all_automute(struct hda_codec
*codec
)
6485 unsigned int present
;
6488 present
= snd_hda_codec_read(codec
, 0x1b, 0,
6489 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
6490 bits
= present
? HDA_AMP_MUTE
: 0;
6491 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
6492 HDA_AMP_MUTE
, bits
);
6493 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
6494 HDA_AMP_MUTE
, bits
);
6497 static void alc883_lenovo_101e_unsol_event(struct hda_codec
*codec
,
6500 if ((res
>> 26) == ALC880_HP_EVENT
)
6501 alc883_lenovo_101e_all_automute(codec
);
6502 if ((res
>> 26) == ALC880_FRONT_EVENT
)
6503 alc883_lenovo_101e_ispeaker_automute(codec
);
6507 * generic initialization of ADC, input mixers and output mixers
6509 static struct hda_verb alc883_auto_init_verbs
[] = {
6511 * Unmute ADC0-2 and set the default input to mic-in
6513 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
6514 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6515 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
6516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6518 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6520 * Note: PASD motherboards uses the Line In 2 as the input for
6521 * front panel mic (mic 2)
6523 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
6528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6531 * Set up output mixers (0x0c - 0x0f)
6533 /* set vol=0 to output mixers */
6534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6537 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
6538 /* set up input amps for analog loopback */
6539 /* Amp Indices: DAC = 0, mixer = 1 */
6540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6543 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6544 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6545 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6546 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6547 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6548 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6549 {0x26, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6551 /* FIXME: use matrix-type input source selection */
6552 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6554 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6555 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6556 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6557 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6560 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
6561 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
6562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
6563 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
6564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
6569 /* capture mixer elements */
6570 static struct snd_kcontrol_new alc883_capture_mixer
[] = {
6571 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
6572 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
6573 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT
),
6574 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT
),
6576 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
6577 /* The multiple "Capture Source" controls confuse alsamixer
6578 * So call somewhat different..
6579 * FIXME: the controls appear in the "playback" view!
6581 /* .name = "Capture Source", */
6582 .name
= "Input Source",
6584 .info
= alc882_mux_enum_info
,
6585 .get
= alc882_mux_enum_get
,
6586 .put
= alc882_mux_enum_put
,
6591 /* pcm configuration: identiacal with ALC880 */
6592 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
6593 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
6594 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
6595 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
6598 * configuration and preset
6600 static const char *alc883_models
[ALC883_MODEL_LAST
] = {
6601 [ALC883_3ST_2ch_DIG
] = "3stack-dig",
6602 [ALC883_3ST_6ch_DIG
] = "3stack-6ch-dig",
6603 [ALC883_3ST_6ch
] = "3stack-6ch",
6604 [ALC883_6ST_DIG
] = "6stack-dig",
6605 [ALC883_TARGA_DIG
] = "targa-dig",
6606 [ALC883_TARGA_2ch_DIG
] = "targa-2ch-dig",
6607 [ALC883_ACER
] = "acer",
6608 [ALC883_ACER_ASPIRE
] = "acer-aspire",
6609 [ALC883_MEDION
] = "medion",
6610 [ALC883_MEDION_MD2
] = "medion-md2",
6611 [ALC883_LAPTOP_EAPD
] = "laptop-eapd",
6612 [ALC883_LENOVO_101E_2ch
] = "lenovo-101e",
6613 [ALC883_LENOVO_NB0763
] = "lenovo-nb0763",
6614 [ALC888_LENOVO_MS7195_DIG
] = "lenovo-ms7195-dig",
6615 [ALC888_6ST_HP
] = "6stack-hp",
6616 [ALC888_3ST_HP
] = "3stack-hp",
6617 [ALC883_AUTO
] = "auto",
6620 static struct snd_pci_quirk alc883_cfg_tbl
[] = {
6621 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG
),
6622 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG
),
6623 SND_PCI_QUIRK(0x108e, 0x534d, NULL
, ALC883_3ST_6ch
),
6624 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD
),
6625 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG
),
6626 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG
),
6627 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG
),
6628 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG
),
6629 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG
),
6630 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG
),
6631 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG
),
6632 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG
),
6633 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG
),
6634 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG
),
6635 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG
),
6636 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG
),
6637 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG
),
6638 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG
),
6639 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG
),
6640 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG
),
6641 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG
),
6642 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG
),
6643 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG
),
6644 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE
),
6645 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER
),
6646 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch
),
6647 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION
),
6648 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD
),
6649 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch
),
6650 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch
),
6651 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763
),
6652 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763
),
6653 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP
),
6654 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP
),
6655 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP
),
6656 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2
),
6660 static struct alc_config_preset alc883_presets
[] = {
6661 [ALC883_3ST_2ch_DIG
] = {
6662 .mixers
= { alc883_3ST_2ch_mixer
},
6663 .init_verbs
= { alc883_init_verbs
},
6664 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6665 .dac_nids
= alc883_dac_nids
,
6666 .dig_out_nid
= ALC883_DIGOUT_NID
,
6667 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6668 .adc_nids
= alc883_adc_nids
,
6669 .dig_in_nid
= ALC883_DIGIN_NID
,
6670 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6671 .channel_mode
= alc883_3ST_2ch_modes
,
6672 .input_mux
= &alc883_capture_source
,
6674 [ALC883_3ST_6ch_DIG
] = {
6675 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
6676 .init_verbs
= { alc883_init_verbs
},
6677 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6678 .dac_nids
= alc883_dac_nids
,
6679 .dig_out_nid
= ALC883_DIGOUT_NID
,
6680 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6681 .adc_nids
= alc883_adc_nids
,
6682 .dig_in_nid
= ALC883_DIGIN_NID
,
6683 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
6684 .channel_mode
= alc883_3ST_6ch_modes
,
6686 .input_mux
= &alc883_capture_source
,
6688 [ALC883_3ST_6ch
] = {
6689 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
6690 .init_verbs
= { alc883_init_verbs
},
6691 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6692 .dac_nids
= alc883_dac_nids
,
6693 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6694 .adc_nids
= alc883_adc_nids
,
6695 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
6696 .channel_mode
= alc883_3ST_6ch_modes
,
6698 .input_mux
= &alc883_capture_source
,
6700 [ALC883_6ST_DIG
] = {
6701 .mixers
= { alc883_base_mixer
, alc883_chmode_mixer
},
6702 .init_verbs
= { alc883_init_verbs
},
6703 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6704 .dac_nids
= alc883_dac_nids
,
6705 .dig_out_nid
= ALC883_DIGOUT_NID
,
6706 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6707 .adc_nids
= alc883_adc_nids
,
6708 .dig_in_nid
= ALC883_DIGIN_NID
,
6709 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
6710 .channel_mode
= alc883_sixstack_modes
,
6711 .input_mux
= &alc883_capture_source
,
6713 [ALC883_TARGA_DIG
] = {
6714 .mixers
= { alc883_tagra_mixer
, alc883_chmode_mixer
},
6715 .init_verbs
= { alc883_init_verbs
, alc883_tagra_verbs
},
6716 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6717 .dac_nids
= alc883_dac_nids
,
6718 .dig_out_nid
= ALC883_DIGOUT_NID
,
6719 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6720 .adc_nids
= alc883_adc_nids
,
6721 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
6722 .channel_mode
= alc883_3ST_6ch_modes
,
6724 .input_mux
= &alc883_capture_source
,
6725 .unsol_event
= alc883_tagra_unsol_event
,
6726 .init_hook
= alc883_tagra_automute
,
6728 [ALC883_TARGA_2ch_DIG
] = {
6729 .mixers
= { alc883_tagra_2ch_mixer
},
6730 .init_verbs
= { alc883_init_verbs
, alc883_tagra_verbs
},
6731 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6732 .dac_nids
= alc883_dac_nids
,
6733 .dig_out_nid
= ALC883_DIGOUT_NID
,
6734 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6735 .adc_nids
= alc883_adc_nids
,
6736 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6737 .channel_mode
= alc883_3ST_2ch_modes
,
6738 .input_mux
= &alc883_capture_source
,
6739 .unsol_event
= alc883_tagra_unsol_event
,
6740 .init_hook
= alc883_tagra_automute
,
6743 .mixers
= { alc883_base_mixer
,
6744 alc883_chmode_mixer
},
6745 /* On TravelMate laptops, GPIO 0 enables the internal speaker
6746 * and the headphone jack. Turn this on and rely on the
6747 * standard mute methods whenever the user wants to turn
6748 * these outputs off.
6750 .init_verbs
= { alc883_init_verbs
, alc880_gpio1_init_verbs
},
6751 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6752 .dac_nids
= alc883_dac_nids
,
6753 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6754 .adc_nids
= alc883_adc_nids
,
6755 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6756 .channel_mode
= alc883_3ST_2ch_modes
,
6757 .input_mux
= &alc883_capture_source
,
6759 [ALC883_ACER_ASPIRE
] = {
6760 .mixers
= { alc883_acer_aspire_mixer
},
6761 .init_verbs
= { alc883_init_verbs
, alc883_acer_aspire_verbs
},
6762 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6763 .dac_nids
= alc883_dac_nids
,
6764 .dig_out_nid
= ALC883_DIGOUT_NID
,
6765 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6766 .adc_nids
= alc883_adc_nids
,
6767 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6768 .channel_mode
= alc883_3ST_2ch_modes
,
6769 .input_mux
= &alc883_capture_source
,
6770 .unsol_event
= alc883_medion_md2_unsol_event
,
6771 .init_hook
= alc883_medion_md2_automute
,
6774 .mixers
= { alc883_fivestack_mixer
,
6775 alc883_chmode_mixer
},
6776 .init_verbs
= { alc883_init_verbs
,
6777 alc883_medion_eapd_verbs
},
6778 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6779 .dac_nids
= alc883_dac_nids
,
6780 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6781 .adc_nids
= alc883_adc_nids
,
6782 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
6783 .channel_mode
= alc883_sixstack_modes
,
6784 .input_mux
= &alc883_capture_source
,
6786 [ALC883_MEDION_MD2
] = {
6787 .mixers
= { alc883_medion_md2_mixer
},
6788 .init_verbs
= { alc883_init_verbs
, alc883_medion_md2_verbs
},
6789 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6790 .dac_nids
= alc883_dac_nids
,
6791 .dig_out_nid
= ALC883_DIGOUT_NID
,
6792 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6793 .adc_nids
= alc883_adc_nids
,
6794 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6795 .channel_mode
= alc883_3ST_2ch_modes
,
6796 .input_mux
= &alc883_capture_source
,
6797 .unsol_event
= alc883_medion_md2_unsol_event
,
6798 .init_hook
= alc883_medion_md2_automute
,
6800 [ALC883_LAPTOP_EAPD
] = {
6801 .mixers
= { alc883_base_mixer
,
6802 alc883_chmode_mixer
},
6803 .init_verbs
= { alc883_init_verbs
, alc882_eapd_verbs
},
6804 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6805 .dac_nids
= alc883_dac_nids
,
6806 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6807 .adc_nids
= alc883_adc_nids
,
6808 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6809 .channel_mode
= alc883_3ST_2ch_modes
,
6810 .input_mux
= &alc883_capture_source
,
6812 [ALC883_LENOVO_101E_2ch
] = {
6813 .mixers
= { alc883_lenovo_101e_2ch_mixer
},
6814 .init_verbs
= { alc883_init_verbs
, alc883_lenovo_101e_verbs
},
6815 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6816 .dac_nids
= alc883_dac_nids
,
6817 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6818 .adc_nids
= alc883_adc_nids
,
6819 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6820 .channel_mode
= alc883_3ST_2ch_modes
,
6821 .input_mux
= &alc883_lenovo_101e_capture_source
,
6822 .unsol_event
= alc883_lenovo_101e_unsol_event
,
6823 .init_hook
= alc883_lenovo_101e_all_automute
,
6825 [ALC883_LENOVO_NB0763
] = {
6826 .mixers
= { alc883_lenovo_nb0763_mixer
},
6827 .init_verbs
= { alc883_init_verbs
, alc883_lenovo_nb0763_verbs
},
6828 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6829 .dac_nids
= alc883_dac_nids
,
6830 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6831 .adc_nids
= alc883_adc_nids
,
6832 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
6833 .channel_mode
= alc883_3ST_2ch_modes
,
6835 .input_mux
= &alc883_lenovo_nb0763_capture_source
,
6836 .unsol_event
= alc883_medion_md2_unsol_event
,
6837 .init_hook
= alc883_medion_md2_automute
,
6839 [ALC888_LENOVO_MS7195_DIG
] = {
6840 .mixers
= { alc883_3ST_6ch_mixer
, alc883_chmode_mixer
},
6841 .init_verbs
= { alc883_init_verbs
, alc888_lenovo_ms7195_verbs
},
6842 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6843 .dac_nids
= alc883_dac_nids
,
6844 .dig_out_nid
= ALC883_DIGOUT_NID
,
6845 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6846 .adc_nids
= alc883_adc_nids
,
6847 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_6ch_modes
),
6848 .channel_mode
= alc883_3ST_6ch_modes
,
6850 .input_mux
= &alc883_capture_source
,
6851 .unsol_event
= alc883_lenovo_ms7195_unsol_event
,
6852 .init_hook
= alc888_lenovo_ms7195_front_automute
,
6855 .mixers
= { alc888_6st_hp_mixer
, alc883_chmode_mixer
},
6856 .init_verbs
= { alc883_init_verbs
, alc888_6st_hp_verbs
},
6857 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6858 .dac_nids
= alc883_dac_nids
,
6859 .dig_out_nid
= ALC883_DIGOUT_NID
,
6860 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6861 .adc_nids
= alc883_adc_nids
,
6862 .dig_in_nid
= ALC883_DIGIN_NID
,
6863 .num_channel_mode
= ARRAY_SIZE(alc883_sixstack_modes
),
6864 .channel_mode
= alc883_sixstack_modes
,
6865 .input_mux
= &alc883_capture_source
,
6868 .mixers
= { alc888_3st_hp_mixer
, alc883_chmode_mixer
},
6869 .init_verbs
= { alc883_init_verbs
, alc888_3st_hp_verbs
},
6870 .num_dacs
= ARRAY_SIZE(alc883_dac_nids
),
6871 .dac_nids
= alc883_dac_nids
,
6872 .num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
),
6873 .adc_nids
= alc883_adc_nids
,
6874 .num_channel_mode
= ARRAY_SIZE(alc888_3st_hp_modes
),
6875 .channel_mode
= alc888_3st_hp_modes
,
6877 .input_mux
= &alc883_capture_source
,
6883 * BIOS auto configuration
6885 static void alc883_auto_set_output_and_unmute(struct hda_codec
*codec
,
6886 hda_nid_t nid
, int pin_type
,
6890 struct alc_spec
*spec
= codec
->spec
;
6893 if (spec
->multiout
.dac_nids
[dac_idx
] == 0x25)
6896 idx
= spec
->multiout
.dac_nids
[dac_idx
] - 2;
6898 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
6900 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
6902 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_CONNECT_SEL
, idx
);
6906 static void alc883_auto_init_multi_out(struct hda_codec
*codec
)
6908 struct alc_spec
*spec
= codec
->spec
;
6911 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
6912 for (i
= 0; i
<= HDA_SIDE
; i
++) {
6913 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
6914 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
6916 alc883_auto_set_output_and_unmute(codec
, nid
, pin_type
,
6921 static void alc883_auto_init_hp_out(struct hda_codec
*codec
)
6923 struct alc_spec
*spec
= codec
->spec
;
6926 pin
= spec
->autocfg
.hp_pins
[0];
6927 if (pin
) /* connect to front */
6929 alc883_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
6932 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
6933 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
6935 static void alc883_auto_init_analog_input(struct hda_codec
*codec
)
6937 struct alc_spec
*spec
= codec
->spec
;
6940 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
6941 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
6942 if (alc883_is_input_pin(nid
)) {
6943 snd_hda_codec_write(codec
, nid
, 0,
6944 AC_VERB_SET_PIN_WIDGET_CONTROL
,
6945 (i
<= AUTO_PIN_FRONT_MIC
?
6946 PIN_VREF80
: PIN_IN
));
6947 if (nid
!= ALC883_PIN_CD_NID
)
6948 snd_hda_codec_write(codec
, nid
, 0,
6949 AC_VERB_SET_AMP_GAIN_MUTE
,
6955 /* almost identical with ALC880 parser... */
6956 static int alc883_parse_auto_config(struct hda_codec
*codec
)
6958 struct alc_spec
*spec
= codec
->spec
;
6959 int err
= alc880_parse_auto_config(codec
);
6964 /* hack - override the init verbs */
6965 spec
->init_verbs
[0] = alc883_auto_init_verbs
;
6966 spec
->mixers
[spec
->num_mixers
] = alc883_capture_mixer
;
6971 /* additional initialization for auto-configuration model */
6972 static void alc883_auto_init(struct hda_codec
*codec
)
6974 alc883_auto_init_multi_out(codec
);
6975 alc883_auto_init_hp_out(codec
);
6976 alc883_auto_init_analog_input(codec
);
6979 static int patch_alc883(struct hda_codec
*codec
)
6981 struct alc_spec
*spec
;
6982 int err
, board_config
;
6984 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
6990 board_config
= snd_hda_check_board_config(codec
, ALC883_MODEL_LAST
,
6993 if (board_config
< 0) {
6994 printk(KERN_INFO
"hda_codec: Unknown model for ALC883, "
6995 "trying auto-probe from BIOS...\n");
6996 board_config
= ALC883_AUTO
;
6999 if (board_config
== ALC883_AUTO
) {
7000 /* automatic parse from the BIOS config */
7001 err
= alc883_parse_auto_config(codec
);
7007 "hda_codec: Cannot set up configuration "
7008 "from BIOS. Using base mode...\n");
7009 board_config
= ALC883_3ST_2ch_DIG
;
7013 if (board_config
!= ALC883_AUTO
)
7014 setup_preset(spec
, &alc883_presets
[board_config
]);
7016 spec
->stream_name_analog
= "ALC883 Analog";
7017 spec
->stream_analog_playback
= &alc883_pcm_analog_playback
;
7018 spec
->stream_analog_capture
= &alc883_pcm_analog_capture
;
7020 spec
->stream_name_digital
= "ALC883 Digital";
7021 spec
->stream_digital_playback
= &alc883_pcm_digital_playback
;
7022 spec
->stream_digital_capture
= &alc883_pcm_digital_capture
;
7024 if (!spec
->adc_nids
&& spec
->input_mux
) {
7025 spec
->adc_nids
= alc883_adc_nids
;
7026 spec
->num_adc_nids
= ARRAY_SIZE(alc883_adc_nids
);
7029 codec
->patch_ops
= alc_patch_ops
;
7030 if (board_config
== ALC883_AUTO
)
7031 spec
->init_hook
= alc883_auto_init
;
7040 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
7041 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
7043 #define alc262_dac_nids alc260_dac_nids
7044 #define alc262_adc_nids alc882_adc_nids
7045 #define alc262_adc_nids_alt alc882_adc_nids_alt
7047 #define alc262_modes alc260_modes
7048 #define alc262_capture_source alc882_capture_source
7050 static struct snd_kcontrol_new alc262_base_mixer
[] = {
7051 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7052 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7059 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7061 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7062 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7063 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7064 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7065 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT
),
7066 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7067 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7068 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
7072 static struct snd_kcontrol_new alc262_hippo1_mixer
[] = {
7073 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7074 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7075 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7076 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7077 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7078 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7079 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7081 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7082 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7083 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7084 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7085 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7086 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7087 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7092 static struct snd_kcontrol_new alc262_HP_BPC_mixer
[] = {
7093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7094 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7096 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7097 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
7099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7101 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7102 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7103 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7104 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
7105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7109 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT
),
7110 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT
),
7111 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT
),
7112 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT
),
7116 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer
[] = {
7117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7118 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
7119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT
),
7120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7121 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT
),
7122 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT
),
7123 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT
),
7124 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT
),
7125 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT
),
7126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7128 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7129 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7130 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT
),
7131 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT
),
7135 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer
[] = {
7136 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7137 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7138 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT
),
7142 static struct hda_bind_ctls alc262_sony_bind_sw
= {
7143 .ops
= &snd_hda_bind_sw
,
7145 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT
),
7146 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
7151 static struct snd_kcontrol_new alc262_sony_mixer
[] = {
7152 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7153 HDA_BIND_SW("Front Playback Switch", &alc262_sony_bind_sw
),
7154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7156 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7157 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7161 static struct snd_kcontrol_new alc262_benq_t31_mixer
[] = {
7162 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT
),
7163 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
7164 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
7165 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7167 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT
),
7168 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT
),
7172 #define alc262_capture_mixer alc882_capture_mixer
7173 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
7176 * generic initialization of ADC, input mixers and output mixers
7178 static struct hda_verb alc262_init_verbs
[] = {
7180 * Unmute ADC0-2 and set the default input to mic-in
7182 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
7183 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7184 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
7185 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7186 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
7187 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7189 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7191 * Note: PASD motherboards uses the Line In 2 as the input for
7192 * front panel mic (mic 2)
7194 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7195 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7197 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
7198 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
7199 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
7202 * Set up output mixers (0x0c - 0x0e)
7204 /* set vol=0 to output mixers */
7205 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7206 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7207 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7208 /* set up input amps for analog loopback */
7209 /* Amp Indices: DAC = 0, mixer = 1 */
7210 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7211 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7212 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7213 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7215 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
7218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
7219 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
7220 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
7221 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
7222 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
7224 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7226 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7228 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7230 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
7231 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
7233 /* FIXME: use matrix-type input source selection */
7234 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7235 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7236 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7237 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7238 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7239 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7254 static struct hda_verb alc262_hippo_unsol_verbs
[] = {
7255 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
7256 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7260 static struct hda_verb alc262_hippo1_unsol_verbs
[] = {
7261 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
7262 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
7263 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, 0x0000},
7265 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
7266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7270 static struct hda_verb alc262_sony_unsol_verbs
[] = {
7271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
7272 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
7273 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24}, // Front Mic
7275 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
7276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7279 /* mute/unmute internal speaker according to the hp jack and mute state */
7280 static void alc262_hippo_automute(struct hda_codec
*codec
)
7282 struct alc_spec
*spec
= codec
->spec
;
7284 unsigned int present
;
7286 /* need to execute and sync at first */
7287 snd_hda_codec_read(codec
, 0x15, 0, AC_VERB_SET_PIN_SENSE
, 0);
7288 present
= snd_hda_codec_read(codec
, 0x15, 0,
7289 AC_VERB_GET_PIN_SENSE
, 0);
7290 spec
->jack_present
= (present
& 0x80000000) != 0;
7291 if (spec
->jack_present
) {
7292 /* mute internal speaker */
7293 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
7294 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
7296 /* unmute internal speaker if necessary */
7297 mute
= snd_hda_codec_amp_read(codec
, 0x15, 0, HDA_OUTPUT
, 0);
7298 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
7299 HDA_AMP_MUTE
, mute
);
7303 /* unsolicited event for HP jack sensing */
7304 static void alc262_hippo_unsol_event(struct hda_codec
*codec
,
7307 if ((res
>> 26) != ALC880_HP_EVENT
)
7309 alc262_hippo_automute(codec
);
7312 static void alc262_hippo1_automute(struct hda_codec
*codec
)
7315 unsigned int present
;
7317 snd_hda_codec_read(codec
, 0x1b, 0, AC_VERB_SET_PIN_SENSE
, 0);
7318 present
= snd_hda_codec_read(codec
, 0x1b, 0,
7319 AC_VERB_GET_PIN_SENSE
, 0);
7320 present
= (present
& 0x80000000) != 0;
7322 /* mute internal speaker */
7323 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
7324 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
7326 /* unmute internal speaker if necessary */
7327 mute
= snd_hda_codec_amp_read(codec
, 0x1b, 0, HDA_OUTPUT
, 0);
7328 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
7329 HDA_AMP_MUTE
, mute
);
7333 /* unsolicited event for HP jack sensing */
7334 static void alc262_hippo1_unsol_event(struct hda_codec
*codec
,
7337 if ((res
>> 26) != ALC880_HP_EVENT
)
7339 alc262_hippo1_automute(codec
);
7344 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
7347 #define ALC_HP_EVENT 0x37
7349 static struct hda_verb alc262_fujitsu_unsol_verbs
[] = {
7350 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC_HP_EVENT
},
7351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
7355 static struct hda_input_mux alc262_fujitsu_capture_source
= {
7363 static struct hda_input_mux alc262_HP_capture_source
= {
7367 { "Front Mic", 0x3 },
7374 /* mute/unmute internal speaker according to the hp jack and mute state */
7375 static void alc262_fujitsu_automute(struct hda_codec
*codec
, int force
)
7377 struct alc_spec
*spec
= codec
->spec
;
7380 if (force
|| !spec
->sense_updated
) {
7381 unsigned int present
;
7382 /* need to execute and sync at first */
7383 snd_hda_codec_read(codec
, 0x14, 0, AC_VERB_SET_PIN_SENSE
, 0);
7384 present
= snd_hda_codec_read(codec
, 0x14, 0,
7385 AC_VERB_GET_PIN_SENSE
, 0);
7386 spec
->jack_present
= (present
& 0x80000000) != 0;
7387 spec
->sense_updated
= 1;
7389 if (spec
->jack_present
) {
7390 /* mute internal speaker */
7391 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
7392 HDA_AMP_MUTE
, HDA_AMP_MUTE
);
7394 /* unmute internal speaker if necessary */
7395 mute
= snd_hda_codec_amp_read(codec
, 0x14, 0, HDA_OUTPUT
, 0);
7396 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
7397 HDA_AMP_MUTE
, mute
);
7401 /* unsolicited event for HP jack sensing */
7402 static void alc262_fujitsu_unsol_event(struct hda_codec
*codec
,
7405 if ((res
>> 26) != ALC_HP_EVENT
)
7407 alc262_fujitsu_automute(codec
, 1);
7410 /* bind volumes of both NID 0x0c and 0x0d */
7411 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol
= {
7412 .ops
= &snd_hda_bind_vol
,
7414 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT
),
7415 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT
),
7420 /* bind hp and internal speaker mute (with plug check) */
7421 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol
*kcontrol
,
7422 struct snd_ctl_elem_value
*ucontrol
)
7424 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
7425 long *valp
= ucontrol
->value
.integer
.value
;
7428 change
= snd_hda_codec_amp_update(codec
, 0x14, 0, HDA_OUTPUT
, 0,
7430 valp
[0] ? 0 : HDA_AMP_MUTE
);
7431 change
|= snd_hda_codec_amp_update(codec
, 0x14, 1, HDA_OUTPUT
, 0,
7433 valp
[1] ? 0 : HDA_AMP_MUTE
);
7435 alc262_fujitsu_automute(codec
, 0);
7439 static struct snd_kcontrol_new alc262_fujitsu_mixer
[] = {
7440 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol
),
7442 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
7443 .name
= "Master Playback Switch",
7444 .info
= snd_hda_mixer_amp_switch_info
,
7445 .get
= snd_hda_mixer_amp_switch_get
,
7446 .put
= alc262_fujitsu_master_sw_put
,
7447 .private_value
= HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT
),
7449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
7450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
7451 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
7452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
7453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
7457 /* additional init verbs for Benq laptops */
7458 static struct hda_verb alc262_EAPD_verbs
[] = {
7459 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
7460 {0x20, AC_VERB_SET_PROC_COEF
, 0x3070},
7464 static struct hda_verb alc262_benq_t31_EAPD_verbs
[] = {
7465 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
7466 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
7468 {0x20, AC_VERB_SET_COEF_INDEX
, 0x07},
7469 {0x20, AC_VERB_SET_PROC_COEF
, 0x3050},
7473 /* add playback controls from the parsed DAC table */
7474 static int alc262_auto_create_multi_out_ctls(struct alc_spec
*spec
,
7475 const struct auto_pin_cfg
*cfg
)
7480 spec
->multiout
.num_dacs
= 1; /* only use one dac */
7481 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
7482 spec
->multiout
.dac_nids
[0] = 2;
7484 nid
= cfg
->line_out_pins
[0];
7486 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
7487 "Front Playback Volume",
7488 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT
));
7491 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
7492 "Front Playback Switch",
7493 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
7498 nid
= cfg
->speaker_pins
[0];
7501 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
7502 "Speaker Playback Volume",
7503 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7507 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
7508 "Speaker Playback Switch",
7509 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
7514 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
7515 "Speaker Playback Switch",
7516 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
7522 nid
= cfg
->hp_pins
[0];
7524 /* spec->multiout.hp_nid = 2; */
7526 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
7527 "Headphone Playback Volume",
7528 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
7532 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
7533 "Headphone Playback Switch",
7534 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
7539 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
7540 "Headphone Playback Switch",
7541 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
7550 /* identical with ALC880 */
7551 #define alc262_auto_create_analog_input_ctls \
7552 alc880_auto_create_analog_input_ctls
7555 * generic initialization of ADC, input mixers and output mixers
7557 static struct hda_verb alc262_volume_init_verbs
[] = {
7559 * Unmute ADC0-2 and set the default input to mic-in
7561 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
7562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7563 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
7564 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7565 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
7566 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7568 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7570 * Note: PASD motherboards uses the Line In 2 as the input for
7571 * front panel mic (mic 2)
7573 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7576 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
7577 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
7578 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
7581 * Set up output mixers (0x0c - 0x0f)
7583 /* set vol=0 to output mixers */
7584 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7585 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7588 /* set up input amps for analog loopback */
7589 /* Amp Indices: DAC = 0, mixer = 1 */
7590 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7592 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7593 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7594 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7595 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7597 /* FIXME: use matrix-type input source selection */
7598 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7599 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7603 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7606 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7608 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x03 << 8))},
7612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8))},
7613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x04 << 8))},
7618 static struct hda_verb alc262_HP_BPC_init_verbs
[] = {
7620 * Unmute ADC0-2 and set the default input to mic-in
7622 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
7623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7624 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
7625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7626 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
7627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7629 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7631 * Note: PASD motherboards uses the Line In 2 as the input for
7632 * front panel mic (mic 2)
7634 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7635 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7636 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7637 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
7638 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
7639 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
7640 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5)},
7641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(6)},
7644 * Set up output mixers (0x0c - 0x0e)
7646 /* set vol=0 to output mixers */
7647 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7648 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7649 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7651 /* set up input amps for analog loopback */
7652 /* Amp Indices: DAC = 0, mixer = 1 */
7653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7654 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7655 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7657 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7658 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7660 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
7661 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7662 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
7664 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7665 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7667 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
7668 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x00},
7670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
7671 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
7672 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
7673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
7674 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
7676 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
7677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7678 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
7680 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7681 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7684 /* FIXME: use matrix-type input source selection */
7685 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7686 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
7689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
7690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
7692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
7694 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
7695 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
7697 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
7699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
7700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
7705 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs
[] = {
7707 * Unmute ADC0-2 and set the default input to mic-in
7709 {0x07, AC_VERB_SET_CONNECT_SEL
, 0x00},
7710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7711 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
7712 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7713 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
7714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7716 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7718 * Note: PASD motherboards uses the Line In 2 as the input for front
7721 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
7725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
7726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
7727 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(5)},
7728 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(6)},
7729 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(7)},
7731 * Set up output mixers (0x0c - 0x0e)
7733 /* set vol=0 to output mixers */
7734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7736 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
7738 /* set up input amps for analog loopback */
7739 /* Amp Indices: DAC = 0, mixer = 1 */
7740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7743 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7744 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
7745 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
7748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
}, /* HP */
7749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Mono */
7750 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* rear MIC */
7751 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* Line in */
7752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
}, /* Front MIC */
7753 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
}, /* Line out */
7754 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
}, /* CD in */
7756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
7759 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
7760 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
7762 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
7763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7765 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7023 },
7766 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7767 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, 0x7000 },
7769 /* FIXME: use matrix-type input source selection */
7770 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7771 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))}, /*rear MIC*/
7773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))}, /*Line in*/
7774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))}, /*F MIC*/
7775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))}, /*Front*/
7776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))}, /*CD*/
7777 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))}, /*HP*/
7780 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7781 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
7782 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
7783 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
7784 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
7785 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7786 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))},
7788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
7789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
7790 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
7791 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
7792 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x04 << 8))},
7793 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x07 << 8))},
7799 /* pcm configuration: identiacal with ALC880 */
7800 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
7801 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
7802 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
7803 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
7806 * BIOS auto configuration
7808 static int alc262_parse_auto_config(struct hda_codec
*codec
)
7810 struct alc_spec
*spec
= codec
->spec
;
7812 static hda_nid_t alc262_ignore
[] = { 0x1d, 0 };
7814 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
7818 if (!spec
->autocfg
.line_outs
)
7819 return 0; /* can't find valid BIOS pin config */
7820 err
= alc262_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
7823 err
= alc262_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
7827 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
7829 if (spec
->autocfg
.dig_out_pin
)
7830 spec
->multiout
.dig_out_nid
= ALC262_DIGOUT_NID
;
7831 if (spec
->autocfg
.dig_in_pin
)
7832 spec
->dig_in_nid
= ALC262_DIGIN_NID
;
7834 if (spec
->kctl_alloc
)
7835 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
7837 spec
->init_verbs
[spec
->num_init_verbs
++] = alc262_volume_init_verbs
;
7838 spec
->num_mux_defs
= 1;
7839 spec
->input_mux
= &spec
->private_imux
;
7844 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
7845 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
7846 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
7849 /* init callback for auto-configuration model -- overriding the default init */
7850 static void alc262_auto_init(struct hda_codec
*codec
)
7852 alc262_auto_init_multi_out(codec
);
7853 alc262_auto_init_hp_out(codec
);
7854 alc262_auto_init_analog_input(codec
);
7858 * configuration and preset
7860 static const char *alc262_models
[ALC262_MODEL_LAST
] = {
7861 [ALC262_BASIC
] = "basic",
7862 [ALC262_HIPPO
] = "hippo",
7863 [ALC262_HIPPO_1
] = "hippo_1",
7864 [ALC262_FUJITSU
] = "fujitsu",
7865 [ALC262_HP_BPC
] = "hp-bpc",
7866 [ALC262_HP_BPC_D7000_WL
]= "hp-bpc-d7000",
7867 [ALC262_BENQ_ED8
] = "benq",
7868 [ALC262_BENQ_T31
] = "benq-t31",
7869 [ALC262_SONY_ASSAMD
] = "sony-assamd",
7870 [ALC262_AUTO
] = "auto",
7873 static struct snd_pci_quirk alc262_cfg_tbl
[] = {
7874 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO
),
7875 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC
),
7876 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC
),
7877 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC
),
7878 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC
),
7879 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC
),
7880 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC
),
7881 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC
),
7882 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC
),
7883 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL
),
7884 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL
),
7885 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL
),
7886 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL
),
7887 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF
),
7888 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF
),
7889 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF
),
7890 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF
),
7891 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO
),
7892 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU
),
7893 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1
),
7894 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8
),
7895 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31
),
7896 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
7897 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD
),
7898 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
7899 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD
),
7903 static struct alc_config_preset alc262_presets
[] = {
7905 .mixers
= { alc262_base_mixer
},
7906 .init_verbs
= { alc262_init_verbs
},
7907 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7908 .dac_nids
= alc262_dac_nids
,
7910 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7911 .channel_mode
= alc262_modes
,
7912 .input_mux
= &alc262_capture_source
,
7915 .mixers
= { alc262_base_mixer
},
7916 .init_verbs
= { alc262_init_verbs
, alc262_hippo_unsol_verbs
},
7917 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7918 .dac_nids
= alc262_dac_nids
,
7920 .dig_out_nid
= ALC262_DIGOUT_NID
,
7921 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7922 .channel_mode
= alc262_modes
,
7923 .input_mux
= &alc262_capture_source
,
7924 .unsol_event
= alc262_hippo_unsol_event
,
7925 .init_hook
= alc262_hippo_automute
,
7927 [ALC262_HIPPO_1
] = {
7928 .mixers
= { alc262_hippo1_mixer
},
7929 .init_verbs
= { alc262_init_verbs
, alc262_hippo1_unsol_verbs
},
7930 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7931 .dac_nids
= alc262_dac_nids
,
7933 .dig_out_nid
= ALC262_DIGOUT_NID
,
7934 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7935 .channel_mode
= alc262_modes
,
7936 .input_mux
= &alc262_capture_source
,
7937 .unsol_event
= alc262_hippo1_unsol_event
,
7938 .init_hook
= alc262_hippo1_automute
,
7940 [ALC262_FUJITSU
] = {
7941 .mixers
= { alc262_fujitsu_mixer
},
7942 .init_verbs
= { alc262_init_verbs
, alc262_fujitsu_unsol_verbs
},
7943 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7944 .dac_nids
= alc262_dac_nids
,
7946 .dig_out_nid
= ALC262_DIGOUT_NID
,
7947 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7948 .channel_mode
= alc262_modes
,
7949 .input_mux
= &alc262_fujitsu_capture_source
,
7950 .unsol_event
= alc262_fujitsu_unsol_event
,
7953 .mixers
= { alc262_HP_BPC_mixer
},
7954 .init_verbs
= { alc262_HP_BPC_init_verbs
},
7955 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7956 .dac_nids
= alc262_dac_nids
,
7958 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7959 .channel_mode
= alc262_modes
,
7960 .input_mux
= &alc262_HP_capture_source
,
7962 [ALC262_HP_BPC_D7000_WF
] = {
7963 .mixers
= { alc262_HP_BPC_WildWest_mixer
},
7964 .init_verbs
= { alc262_HP_BPC_WildWest_init_verbs
},
7965 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7966 .dac_nids
= alc262_dac_nids
,
7968 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7969 .channel_mode
= alc262_modes
,
7970 .input_mux
= &alc262_HP_capture_source
,
7972 [ALC262_HP_BPC_D7000_WL
] = {
7973 .mixers
= { alc262_HP_BPC_WildWest_mixer
,
7974 alc262_HP_BPC_WildWest_option_mixer
},
7975 .init_verbs
= { alc262_HP_BPC_WildWest_init_verbs
},
7976 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7977 .dac_nids
= alc262_dac_nids
,
7979 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7980 .channel_mode
= alc262_modes
,
7981 .input_mux
= &alc262_HP_capture_source
,
7983 [ALC262_BENQ_ED8
] = {
7984 .mixers
= { alc262_base_mixer
},
7985 .init_verbs
= { alc262_init_verbs
, alc262_EAPD_verbs
},
7986 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7987 .dac_nids
= alc262_dac_nids
,
7989 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
7990 .channel_mode
= alc262_modes
,
7991 .input_mux
= &alc262_capture_source
,
7993 [ALC262_SONY_ASSAMD
] = {
7994 .mixers
= { alc262_sony_mixer
},
7995 .init_verbs
= { alc262_init_verbs
, alc262_sony_unsol_verbs
},
7996 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
7997 .dac_nids
= alc262_dac_nids
,
7999 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
8000 .channel_mode
= alc262_modes
,
8001 .input_mux
= &alc262_capture_source
,
8002 .unsol_event
= alc262_hippo_unsol_event
,
8003 .init_hook
= alc262_hippo_automute
,
8005 [ALC262_BENQ_T31
] = {
8006 .mixers
= { alc262_benq_t31_mixer
},
8007 .init_verbs
= { alc262_init_verbs
, alc262_benq_t31_EAPD_verbs
, alc262_hippo_unsol_verbs
},
8008 .num_dacs
= ARRAY_SIZE(alc262_dac_nids
),
8009 .dac_nids
= alc262_dac_nids
,
8011 .num_channel_mode
= ARRAY_SIZE(alc262_modes
),
8012 .channel_mode
= alc262_modes
,
8013 .input_mux
= &alc262_capture_source
,
8014 .unsol_event
= alc262_hippo_unsol_event
,
8015 .init_hook
= alc262_hippo_automute
,
8019 static int patch_alc262(struct hda_codec
*codec
)
8021 struct alc_spec
*spec
;
8025 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
8031 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
8036 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_COEF_INDEX
, 7);
8037 tmp
= snd_hda_codec_read(codec
, 0x20, 0, AC_VERB_GET_PROC_COEF
, 0);
8038 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_COEF_INDEX
, 7);
8039 snd_hda_codec_write(codec
, 0x1a, 0, AC_VERB_SET_PROC_COEF
, tmp
| 0x80);
8043 board_config
= snd_hda_check_board_config(codec
, ALC262_MODEL_LAST
,
8047 if (board_config
< 0) {
8048 printk(KERN_INFO
"hda_codec: Unknown model for ALC262, "
8049 "trying auto-probe from BIOS...\n");
8050 board_config
= ALC262_AUTO
;
8053 if (board_config
== ALC262_AUTO
) {
8054 /* automatic parse from the BIOS config */
8055 err
= alc262_parse_auto_config(codec
);
8061 "hda_codec: Cannot set up configuration "
8062 "from BIOS. Using base mode...\n");
8063 board_config
= ALC262_BASIC
;
8067 if (board_config
!= ALC262_AUTO
)
8068 setup_preset(spec
, &alc262_presets
[board_config
]);
8070 spec
->stream_name_analog
= "ALC262 Analog";
8071 spec
->stream_analog_playback
= &alc262_pcm_analog_playback
;
8072 spec
->stream_analog_capture
= &alc262_pcm_analog_capture
;
8074 spec
->stream_name_digital
= "ALC262 Digital";
8075 spec
->stream_digital_playback
= &alc262_pcm_digital_playback
;
8076 spec
->stream_digital_capture
= &alc262_pcm_digital_capture
;
8078 if (!spec
->adc_nids
&& spec
->input_mux
) {
8079 /* check whether NID 0x07 is valid */
8080 unsigned int wcap
= get_wcaps(codec
, 0x07);
8083 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
8084 if (wcap
!= AC_WID_AUD_IN
) {
8085 spec
->adc_nids
= alc262_adc_nids_alt
;
8086 spec
->num_adc_nids
= ARRAY_SIZE(alc262_adc_nids_alt
);
8087 spec
->mixers
[spec
->num_mixers
] =
8088 alc262_capture_alt_mixer
;
8091 spec
->adc_nids
= alc262_adc_nids
;
8092 spec
->num_adc_nids
= ARRAY_SIZE(alc262_adc_nids
);
8093 spec
->mixers
[spec
->num_mixers
] = alc262_capture_mixer
;
8098 codec
->patch_ops
= alc_patch_ops
;
8099 if (board_config
== ALC262_AUTO
)
8100 spec
->init_hook
= alc262_auto_init
;
8106 * ALC268 channel source setting (2 channel)
8108 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
8109 #define alc268_modes alc260_modes
8111 static hda_nid_t alc268_dac_nids
[2] = {
8116 static hda_nid_t alc268_adc_nids
[2] = {
8121 static hda_nid_t alc268_adc_nids_alt
[1] = {
8126 static struct snd_kcontrol_new alc268_base_mixer
[] = {
8127 /* output mixer control */
8128 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT
),
8129 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
8130 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT
),
8131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
8136 * generic initialization of ADC, input mixers and output mixers
8138 static struct hda_verb alc268_base_init_verbs
[] = {
8139 /* Unmute DAC0-1 and set vol = 0 */
8140 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8141 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8142 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8143 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8144 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8145 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8148 * Set up output mixers (0x0c - 0x0e)
8150 /* set vol=0 to output mixers */
8151 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8152 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8153 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8154 {0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00},
8156 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8157 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
8160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0},
8161 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40},
8162 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
8163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
8164 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8165 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8166 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8168 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8169 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8170 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8173 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8174 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8175 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
8177 /* FIXME: use matrix-type input source selection */
8178 /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8179 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
8182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
8183 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
8184 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
8186 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x00 << 8))},
8187 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8))},
8188 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8))},
8189 {0x24, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x03 << 8))},
8194 * generic initialization of ADC, input mixers and output mixers
8196 static struct hda_verb alc268_volume_init_verbs
[] = {
8197 /* set output DAC */
8198 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8199 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8200 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8201 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8203 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
8204 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24},
8205 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8206 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8207 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20},
8209 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
8210 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8211 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8212 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8213 {0x10, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8215 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8218 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
8220 /* set PCBEEP vol = 0 */
8221 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE
, (0xb000 | (0x00 << 8))},
8226 #define alc268_mux_enum_info alc_mux_enum_info
8227 #define alc268_mux_enum_get alc_mux_enum_get
8229 static int alc268_mux_enum_put(struct snd_kcontrol
*kcontrol
,
8230 struct snd_ctl_elem_value
*ucontrol
)
8232 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
8233 struct alc_spec
*spec
= codec
->spec
;
8234 const struct hda_input_mux
*imux
= spec
->input_mux
;
8235 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
8236 static hda_nid_t capture_mixers
[3] = { 0x23, 0x24 };
8237 hda_nid_t nid
= capture_mixers
[adc_idx
];
8238 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
8239 unsigned int i
, idx
;
8241 idx
= ucontrol
->value
.enumerated
.item
[0];
8242 if (idx
>= imux
->num_items
)
8243 idx
= imux
->num_items
- 1;
8244 if (*cur_val
== idx
)
8246 for (i
= 0; i
< imux
->num_items
; i
++) {
8247 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
8248 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
8249 imux
->items
[i
].index
,
8251 snd_hda_codec_write_cache(codec
, nid
, 0,
8252 AC_VERB_SET_CONNECT_SEL
,
8259 static struct snd_kcontrol_new alc268_capture_alt_mixer
[] = {
8260 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
8261 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT
),
8263 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8264 /* The multiple "Capture Source" controls confuse alsamixer
8265 * So call somewhat different..
8266 * FIXME: the controls appear in the "playback" view!
8268 /* .name = "Capture Source", */
8269 .name
= "Input Source",
8271 .info
= alc268_mux_enum_info
,
8272 .get
= alc268_mux_enum_get
,
8273 .put
= alc268_mux_enum_put
,
8278 static struct snd_kcontrol_new alc268_capture_mixer
[] = {
8279 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT
),
8280 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT
),
8281 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT
),
8282 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT
),
8284 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8285 /* The multiple "Capture Source" controls confuse alsamixer
8286 * So call somewhat different..
8287 * FIXME: the controls appear in the "playback" view!
8289 /* .name = "Capture Source", */
8290 .name
= "Input Source",
8292 .info
= alc268_mux_enum_info
,
8293 .get
= alc268_mux_enum_get
,
8294 .put
= alc268_mux_enum_put
,
8299 static struct hda_input_mux alc268_capture_source
= {
8303 { "Front Mic", 0x1 },
8309 /* create input playback/capture controls for the given pin */
8310 static int alc268_new_analog_output(struct alc_spec
*spec
, hda_nid_t nid
,
8311 const char *ctlname
, int idx
)
8316 sprintf(name
, "%s Playback Volume", ctlname
);
8318 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
8319 HDA_COMPOSE_AMP_VAL(0x02, 3, idx
,
8323 } else if (nid
== 0x15) {
8324 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
8325 HDA_COMPOSE_AMP_VAL(0x03, 3, idx
,
8331 sprintf(name
, "%s Playback Switch", ctlname
);
8332 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
8333 HDA_COMPOSE_AMP_VAL(nid
, 3, idx
, HDA_OUTPUT
));
8339 /* add playback controls from the parsed DAC table */
8340 static int alc268_auto_create_multi_out_ctls(struct alc_spec
*spec
,
8341 const struct auto_pin_cfg
*cfg
)
8346 spec
->multiout
.num_dacs
= 2; /* only use one dac */
8347 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
8348 spec
->multiout
.dac_nids
[0] = 2;
8349 spec
->multiout
.dac_nids
[1] = 3;
8351 nid
= cfg
->line_out_pins
[0];
8353 alc268_new_analog_output(spec
, nid
, "Front", 0);
8355 nid
= cfg
->speaker_pins
[0];
8357 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
8358 "Speaker Playback Volume",
8359 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_INPUT
));
8363 nid
= cfg
->hp_pins
[0];
8365 alc268_new_analog_output(spec
, nid
, "Headphone", 0);
8367 nid
= cfg
->line_out_pins
[1] | cfg
->line_out_pins
[2];
8369 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
8370 "Mono Playback Switch",
8371 HDA_COMPOSE_AMP_VAL(nid
, 2, 0, HDA_INPUT
));
8378 /* create playback/capture controls for input pins */
8379 static int alc268_auto_create_analog_input_ctls(struct alc_spec
*spec
,
8380 const struct auto_pin_cfg
*cfg
)
8382 struct hda_input_mux
*imux
= &spec
->private_imux
;
8385 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
8386 switch(cfg
->input_pins
[i
]) {
8388 idx1
= 0; /* Mic 1 */
8391 idx1
= 1; /* Mic 2 */
8394 idx1
= 2; /* Line In */
8402 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
8403 imux
->items
[imux
->num_items
].index
= idx1
;
8409 static void alc268_auto_init_mono_speaker_out(struct hda_codec
*codec
)
8411 struct alc_spec
*spec
= codec
->spec
;
8412 hda_nid_t speaker_nid
= spec
->autocfg
.speaker_pins
[0];
8413 hda_nid_t hp_nid
= spec
->autocfg
.hp_pins
[0];
8414 hda_nid_t line_nid
= spec
->autocfg
.line_out_pins
[0];
8415 unsigned int dac_vol1
, dac_vol2
;
8418 snd_hda_codec_write(codec
, speaker_nid
, 0,
8419 AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
);
8420 snd_hda_codec_write(codec
, 0x0f, 0,
8421 AC_VERB_SET_AMP_GAIN_MUTE
,
8423 snd_hda_codec_write(codec
, 0x10, 0,
8424 AC_VERB_SET_AMP_GAIN_MUTE
,
8427 snd_hda_codec_write(codec
, 0x0f, 0,
8428 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1));
8429 snd_hda_codec_write(codec
, 0x10, 0,
8430 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1));
8433 dac_vol1
= dac_vol2
= 0xb000 | 0x40; /* set max volume */
8434 if (line_nid
== 0x14)
8435 dac_vol2
= AMP_OUT_ZERO
;
8436 else if (line_nid
== 0x15)
8437 dac_vol1
= AMP_OUT_ZERO
;
8439 dac_vol2
= AMP_OUT_ZERO
;
8440 else if (hp_nid
== 0x15)
8441 dac_vol1
= AMP_OUT_ZERO
;
8442 if (line_nid
!= 0x16 || hp_nid
!= 0x16 ||
8443 spec
->autocfg
.line_out_pins
[1] != 0x16 ||
8444 spec
->autocfg
.line_out_pins
[2] != 0x16)
8445 dac_vol1
= dac_vol2
= AMP_OUT_ZERO
;
8447 snd_hda_codec_write(codec
, 0x02, 0,
8448 AC_VERB_SET_AMP_GAIN_MUTE
, dac_vol1
);
8449 snd_hda_codec_write(codec
, 0x03, 0,
8450 AC_VERB_SET_AMP_GAIN_MUTE
, dac_vol2
);
8453 /* pcm configuration: identiacal with ALC880 */
8454 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
8455 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
8456 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
8459 * BIOS auto configuration
8461 static int alc268_parse_auto_config(struct hda_codec
*codec
)
8463 struct alc_spec
*spec
= codec
->spec
;
8465 static hda_nid_t alc268_ignore
[] = { 0 };
8467 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
8471 if (!spec
->autocfg
.line_outs
)
8472 return 0; /* can't find valid BIOS pin config */
8474 err
= alc268_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
8477 err
= alc268_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
8481 spec
->multiout
.max_channels
= 2;
8483 /* digital only support output */
8484 if (spec
->autocfg
.dig_out_pin
)
8485 spec
->multiout
.dig_out_nid
= ALC268_DIGOUT_NID
;
8487 if (spec
->kctl_alloc
)
8488 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
8490 spec
->init_verbs
[spec
->num_init_verbs
++] = alc268_volume_init_verbs
;
8491 spec
->num_mux_defs
= 1;
8492 spec
->input_mux
= &spec
->private_imux
;
8497 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
8498 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
8499 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
8501 /* init callback for auto-configuration model -- overriding the default init */
8502 static void alc268_auto_init(struct hda_codec
*codec
)
8504 alc268_auto_init_multi_out(codec
);
8505 alc268_auto_init_hp_out(codec
);
8506 alc268_auto_init_mono_speaker_out(codec
);
8507 alc268_auto_init_analog_input(codec
);
8511 * configuration and preset
8513 static const char *alc268_models
[ALC268_MODEL_LAST
] = {
8514 [ALC268_3ST
] = "3stack",
8515 [ALC268_AUTO
] = "auto",
8518 static struct snd_pci_quirk alc268_cfg_tbl
[] = {
8519 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST
),
8523 static struct alc_config_preset alc268_presets
[] = {
8525 .mixers
= { alc268_base_mixer
, alc268_capture_alt_mixer
},
8526 .init_verbs
= { alc268_base_init_verbs
},
8527 .num_dacs
= ARRAY_SIZE(alc268_dac_nids
),
8528 .dac_nids
= alc268_dac_nids
,
8529 .num_adc_nids
= ARRAY_SIZE(alc268_adc_nids_alt
),
8530 .adc_nids
= alc268_adc_nids_alt
,
8532 .dig_out_nid
= ALC268_DIGOUT_NID
,
8533 .num_channel_mode
= ARRAY_SIZE(alc268_modes
),
8534 .channel_mode
= alc268_modes
,
8535 .input_mux
= &alc268_capture_source
,
8539 static int patch_alc268(struct hda_codec
*codec
)
8541 struct alc_spec
*spec
;
8545 spec
= kcalloc(1, sizeof(*spec
), GFP_KERNEL
);
8551 board_config
= snd_hda_check_board_config(codec
, ALC268_MODEL_LAST
,
8555 if (board_config
< 0 || board_config
>= ALC268_MODEL_LAST
) {
8556 printk(KERN_INFO
"hda_codec: Unknown model for ALC268, "
8557 "trying auto-probe from BIOS...\n");
8558 board_config
= ALC268_AUTO
;
8561 if (board_config
== ALC268_AUTO
) {
8562 /* automatic parse from the BIOS config */
8563 err
= alc268_parse_auto_config(codec
);
8569 "hda_codec: Cannot set up configuration "
8570 "from BIOS. Using base mode...\n");
8571 board_config
= ALC268_3ST
;
8575 if (board_config
!= ALC268_AUTO
)
8576 setup_preset(spec
, &alc268_presets
[board_config
]);
8578 spec
->stream_name_analog
= "ALC268 Analog";
8579 spec
->stream_analog_playback
= &alc268_pcm_analog_playback
;
8580 spec
->stream_analog_capture
= &alc268_pcm_analog_capture
;
8582 spec
->stream_name_digital
= "ALC268 Digital";
8583 spec
->stream_digital_playback
= &alc268_pcm_digital_playback
;
8585 if (board_config
== ALC268_AUTO
) {
8586 if (!spec
->adc_nids
&& spec
->input_mux
) {
8587 /* check whether NID 0x07 is valid */
8588 unsigned int wcap
= get_wcaps(codec
, 0x07);
8591 wcap
= (wcap
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
8592 if (wcap
!= AC_WID_AUD_IN
) {
8593 spec
->adc_nids
= alc268_adc_nids_alt
;
8594 spec
->num_adc_nids
=
8595 ARRAY_SIZE(alc268_adc_nids_alt
);
8596 spec
->mixers
[spec
->num_mixers
] =
8597 alc268_capture_alt_mixer
;
8600 spec
->adc_nids
= alc268_adc_nids
;
8601 spec
->num_adc_nids
=
8602 ARRAY_SIZE(alc268_adc_nids
);
8603 spec
->mixers
[spec
->num_mixers
] =
8604 alc268_capture_mixer
;
8609 codec
->patch_ops
= alc_patch_ops
;
8610 if (board_config
== ALC268_AUTO
)
8611 spec
->init_hook
= alc268_auto_init
;
8617 * ALC861 channel source setting (2/6 channel selection for 3-stack)
8621 * set the path ways for 2 channel output
8622 * need to set the codec line out and mic 1 pin widgets to inputs
8624 static struct hda_verb alc861_threestack_ch2_init
[] = {
8625 /* set pin widget 1Ah (line in) for input */
8626 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
8627 /* set pin widget 18h (mic1/2) for input, for mic also enable
8630 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8632 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c },
8634 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
8635 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8)) }, /*line-in*/
8641 * need to set the codec line out and mic 1 pin widgets to outputs
8643 static struct hda_verb alc861_threestack_ch6_init
[] = {
8644 /* set pin widget 1Ah (line in) for output (Back Surround)*/
8645 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8646 /* set pin widget 18h (mic1) for output (CLFE)*/
8647 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8649 { 0x0c, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8650 { 0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8652 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080 },
8654 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
8655 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8)) }, /*line in*/
8660 static struct hda_channel_mode alc861_threestack_modes
[2] = {
8661 { 2, alc861_threestack_ch2_init
},
8662 { 6, alc861_threestack_ch6_init
},
8664 /* Set mic1 as input and unmute the mixer */
8665 static struct hda_verb alc861_uniwill_m31_ch2_init
[] = {
8666 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8667 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
8670 /* Set mic1 as output and mute mixer */
8671 static struct hda_verb alc861_uniwill_m31_ch4_init
[] = {
8672 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8673 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
8677 static struct hda_channel_mode alc861_uniwill_m31_modes
[2] = {
8678 { 2, alc861_uniwill_m31_ch2_init
},
8679 { 4, alc861_uniwill_m31_ch4_init
},
8682 /* Set mic1 and line-in as input and unmute the mixer */
8683 static struct hda_verb alc861_asus_ch2_init
[] = {
8684 /* set pin widget 1Ah (line in) for input */
8685 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
8686 /* set pin widget 18h (mic1/2) for input, for mic also enable
8689 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8691 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c },
8693 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x01 << 8)) }, /*mic*/
8694 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7000 | (0x02 << 8)) }, /*line-in*/
8698 /* Set mic1 nad line-in as output and mute mixer */
8699 static struct hda_verb alc861_asus_ch6_init
[] = {
8700 /* set pin widget 1Ah (line in) for output (Back Surround)*/
8701 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8702 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8703 /* set pin widget 18h (mic1) for output (CLFE)*/
8704 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8705 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
8706 { 0x0c, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8707 { 0x0d, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8709 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb080 },
8711 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x01 << 8)) }, /*mic*/
8712 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, (0x7080 | (0x02 << 8)) }, /*line in*/
8717 static struct hda_channel_mode alc861_asus_modes
[2] = {
8718 { 2, alc861_asus_ch2_init
},
8719 { 6, alc861_asus_ch6_init
},
8724 static struct snd_kcontrol_new alc861_base_mixer
[] = {
8725 /* output mixer control */
8726 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
8727 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
8728 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
8729 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
8730 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT
),
8732 /*Input mixer control */
8733 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8734 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8735 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
8736 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
8737 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
8738 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
8739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
8740 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
8741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
8742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
8744 /* Capture mixer control */
8745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
8746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
8748 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8749 .name
= "Capture Source",
8751 .info
= alc_mux_enum_info
,
8752 .get
= alc_mux_enum_get
,
8753 .put
= alc_mux_enum_put
,
8758 static struct snd_kcontrol_new alc861_3ST_mixer
[] = {
8759 /* output mixer control */
8760 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
8761 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
8762 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
8763 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
8764 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8766 /* Input mixer control */
8767 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8768 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8769 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
8770 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
8771 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
8772 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
8773 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
8774 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
8775 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
8776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
8778 /* Capture mixer control */
8779 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
8780 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
8782 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8783 .name
= "Capture Source",
8785 .info
= alc_mux_enum_info
,
8786 .get
= alc_mux_enum_get
,
8787 .put
= alc_mux_enum_put
,
8790 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8791 .name
= "Channel Mode",
8792 .info
= alc_ch_mode_info
,
8793 .get
= alc_ch_mode_get
,
8794 .put
= alc_ch_mode_put
,
8795 .private_value
= ARRAY_SIZE(alc861_threestack_modes
),
8800 static struct snd_kcontrol_new alc861_toshiba_mixer
[] = {
8801 /* output mixer control */
8802 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
8803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
8804 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
8806 /*Capture mixer control */
8807 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
8808 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
8810 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8811 .name
= "Capture Source",
8813 .info
= alc_mux_enum_info
,
8814 .get
= alc_mux_enum_get
,
8815 .put
= alc_mux_enum_put
,
8821 static struct snd_kcontrol_new alc861_uniwill_m31_mixer
[] = {
8822 /* output mixer control */
8823 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
8824 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
8825 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
8826 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
8827 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
8829 /* Input mixer control */
8830 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
8831 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
8832 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
8833 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
8834 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
8835 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
8836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
8837 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
8838 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
8839 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT
),
8841 /* Capture mixer control */
8842 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
8843 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
8845 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8846 .name
= "Capture Source",
8848 .info
= alc_mux_enum_info
,
8849 .get
= alc_mux_enum_get
,
8850 .put
= alc_mux_enum_put
,
8853 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8854 .name
= "Channel Mode",
8855 .info
= alc_ch_mode_info
,
8856 .get
= alc_ch_mode_get
,
8857 .put
= alc_ch_mode_put
,
8858 .private_value
= ARRAY_SIZE(alc861_uniwill_m31_modes
),
8863 static struct snd_kcontrol_new alc861_asus_mixer
[] = {
8864 /* output mixer control */
8865 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
8866 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT
),
8867 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT
),
8868 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT
),
8869 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT
),
8871 /* Input mixer control */
8872 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT
),
8873 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT
),
8874 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
8875 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
8876 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT
),
8877 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT
),
8878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT
),
8879 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT
),
8880 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT
),
8881 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT
),
8883 /* Capture mixer control */
8884 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
8885 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
8887 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8888 .name
= "Capture Source",
8890 .info
= alc_mux_enum_info
,
8891 .get
= alc_mux_enum_get
,
8892 .put
= alc_mux_enum_put
,
8895 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
8896 .name
= "Channel Mode",
8897 .info
= alc_ch_mode_info
,
8898 .get
= alc_ch_mode_get
,
8899 .put
= alc_ch_mode_put
,
8900 .private_value
= ARRAY_SIZE(alc861_asus_modes
),
8905 /* additional mixer */
8906 static struct snd_kcontrol_new alc861_asus_laptop_mixer
[] = {
8907 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT
),
8908 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT
),
8909 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT
),
8910 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT
),
8915 * generic initialization of ADC, input mixers and output mixers
8917 static struct hda_verb alc861_base_init_verbs
[] = {
8919 * Unmute ADC0 and set the default input to mic-in
8921 /* port-A for surround (rear panel) */
8922 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8923 { 0x0e, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8924 /* port-B for mic-in (rear panel) with vref */
8925 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8926 /* port-C for line-in (rear panel) */
8927 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
8928 /* port-D for Front */
8929 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8930 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8931 /* port-E for HP out (front panel) */
8932 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
8933 /* route front PCM to HP */
8934 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8935 /* port-F for mic-in (front panel) with vref */
8936 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8937 /* port-G for CLFE (rear panel) */
8938 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8939 { 0x1f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8940 /* port-H for side (rear panel) */
8941 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8942 { 0x20, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8944 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
8945 /* route front mic to ADC1*/
8946 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
8947 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8949 /* Unmute DAC0~3 & spdif out*/
8950 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8951 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8952 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8953 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8954 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
8956 /* Unmute Mixer 14 (mic) 1c (Line in)*/
8957 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8958 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8959 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8960 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8962 /* Unmute Stereo Mixer 15 */
8963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8965 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
8966 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
8968 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8969 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8970 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8971 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8972 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
8975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
8976 /* hp used DAC 3 (Front) */
8977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
8978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
8983 static struct hda_verb alc861_threestack_init_verbs
[] = {
8985 * Unmute ADC0 and set the default input to mic-in
8987 /* port-A for surround (rear panel) */
8988 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
8989 /* port-B for mic-in (rear panel) with vref */
8990 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
8991 /* port-C for line-in (rear panel) */
8992 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
8993 /* port-D for Front */
8994 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
8995 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
8996 /* port-E for HP out (front panel) */
8997 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 },
8998 /* route front PCM to HP */
8999 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
9000 /* port-F for mic-in (front panel) with vref */
9001 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9002 /* port-G for CLFE (rear panel) */
9003 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9004 /* port-H for side (rear panel) */
9005 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9007 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
9008 /* route front mic to ADC1*/
9009 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
9010 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9011 /* Unmute DAC0~3 & spdif out*/
9012 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9013 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9014 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9015 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9016 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9018 /* Unmute Mixer 14 (mic) 1c (Line in)*/
9019 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9020 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9021 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9022 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9024 /* Unmute Stereo Mixer 15 */
9025 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9026 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9028 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
9030 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9031 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9032 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9033 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9034 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9035 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9036 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9038 /* hp used DAC 3 (Front) */
9039 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
9040 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9044 static struct hda_verb alc861_uniwill_m31_init_verbs
[] = {
9046 * Unmute ADC0 and set the default input to mic-in
9048 /* port-A for surround (rear panel) */
9049 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9050 /* port-B for mic-in (rear panel) with vref */
9051 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9052 /* port-C for line-in (rear panel) */
9053 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
9054 /* port-D for Front */
9055 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
9056 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
9057 /* port-E for HP out (front panel) */
9058 /* this has to be set to VREF80 */
9059 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9060 /* route front PCM to HP */
9061 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
9062 /* port-F for mic-in (front panel) with vref */
9063 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9064 /* port-G for CLFE (rear panel) */
9065 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9066 /* port-H for side (rear panel) */
9067 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9069 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
9070 /* route front mic to ADC1*/
9071 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
9072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9073 /* Unmute DAC0~3 & spdif out*/
9074 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9075 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9076 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9077 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9080 /* Unmute Mixer 14 (mic) 1c (Line in)*/
9081 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9082 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9083 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9084 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9086 /* Unmute Stereo Mixer 15 */
9087 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
9092 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9094 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9095 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9096 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9097 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9100 /* hp used DAC 3 (Front) */
9101 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
9102 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9106 static struct hda_verb alc861_asus_init_verbs
[] = {
9108 * Unmute ADC0 and set the default input to mic-in
9110 /* port-A for surround (rear panel)
9111 * according to codec#0 this is the HP jack
9113 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0xc0 }, /* was 0x00 */
9114 /* route front PCM to HP */
9115 { 0x0e, AC_VERB_SET_CONNECT_SEL
, 0x01 },
9116 /* port-B for mic-in (rear panel) with vref */
9117 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9118 /* port-C for line-in (rear panel) */
9119 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
9120 /* port-D for Front */
9121 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
9122 { 0x0b, AC_VERB_SET_CONNECT_SEL
, 0x00 },
9123 /* port-E for HP out (front panel) */
9124 /* this has to be set to VREF80 */
9125 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9126 /* route front PCM to HP */
9127 { 0x0f, AC_VERB_SET_CONNECT_SEL
, 0x00 },
9128 /* port-F for mic-in (front panel) with vref */
9129 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x24 },
9130 /* port-G for CLFE (rear panel) */
9131 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
9132 /* port-H for side (rear panel) */
9133 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x40 },
9135 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x20 },
9136 /* route front mic to ADC1*/
9137 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00},
9138 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9139 /* Unmute DAC0~3 & spdif out*/
9140 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9141 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9142 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9143 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9145 /* Unmute Mixer 14 (mic) 1c (Line in)*/
9146 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9147 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9148 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9149 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9151 /* Unmute Stereo Mixer 15 */
9152 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9153 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9154 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c}, /* Output 0~12 step */
9157 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9158 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9159 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9160 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9162 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9163 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9165 /* hp used DAC 3 (Front) */
9166 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
9167 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9171 /* additional init verbs for ASUS laptops */
9172 static struct hda_verb alc861_asus_laptop_init_verbs
[] = {
9173 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x45 }, /* HP-out */
9174 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2) }, /* mute line-in */
9179 * generic initialization of ADC, input mixers and output mixers
9181 static struct hda_verb alc861_auto_init_verbs
[] = {
9183 * Unmute ADC0 and set the default input to mic-in
9185 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9186 {0x08, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9188 /* Unmute DAC0~3 & spdif out*/
9189 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
9190 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
9191 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
9192 {0x06, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
9193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
9195 /* Unmute Mixer 14 (mic) 1c (Line in)*/
9196 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9197 {0x014, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9198 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9199 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9201 /* Unmute Stereo Mixer 15 */
9202 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, 0xb00c},
9207 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9208 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9212 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9213 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
9214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
9216 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
9217 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
9218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
9220 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
9221 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
9222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
9223 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
9225 {0x08, AC_VERB_SET_CONNECT_SEL
, 0x00}, /* set Mic 1 */
9230 static struct hda_verb alc861_toshiba_init_verbs
[] = {
9231 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
9236 /* toggle speaker-output according to the hp-jack state */
9237 static void alc861_toshiba_automute(struct hda_codec
*codec
)
9239 unsigned int present
;
9241 present
= snd_hda_codec_read(codec
, 0x0f, 0,
9242 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
9243 snd_hda_codec_amp_stereo(codec
, 0x16, HDA_INPUT
, 0,
9244 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
9245 snd_hda_codec_amp_stereo(codec
, 0x1a, HDA_INPUT
, 3,
9246 HDA_AMP_MUTE
, present
? 0 : HDA_AMP_MUTE
);
9249 static void alc861_toshiba_unsol_event(struct hda_codec
*codec
,
9252 if ((res
>> 26) == ALC880_HP_EVENT
)
9253 alc861_toshiba_automute(codec
);
9256 /* pcm configuration: identiacal with ALC880 */
9257 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
9258 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
9259 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
9260 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
9263 #define ALC861_DIGOUT_NID 0x07
9265 static struct hda_channel_mode alc861_8ch_modes
[1] = {
9269 static hda_nid_t alc861_dac_nids
[4] = {
9270 /* front, surround, clfe, side */
9271 0x03, 0x06, 0x05, 0x04
9274 static hda_nid_t alc660_dac_nids
[3] = {
9275 /* front, clfe, surround */
9279 static hda_nid_t alc861_adc_nids
[1] = {
9284 static struct hda_input_mux alc861_capture_source
= {
9288 { "Front Mic", 0x3 },
9295 /* fill in the dac_nids table from the parsed pin configuration */
9296 static int alc861_auto_fill_dac_nids(struct alc_spec
*spec
,
9297 const struct auto_pin_cfg
*cfg
)
9302 spec
->multiout
.dac_nids
= spec
->private_dac_nids
;
9303 for (i
= 0; i
< cfg
->line_outs
; i
++) {
9304 nid
= cfg
->line_out_pins
[i
];
9306 if (i
>= ARRAY_SIZE(alc861_dac_nids
))
9308 spec
->multiout
.dac_nids
[i
] = alc861_dac_nids
[i
];
9311 spec
->multiout
.num_dacs
= cfg
->line_outs
;
9315 /* add playback controls from the parsed DAC table */
9316 static int alc861_auto_create_multi_out_ctls(struct alc_spec
*spec
,
9317 const struct auto_pin_cfg
*cfg
)
9320 static const char *chname
[4] = {
9321 "Front", "Surround", NULL
/*CLFE*/, "Side"
9326 for (i
= 0; i
< cfg
->line_outs
; i
++) {
9327 nid
= spec
->multiout
.dac_nids
[i
];
9332 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
9333 "Center Playback Switch",
9334 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
9338 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
9339 "LFE Playback Switch",
9340 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
9345 for (idx
= 0; idx
< ARRAY_SIZE(alc861_dac_nids
) - 1;
9347 if (nid
== alc861_dac_nids
[idx
])
9349 sprintf(name
, "%s Playback Switch", chname
[idx
]);
9350 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
9351 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
9360 static int alc861_auto_create_hp_ctls(struct alc_spec
*spec
, hda_nid_t pin
)
9368 if ((pin
>= 0x0b && pin
<= 0x10) || pin
== 0x1f || pin
== 0x20) {
9370 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
,
9371 "Headphone Playback Switch",
9372 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
9375 spec
->multiout
.hp_nid
= nid
;
9380 /* create playback/capture controls for input pins */
9381 static int alc861_auto_create_analog_input_ctls(struct alc_spec
*spec
,
9382 const struct auto_pin_cfg
*cfg
)
9384 struct hda_input_mux
*imux
= &spec
->private_imux
;
9385 int i
, err
, idx
, idx1
;
9387 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
9388 switch (cfg
->input_pins
[i
]) {
9391 idx
= 2; /* Line In */
9395 idx
= 2; /* Line In */
9399 idx
= 1; /* Mic In */
9403 idx
= 1; /* Mic In */
9413 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
9414 auto_pin_cfg_labels
[i
], idx
, 0x15);
9418 imux
->items
[imux
->num_items
].label
= auto_pin_cfg_labels
[i
];
9419 imux
->items
[imux
->num_items
].index
= idx1
;
9425 static struct snd_kcontrol_new alc861_capture_mixer
[] = {
9426 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT
),
9427 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT
),
9430 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9431 /* The multiple "Capture Source" controls confuse alsamixer
9432 * So call somewhat different..
9433 *FIXME: the controls appear in the "playback" view!
9435 /* .name = "Capture Source", */
9436 .name
= "Input Source",
9438 .info
= alc_mux_enum_info
,
9439 .get
= alc_mux_enum_get
,
9440 .put
= alc_mux_enum_put
,
9445 static void alc861_auto_set_output_and_unmute(struct hda_codec
*codec
,
9447 int pin_type
, int dac_idx
)
9451 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_PIN_WIDGET_CONTROL
,
9453 snd_hda_codec_write(codec
, dac_idx
, 0, AC_VERB_SET_AMP_GAIN_MUTE
,
9458 static void alc861_auto_init_multi_out(struct hda_codec
*codec
)
9460 struct alc_spec
*spec
= codec
->spec
;
9463 alc_subsystem_id(codec
, 0x0e, 0x0f, 0x0b);
9464 for (i
= 0; i
< spec
->autocfg
.line_outs
; i
++) {
9465 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
9466 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
9468 alc861_auto_set_output_and_unmute(codec
, nid
, pin_type
,
9469 spec
->multiout
.dac_nids
[i
]);
9473 static void alc861_auto_init_hp_out(struct hda_codec
*codec
)
9475 struct alc_spec
*spec
= codec
->spec
;
9478 pin
= spec
->autocfg
.hp_pins
[0];
9479 if (pin
) /* connect to front */
9480 alc861_auto_set_output_and_unmute(codec
, pin
, PIN_HP
,
9481 spec
->multiout
.dac_nids
[0]);
9484 static void alc861_auto_init_analog_input(struct hda_codec
*codec
)
9486 struct alc_spec
*spec
= codec
->spec
;
9489 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
9490 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
9491 if (nid
>= 0x0c && nid
<= 0x11) {
9492 snd_hda_codec_write(codec
, nid
, 0,
9493 AC_VERB_SET_PIN_WIDGET_CONTROL
,
9494 i
<= AUTO_PIN_FRONT_MIC
?
9495 PIN_VREF80
: PIN_IN
);
9500 /* parse the BIOS configuration and set up the alc_spec */
9501 /* return 1 if successful, 0 if the proper config is not found,
9502 * or a negative error code
9504 static int alc861_parse_auto_config(struct hda_codec
*codec
)
9506 struct alc_spec
*spec
= codec
->spec
;
9508 static hda_nid_t alc861_ignore
[] = { 0x1d, 0 };
9510 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
9514 if (!spec
->autocfg
.line_outs
)
9515 return 0; /* can't find valid BIOS pin config */
9517 err
= alc861_auto_fill_dac_nids(spec
, &spec
->autocfg
);
9520 err
= alc861_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
9523 err
= alc861_auto_create_hp_ctls(spec
, spec
->autocfg
.hp_pins
[0]);
9526 err
= alc861_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
9530 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
9532 if (spec
->autocfg
.dig_out_pin
)
9533 spec
->multiout
.dig_out_nid
= ALC861_DIGOUT_NID
;
9535 if (spec
->kctl_alloc
)
9536 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
9538 spec
->init_verbs
[spec
->num_init_verbs
++] = alc861_auto_init_verbs
;
9540 spec
->num_mux_defs
= 1;
9541 spec
->input_mux
= &spec
->private_imux
;
9543 spec
->adc_nids
= alc861_adc_nids
;
9544 spec
->num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
);
9545 spec
->mixers
[spec
->num_mixers
] = alc861_capture_mixer
;
9551 /* additional initialization for auto-configuration model */
9552 static void alc861_auto_init(struct hda_codec
*codec
)
9554 alc861_auto_init_multi_out(codec
);
9555 alc861_auto_init_hp_out(codec
);
9556 alc861_auto_init_analog_input(codec
);
9561 * configuration and preset
9563 static const char *alc861_models
[ALC861_MODEL_LAST
] = {
9564 [ALC861_3ST
] = "3stack",
9565 [ALC660_3ST
] = "3stack-660",
9566 [ALC861_3ST_DIG
] = "3stack-dig",
9567 [ALC861_6ST_DIG
] = "6stack-dig",
9568 [ALC861_UNIWILL_M31
] = "uniwill-m31",
9569 [ALC861_TOSHIBA
] = "toshiba",
9570 [ALC861_ASUS
] = "asus",
9571 [ALC861_ASUS_LAPTOP
] = "asus-laptop",
9572 [ALC861_AUTO
] = "auto",
9575 static struct snd_pci_quirk alc861_cfg_tbl
[] = {
9576 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST
),
9577 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP
),
9578 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP
),
9579 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP
),
9580 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP
),
9581 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS
),
9582 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG
),
9583 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA
),
9584 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
9585 * Any other models that need this preset?
9587 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
9588 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31
),
9589 SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31
),
9590 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31
),
9591 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST
),
9592 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST
),
9593 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST
),
9594 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST
),
9598 static struct alc_config_preset alc861_presets
[] = {
9600 .mixers
= { alc861_3ST_mixer
},
9601 .init_verbs
= { alc861_threestack_init_verbs
},
9602 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9603 .dac_nids
= alc861_dac_nids
,
9604 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
9605 .channel_mode
= alc861_threestack_modes
,
9607 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9608 .adc_nids
= alc861_adc_nids
,
9609 .input_mux
= &alc861_capture_source
,
9611 [ALC861_3ST_DIG
] = {
9612 .mixers
= { alc861_base_mixer
},
9613 .init_verbs
= { alc861_threestack_init_verbs
},
9614 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9615 .dac_nids
= alc861_dac_nids
,
9616 .dig_out_nid
= ALC861_DIGOUT_NID
,
9617 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
9618 .channel_mode
= alc861_threestack_modes
,
9620 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9621 .adc_nids
= alc861_adc_nids
,
9622 .input_mux
= &alc861_capture_source
,
9624 [ALC861_6ST_DIG
] = {
9625 .mixers
= { alc861_base_mixer
},
9626 .init_verbs
= { alc861_base_init_verbs
},
9627 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9628 .dac_nids
= alc861_dac_nids
,
9629 .dig_out_nid
= ALC861_DIGOUT_NID
,
9630 .num_channel_mode
= ARRAY_SIZE(alc861_8ch_modes
),
9631 .channel_mode
= alc861_8ch_modes
,
9632 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9633 .adc_nids
= alc861_adc_nids
,
9634 .input_mux
= &alc861_capture_source
,
9637 .mixers
= { alc861_3ST_mixer
},
9638 .init_verbs
= { alc861_threestack_init_verbs
},
9639 .num_dacs
= ARRAY_SIZE(alc660_dac_nids
),
9640 .dac_nids
= alc660_dac_nids
,
9641 .num_channel_mode
= ARRAY_SIZE(alc861_threestack_modes
),
9642 .channel_mode
= alc861_threestack_modes
,
9644 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9645 .adc_nids
= alc861_adc_nids
,
9646 .input_mux
= &alc861_capture_source
,
9648 [ALC861_UNIWILL_M31
] = {
9649 .mixers
= { alc861_uniwill_m31_mixer
},
9650 .init_verbs
= { alc861_uniwill_m31_init_verbs
},
9651 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9652 .dac_nids
= alc861_dac_nids
,
9653 .dig_out_nid
= ALC861_DIGOUT_NID
,
9654 .num_channel_mode
= ARRAY_SIZE(alc861_uniwill_m31_modes
),
9655 .channel_mode
= alc861_uniwill_m31_modes
,
9657 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9658 .adc_nids
= alc861_adc_nids
,
9659 .input_mux
= &alc861_capture_source
,
9661 [ALC861_TOSHIBA
] = {
9662 .mixers
= { alc861_toshiba_mixer
},
9663 .init_verbs
= { alc861_base_init_verbs
,
9664 alc861_toshiba_init_verbs
},
9665 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9666 .dac_nids
= alc861_dac_nids
,
9667 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
9668 .channel_mode
= alc883_3ST_2ch_modes
,
9669 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9670 .adc_nids
= alc861_adc_nids
,
9671 .input_mux
= &alc861_capture_source
,
9672 .unsol_event
= alc861_toshiba_unsol_event
,
9673 .init_hook
= alc861_toshiba_automute
,
9676 .mixers
= { alc861_asus_mixer
},
9677 .init_verbs
= { alc861_asus_init_verbs
},
9678 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9679 .dac_nids
= alc861_dac_nids
,
9680 .dig_out_nid
= ALC861_DIGOUT_NID
,
9681 .num_channel_mode
= ARRAY_SIZE(alc861_asus_modes
),
9682 .channel_mode
= alc861_asus_modes
,
9685 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9686 .adc_nids
= alc861_adc_nids
,
9687 .input_mux
= &alc861_capture_source
,
9689 [ALC861_ASUS_LAPTOP
] = {
9690 .mixers
= { alc861_toshiba_mixer
, alc861_asus_laptop_mixer
},
9691 .init_verbs
= { alc861_asus_init_verbs
,
9692 alc861_asus_laptop_init_verbs
},
9693 .num_dacs
= ARRAY_SIZE(alc861_dac_nids
),
9694 .dac_nids
= alc861_dac_nids
,
9695 .dig_out_nid
= ALC861_DIGOUT_NID
,
9696 .num_channel_mode
= ARRAY_SIZE(alc883_3ST_2ch_modes
),
9697 .channel_mode
= alc883_3ST_2ch_modes
,
9699 .num_adc_nids
= ARRAY_SIZE(alc861_adc_nids
),
9700 .adc_nids
= alc861_adc_nids
,
9701 .input_mux
= &alc861_capture_source
,
9706 static int patch_alc861(struct hda_codec
*codec
)
9708 struct alc_spec
*spec
;
9712 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
9718 board_config
= snd_hda_check_board_config(codec
, ALC861_MODEL_LAST
,
9722 if (board_config
< 0) {
9723 printk(KERN_INFO
"hda_codec: Unknown model for ALC861, "
9724 "trying auto-probe from BIOS...\n");
9725 board_config
= ALC861_AUTO
;
9728 if (board_config
== ALC861_AUTO
) {
9729 /* automatic parse from the BIOS config */
9730 err
= alc861_parse_auto_config(codec
);
9736 "hda_codec: Cannot set up configuration "
9737 "from BIOS. Using base mode...\n");
9738 board_config
= ALC861_3ST_DIG
;
9742 if (board_config
!= ALC861_AUTO
)
9743 setup_preset(spec
, &alc861_presets
[board_config
]);
9745 spec
->stream_name_analog
= "ALC861 Analog";
9746 spec
->stream_analog_playback
= &alc861_pcm_analog_playback
;
9747 spec
->stream_analog_capture
= &alc861_pcm_analog_capture
;
9749 spec
->stream_name_digital
= "ALC861 Digital";
9750 spec
->stream_digital_playback
= &alc861_pcm_digital_playback
;
9751 spec
->stream_digital_capture
= &alc861_pcm_digital_capture
;
9753 codec
->patch_ops
= alc_patch_ops
;
9754 if (board_config
== ALC861_AUTO
)
9755 spec
->init_hook
= alc861_auto_init
;
9765 * In addition, an independent DAC
9767 #define ALC861VD_DIGOUT_NID 0x06
9769 static hda_nid_t alc861vd_dac_nids
[4] = {
9770 /* front, surr, clfe, side surr */
9771 0x02, 0x03, 0x04, 0x05
9774 /* dac_nids for ALC660vd are in a different order - according to
9776 * This should probably tesult in a different mixer for 6stack models
9777 * of ALC660vd codecs, but for now there is only 3stack mixer
9778 * - and it is the same as in 861vd.
9779 * adc_nids in ALC660vd are (is) the same as in 861vd
9781 static hda_nid_t alc660vd_dac_nids
[3] = {
9782 /* front, rear, clfe, rear_surr */
9786 static hda_nid_t alc861vd_adc_nids
[1] = {
9792 /* FIXME: should be a matrix-type input source selection */
9793 static struct hda_input_mux alc861vd_capture_source
= {
9797 { "Front Mic", 0x1 },
9803 static struct hda_input_mux alc861vd_dallas_capture_source
= {
9806 { "Front Mic", 0x0 },
9807 { "ATAPI Mic", 0x1 },
9812 #define alc861vd_mux_enum_info alc_mux_enum_info
9813 #define alc861vd_mux_enum_get alc_mux_enum_get
9815 static int alc861vd_mux_enum_put(struct snd_kcontrol
*kcontrol
,
9816 struct snd_ctl_elem_value
*ucontrol
)
9818 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
9819 struct alc_spec
*spec
= codec
->spec
;
9820 const struct hda_input_mux
*imux
= spec
->input_mux
;
9821 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
9822 static hda_nid_t capture_mixers
[1] = { 0x22 };
9823 hda_nid_t nid
= capture_mixers
[adc_idx
];
9824 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
9825 unsigned int i
, idx
;
9827 idx
= ucontrol
->value
.enumerated
.item
[0];
9828 if (idx
>= imux
->num_items
)
9829 idx
= imux
->num_items
- 1;
9830 if (*cur_val
== idx
)
9832 for (i
= 0; i
< imux
->num_items
; i
++) {
9833 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
9834 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
9835 imux
->items
[i
].index
,
9845 static struct hda_channel_mode alc861vd_3stack_2ch_modes
[1] = {
9852 static struct hda_verb alc861vd_6stack_ch6_init
[] = {
9853 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
9854 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9855 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9856 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9863 static struct hda_verb alc861vd_6stack_ch8_init
[] = {
9864 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9865 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9866 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9867 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
9871 static struct hda_channel_mode alc861vd_6stack_modes
[2] = {
9872 { 6, alc861vd_6stack_ch6_init
},
9873 { 8, alc861vd_6stack_ch8_init
},
9876 static struct snd_kcontrol_new alc861vd_chmode_mixer
[] = {
9878 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9879 .name
= "Channel Mode",
9880 .info
= alc_ch_mode_info
,
9881 .get
= alc_ch_mode_get
,
9882 .put
= alc_ch_mode_put
,
9887 static struct snd_kcontrol_new alc861vd_capture_mixer
[] = {
9888 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
9889 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
9892 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
9893 /* The multiple "Capture Source" controls confuse alsamixer
9894 * So call somewhat different..
9895 *FIXME: the controls appear in the "playback" view!
9897 /* .name = "Capture Source", */
9898 .name
= "Input Source",
9900 .info
= alc861vd_mux_enum_info
,
9901 .get
= alc861vd_mux_enum_get
,
9902 .put
= alc861vd_mux_enum_put
,
9907 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
9908 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
9910 static struct snd_kcontrol_new alc861vd_6st_mixer
[] = {
9911 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
9912 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
9914 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
9915 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT
),
9917 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
9919 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
9921 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT
),
9922 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT
),
9924 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT
),
9925 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT
),
9927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9933 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9934 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
9935 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
9937 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9938 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9943 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
9944 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
9949 static struct snd_kcontrol_new alc861vd_3st_mixer
[] = {
9950 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
9951 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
9953 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9955 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9957 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9959 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9960 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
9961 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
9963 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
9964 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
9966 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9967 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9969 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
9970 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
9975 static struct snd_kcontrol_new alc861vd_lenovo_mixer
[] = {
9976 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
9977 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
9978 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT
),
9980 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
9982 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT
),
9983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
9984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
9986 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT
),
9987 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
9988 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
9990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
9991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
9996 /* Pin assignment: Front=0x14, HP = 0x15,
9997 * Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
9999 static struct snd_kcontrol_new alc861vd_dallas_mixer
[] = {
10000 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
10001 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT
),
10002 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
10003 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT
),
10004 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10005 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10006 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10007 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT
),
10009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT
),
10010 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
10011 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
10013 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10014 /* .name = "Capture Source", */
10015 .name
= "Input Source",
10017 .info
= alc882_mux_enum_info
,
10018 .get
= alc882_mux_enum_get
,
10019 .put
= alc882_mux_enum_put
,
10025 * generic initialization of ADC, input mixers and output mixers
10027 static struct hda_verb alc861vd_volume_init_verbs
[] = {
10029 * Unmute ADC0 and set the default input to mic-in
10031 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10034 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10035 * the analog-loopback mixer widget
10037 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10038 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10039 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
10041 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
10042 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
10044 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
10048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
10051 * Set up output mixers (0x02 - 0x05)
10053 /* set vol=0 to output mixers */
10054 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10055 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10057 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10059 /* set up input amps for analog loopback */
10060 /* Amp Indices: DAC = 0, mixer = 1 */
10061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10074 * 3-stack pin configuration:
10075 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10077 static struct hda_verb alc861vd_3stack_init_verbs
[] = {
10079 * Set pin mode and muting
10081 /* set front pin widgets 0x14 for output */
10082 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10083 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10084 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
10086 /* Mic (rear) pin: input vref at 80% */
10087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10088 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10089 /* Front Mic pin: input vref at 80% */
10090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10092 /* Line In pin: input */
10093 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10094 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10095 /* Line-2 In: Headphone output (output 0 - 0x0c) */
10096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
10097 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10098 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
10099 /* CD pin widget for input */
10100 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10106 * 6-stack pin configuration:
10108 static struct hda_verb alc861vd_6stack_init_verbs
[] = {
10110 * Set pin mode and muting
10112 /* set front pin widgets 0x14 for output */
10113 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10114 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10115 {0x14, AC_VERB_SET_CONNECT_SEL
, 0x00},
10117 /* Rear Pin: output 1 (0x0d) */
10118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10120 {0x15, AC_VERB_SET_CONNECT_SEL
, 0x01},
10121 /* CLFE Pin: output 2 (0x0e) */
10122 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10123 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10124 {0x16, AC_VERB_SET_CONNECT_SEL
, 0x02},
10125 /* Side Pin: output 3 (0x0f) */
10126 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10128 {0x17, AC_VERB_SET_CONNECT_SEL
, 0x03},
10130 /* Mic (rear) pin: input vref at 80% */
10131 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10132 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10133 /* Front Mic pin: input vref at 80% */
10134 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10135 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10136 /* Line In pin: input */
10137 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10139 /* Line-2 In: Headphone output (output 0 - 0x0c) */
10140 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
10141 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10142 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
10143 /* CD pin widget for input */
10144 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10149 static struct hda_verb alc861vd_eapd_verbs
[] = {
10150 {0x14, AC_VERB_SET_EAPD_BTLENABLE
, 2},
10154 static struct hda_verb alc861vd_lenovo_unsol_verbs
[] = {
10155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10156 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(5)},
10158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
10159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_MIC_EVENT
},
10163 /* toggle speaker-output according to the hp-jack state */
10164 static void alc861vd_lenovo_hp_automute(struct hda_codec
*codec
)
10166 unsigned int present
;
10167 unsigned char bits
;
10169 present
= snd_hda_codec_read(codec
, 0x1b, 0,
10170 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
10171 bits
= present
? HDA_AMP_MUTE
: 0;
10172 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10173 HDA_AMP_MUTE
, bits
);
10176 static void alc861vd_lenovo_mic_automute(struct hda_codec
*codec
)
10178 unsigned int present
;
10179 unsigned char bits
;
10181 present
= snd_hda_codec_read(codec
, 0x18, 0,
10182 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
10183 bits
= present
? HDA_AMP_MUTE
: 0;
10184 snd_hda_codec_amp_stereo(codec
, 0x0b, HDA_INPUT
, 1,
10185 HDA_AMP_MUTE
, bits
);
10188 static void alc861vd_lenovo_automute(struct hda_codec
*codec
)
10190 alc861vd_lenovo_hp_automute(codec
);
10191 alc861vd_lenovo_mic_automute(codec
);
10194 static void alc861vd_lenovo_unsol_event(struct hda_codec
*codec
,
10197 switch (res
>> 26) {
10198 case ALC880_HP_EVENT
:
10199 alc861vd_lenovo_hp_automute(codec
);
10201 case ALC880_MIC_EVENT
:
10202 alc861vd_lenovo_mic_automute(codec
);
10207 static struct hda_verb alc861vd_dallas_verbs
[] = {
10208 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10209 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10210 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10211 {0x05, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
10213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10215 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10216 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10217 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10218 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10219 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10220 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(1)},
10222 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10223 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10226 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10227 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10228 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10229 {0x17, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10231 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
10232 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10233 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF50
},
10234 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10235 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10237 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10238 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(3)},
10242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(2)},
10243 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(4)},
10245 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10246 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10247 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
| ALC880_HP_EVENT
},
10252 /* toggle speaker-output according to the hp-jack state */
10253 static void alc861vd_dallas_automute(struct hda_codec
*codec
)
10255 unsigned int present
;
10257 present
= snd_hda_codec_read(codec
, 0x15, 0,
10258 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
10259 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
10260 HDA_AMP_MUTE
, present
? HDA_AMP_MUTE
: 0);
10263 static void alc861vd_dallas_unsol_event(struct hda_codec
*codec
, unsigned int res
)
10265 if ((res
>> 26) == ALC880_HP_EVENT
)
10266 alc861vd_dallas_automute(codec
);
10269 /* pcm configuration: identiacal with ALC880 */
10270 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
10271 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
10272 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
10273 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
10276 * configuration and preset
10278 static const char *alc861vd_models
[ALC861VD_MODEL_LAST
] = {
10279 [ALC660VD_3ST
] = "3stack-660",
10280 [ALC660VD_3ST_DIG
]= "3stack-660-digout",
10281 [ALC861VD_3ST
] = "3stack",
10282 [ALC861VD_3ST_DIG
] = "3stack-digout",
10283 [ALC861VD_6ST_DIG
] = "6stack-digout",
10284 [ALC861VD_LENOVO
] = "lenovo",
10285 [ALC861VD_DALLAS
] = "dallas",
10286 [ALC861VD_AUTO
] = "auto",
10289 static struct snd_pci_quirk alc861vd_cfg_tbl
[] = {
10290 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST
),
10291 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST
),
10292 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG
),
10293 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST
),
10294 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST
),
10296 SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS
),
10297 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS
),
10298 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO
),
10299 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO
),
10300 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO
),
10301 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG
),
10305 static struct alc_config_preset alc861vd_presets
[] = {
10307 .mixers
= { alc861vd_3st_mixer
},
10308 .init_verbs
= { alc861vd_volume_init_verbs
,
10309 alc861vd_3stack_init_verbs
},
10310 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
10311 .dac_nids
= alc660vd_dac_nids
,
10312 .num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
),
10313 .adc_nids
= alc861vd_adc_nids
,
10314 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10315 .channel_mode
= alc861vd_3stack_2ch_modes
,
10316 .input_mux
= &alc861vd_capture_source
,
10318 [ALC660VD_3ST_DIG
] = {
10319 .mixers
= { alc861vd_3st_mixer
},
10320 .init_verbs
= { alc861vd_volume_init_verbs
,
10321 alc861vd_3stack_init_verbs
},
10322 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
10323 .dac_nids
= alc660vd_dac_nids
,
10324 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
10325 .num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
),
10326 .adc_nids
= alc861vd_adc_nids
,
10327 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10328 .channel_mode
= alc861vd_3stack_2ch_modes
,
10329 .input_mux
= &alc861vd_capture_source
,
10332 .mixers
= { alc861vd_3st_mixer
},
10333 .init_verbs
= { alc861vd_volume_init_verbs
,
10334 alc861vd_3stack_init_verbs
},
10335 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
10336 .dac_nids
= alc861vd_dac_nids
,
10337 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10338 .channel_mode
= alc861vd_3stack_2ch_modes
,
10339 .input_mux
= &alc861vd_capture_source
,
10341 [ALC861VD_3ST_DIG
] = {
10342 .mixers
= { alc861vd_3st_mixer
},
10343 .init_verbs
= { alc861vd_volume_init_verbs
,
10344 alc861vd_3stack_init_verbs
},
10345 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
10346 .dac_nids
= alc861vd_dac_nids
,
10347 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
10348 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10349 .channel_mode
= alc861vd_3stack_2ch_modes
,
10350 .input_mux
= &alc861vd_capture_source
,
10352 [ALC861VD_6ST_DIG
] = {
10353 .mixers
= { alc861vd_6st_mixer
, alc861vd_chmode_mixer
},
10354 .init_verbs
= { alc861vd_volume_init_verbs
,
10355 alc861vd_6stack_init_verbs
},
10356 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
10357 .dac_nids
= alc861vd_dac_nids
,
10358 .dig_out_nid
= ALC861VD_DIGOUT_NID
,
10359 .num_channel_mode
= ARRAY_SIZE(alc861vd_6stack_modes
),
10360 .channel_mode
= alc861vd_6stack_modes
,
10361 .input_mux
= &alc861vd_capture_source
,
10363 [ALC861VD_LENOVO
] = {
10364 .mixers
= { alc861vd_lenovo_mixer
},
10365 .init_verbs
= { alc861vd_volume_init_verbs
,
10366 alc861vd_3stack_init_verbs
,
10367 alc861vd_eapd_verbs
,
10368 alc861vd_lenovo_unsol_verbs
},
10369 .num_dacs
= ARRAY_SIZE(alc660vd_dac_nids
),
10370 .dac_nids
= alc660vd_dac_nids
,
10371 .num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
),
10372 .adc_nids
= alc861vd_adc_nids
,
10373 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10374 .channel_mode
= alc861vd_3stack_2ch_modes
,
10375 .input_mux
= &alc861vd_capture_source
,
10376 .unsol_event
= alc861vd_lenovo_unsol_event
,
10377 .init_hook
= alc861vd_lenovo_automute
,
10379 [ALC861VD_DALLAS
] = {
10380 .mixers
= { alc861vd_dallas_mixer
},
10381 .init_verbs
= { alc861vd_dallas_verbs
},
10382 .num_dacs
= ARRAY_SIZE(alc861vd_dac_nids
),
10383 .dac_nids
= alc861vd_dac_nids
,
10384 .num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
),
10385 .adc_nids
= alc861vd_adc_nids
,
10386 .num_channel_mode
= ARRAY_SIZE(alc861vd_3stack_2ch_modes
),
10387 .channel_mode
= alc861vd_3stack_2ch_modes
,
10388 .input_mux
= &alc861vd_dallas_capture_source
,
10389 .unsol_event
= alc861vd_dallas_unsol_event
,
10390 .init_hook
= alc861vd_dallas_automute
,
10395 * BIOS auto configuration
10397 static void alc861vd_auto_set_output_and_unmute(struct hda_codec
*codec
,
10398 hda_nid_t nid
, int pin_type
, int dac_idx
)
10400 /* set as output */
10401 snd_hda_codec_write(codec
, nid
, 0,
10402 AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
10403 snd_hda_codec_write(codec
, nid
, 0,
10404 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
);
10407 static void alc861vd_auto_init_multi_out(struct hda_codec
*codec
)
10409 struct alc_spec
*spec
= codec
->spec
;
10412 alc_subsystem_id(codec
, 0x15, 0x1b, 0x14);
10413 for (i
= 0; i
<= HDA_SIDE
; i
++) {
10414 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
10415 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
10417 alc861vd_auto_set_output_and_unmute(codec
, nid
,
10423 static void alc861vd_auto_init_hp_out(struct hda_codec
*codec
)
10425 struct alc_spec
*spec
= codec
->spec
;
10428 pin
= spec
->autocfg
.hp_pins
[0];
10429 if (pin
) /* connect to front and use dac 0 */
10430 alc861vd_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
10433 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
10434 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
10436 static void alc861vd_auto_init_analog_input(struct hda_codec
*codec
)
10438 struct alc_spec
*spec
= codec
->spec
;
10441 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
10442 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
10443 if (alc861vd_is_input_pin(nid
)) {
10444 snd_hda_codec_write(codec
, nid
, 0,
10445 AC_VERB_SET_PIN_WIDGET_CONTROL
,
10446 i
<= AUTO_PIN_FRONT_MIC
?
10447 PIN_VREF80
: PIN_IN
);
10448 if (nid
!= ALC861VD_PIN_CD_NID
)
10449 snd_hda_codec_write(codec
, nid
, 0,
10450 AC_VERB_SET_AMP_GAIN_MUTE
,
10456 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
10457 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
10459 /* add playback controls from the parsed DAC table */
10460 /* Based on ALC880 version. But ALC861VD has separate,
10461 * different NIDs for mute/unmute switch and volume control */
10462 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec
*spec
,
10463 const struct auto_pin_cfg
*cfg
)
10466 static const char *chname
[4] = {"Front", "Surround", "CLFE", "Side"};
10467 hda_nid_t nid_v
, nid_s
;
10470 for (i
= 0; i
< cfg
->line_outs
; i
++) {
10471 if (!spec
->multiout
.dac_nids
[i
])
10473 nid_v
= alc861vd_idx_to_mixer_vol(
10475 spec
->multiout
.dac_nids
[i
]));
10476 nid_s
= alc861vd_idx_to_mixer_switch(
10478 spec
->multiout
.dac_nids
[i
]));
10482 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
10483 "Center Playback Volume",
10484 HDA_COMPOSE_AMP_VAL(nid_v
, 1, 0,
10488 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
10489 "LFE Playback Volume",
10490 HDA_COMPOSE_AMP_VAL(nid_v
, 2, 0,
10494 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
10495 "Center Playback Switch",
10496 HDA_COMPOSE_AMP_VAL(nid_s
, 1, 2,
10500 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
10501 "LFE Playback Switch",
10502 HDA_COMPOSE_AMP_VAL(nid_s
, 2, 2,
10507 sprintf(name
, "%s Playback Volume", chname
[i
]);
10508 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
10509 HDA_COMPOSE_AMP_VAL(nid_v
, 3, 0,
10513 sprintf(name
, "%s Playback Switch", chname
[i
]);
10514 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
10515 HDA_COMPOSE_AMP_VAL(nid_s
, 3, 2,
10524 /* add playback controls for speaker and HP outputs */
10525 /* Based on ALC880 version. But ALC861VD has separate,
10526 * different NIDs for mute/unmute switch and volume control */
10527 static int alc861vd_auto_create_extra_out(struct alc_spec
*spec
,
10528 hda_nid_t pin
, const char *pfx
)
10530 hda_nid_t nid_v
, nid_s
;
10537 if (alc880_is_fixed_pin(pin
)) {
10538 nid_v
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
10539 /* specify the DAC as the extra output */
10540 if (!spec
->multiout
.hp_nid
)
10541 spec
->multiout
.hp_nid
= nid_v
;
10543 spec
->multiout
.extra_out_nid
[0] = nid_v
;
10544 /* control HP volume/switch on the output mixer amp */
10545 nid_v
= alc861vd_idx_to_mixer_vol(
10546 alc880_fixed_pin_idx(pin
));
10547 nid_s
= alc861vd_idx_to_mixer_switch(
10548 alc880_fixed_pin_idx(pin
));
10550 sprintf(name
, "%s Playback Volume", pfx
);
10551 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
10552 HDA_COMPOSE_AMP_VAL(nid_v
, 3, 0, HDA_OUTPUT
));
10555 sprintf(name
, "%s Playback Switch", pfx
);
10556 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
10557 HDA_COMPOSE_AMP_VAL(nid_s
, 3, 2, HDA_INPUT
));
10560 } else if (alc880_is_multi_pin(pin
)) {
10561 /* set manual connection */
10562 /* we have only a switch on HP-out PIN */
10563 sprintf(name
, "%s Playback Switch", pfx
);
10564 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
10565 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
10572 /* parse the BIOS configuration and set up the alc_spec
10573 * return 1 if successful, 0 if the proper config is not found,
10574 * or a negative error code
10575 * Based on ALC880 version - had to change it to override
10576 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
10577 static int alc861vd_parse_auto_config(struct hda_codec
*codec
)
10579 struct alc_spec
*spec
= codec
->spec
;
10581 static hda_nid_t alc861vd_ignore
[] = { 0x1d, 0 };
10583 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
10587 if (!spec
->autocfg
.line_outs
)
10588 return 0; /* can't find valid BIOS pin config */
10590 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
10593 err
= alc861vd_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
10596 err
= alc861vd_auto_create_extra_out(spec
,
10597 spec
->autocfg
.speaker_pins
[0],
10601 err
= alc861vd_auto_create_extra_out(spec
,
10602 spec
->autocfg
.hp_pins
[0],
10606 err
= alc880_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
10610 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
10612 if (spec
->autocfg
.dig_out_pin
)
10613 spec
->multiout
.dig_out_nid
= ALC861VD_DIGOUT_NID
;
10615 if (spec
->kctl_alloc
)
10616 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
10618 spec
->init_verbs
[spec
->num_init_verbs
++]
10619 = alc861vd_volume_init_verbs
;
10621 spec
->num_mux_defs
= 1;
10622 spec
->input_mux
= &spec
->private_imux
;
10627 /* additional initialization for auto-configuration model */
10628 static void alc861vd_auto_init(struct hda_codec
*codec
)
10630 alc861vd_auto_init_multi_out(codec
);
10631 alc861vd_auto_init_hp_out(codec
);
10632 alc861vd_auto_init_analog_input(codec
);
10635 static int patch_alc861vd(struct hda_codec
*codec
)
10637 struct alc_spec
*spec
;
10638 int err
, board_config
;
10640 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
10644 codec
->spec
= spec
;
10646 board_config
= snd_hda_check_board_config(codec
, ALC861VD_MODEL_LAST
,
10650 if (board_config
< 0 || board_config
>= ALC861VD_MODEL_LAST
) {
10651 printk(KERN_INFO
"hda_codec: Unknown model for ALC660VD/"
10652 "ALC861VD, trying auto-probe from BIOS...\n");
10653 board_config
= ALC861VD_AUTO
;
10656 if (board_config
== ALC861VD_AUTO
) {
10657 /* automatic parse from the BIOS config */
10658 err
= alc861vd_parse_auto_config(codec
);
10664 "hda_codec: Cannot set up configuration "
10665 "from BIOS. Using base mode...\n");
10666 board_config
= ALC861VD_3ST
;
10670 if (board_config
!= ALC861VD_AUTO
)
10671 setup_preset(spec
, &alc861vd_presets
[board_config
]);
10673 spec
->stream_name_analog
= "ALC861VD Analog";
10674 spec
->stream_analog_playback
= &alc861vd_pcm_analog_playback
;
10675 spec
->stream_analog_capture
= &alc861vd_pcm_analog_capture
;
10677 spec
->stream_name_digital
= "ALC861VD Digital";
10678 spec
->stream_digital_playback
= &alc861vd_pcm_digital_playback
;
10679 spec
->stream_digital_capture
= &alc861vd_pcm_digital_capture
;
10681 spec
->adc_nids
= alc861vd_adc_nids
;
10682 spec
->num_adc_nids
= ARRAY_SIZE(alc861vd_adc_nids
);
10684 spec
->mixers
[spec
->num_mixers
] = alc861vd_capture_mixer
;
10685 spec
->num_mixers
++;
10687 codec
->patch_ops
= alc_patch_ops
;
10689 if (board_config
== ALC861VD_AUTO
)
10690 spec
->init_hook
= alc861vd_auto_init
;
10698 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
10699 * configuration. Each pin widget can choose any input DACs and a mixer.
10700 * Each ADC is connected from a mixer of all inputs. This makes possible
10701 * 6-channel independent captures.
10703 * In addition, an independent DAC for the multi-playback (not used in this
10706 #define ALC662_DIGOUT_NID 0x06
10707 #define ALC662_DIGIN_NID 0x0a
10709 static hda_nid_t alc662_dac_nids
[4] = {
10710 /* front, rear, clfe, rear_surr */
10714 static hda_nid_t alc662_adc_nids
[1] = {
10719 /* FIXME: should be a matrix-type input source selection */
10721 static struct hda_input_mux alc662_capture_source
= {
10725 { "Front Mic", 0x1 },
10731 static struct hda_input_mux alc662_lenovo_101e_capture_source
= {
10738 #define alc662_mux_enum_info alc_mux_enum_info
10739 #define alc662_mux_enum_get alc_mux_enum_get
10741 static int alc662_mux_enum_put(struct snd_kcontrol
*kcontrol
,
10742 struct snd_ctl_elem_value
*ucontrol
)
10744 struct hda_codec
*codec
= snd_kcontrol_chip(kcontrol
);
10745 struct alc_spec
*spec
= codec
->spec
;
10746 const struct hda_input_mux
*imux
= spec
->input_mux
;
10747 unsigned int adc_idx
= snd_ctl_get_ioffidx(kcontrol
, &ucontrol
->id
);
10748 static hda_nid_t capture_mixers
[3] = { 0x24, 0x23, 0x22 };
10749 hda_nid_t nid
= capture_mixers
[adc_idx
];
10750 unsigned int *cur_val
= &spec
->cur_mux
[adc_idx
];
10751 unsigned int i
, idx
;
10753 idx
= ucontrol
->value
.enumerated
.item
[0];
10754 if (idx
>= imux
->num_items
)
10755 idx
= imux
->num_items
- 1;
10756 if (*cur_val
== idx
)
10758 for (i
= 0; i
< imux
->num_items
; i
++) {
10759 unsigned int v
= (i
== idx
) ? 0 : HDA_AMP_MUTE
;
10760 snd_hda_codec_amp_stereo(codec
, nid
, HDA_INPUT
,
10761 imux
->items
[i
].index
,
10770 static struct hda_channel_mode alc662_3ST_2ch_modes
[1] = {
10777 static struct hda_verb alc662_3ST_ch2_init
[] = {
10778 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10779 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10780 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
10781 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10788 static struct hda_verb alc662_3ST_ch6_init
[] = {
10789 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10790 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10791 { 0x18, AC_VERB_SET_CONNECT_SEL
, 0x02 },
10792 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10793 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10794 { 0x1a, AC_VERB_SET_CONNECT_SEL
, 0x01 },
10798 static struct hda_channel_mode alc662_3ST_6ch_modes
[2] = {
10799 { 2, alc662_3ST_ch2_init
},
10800 { 6, alc662_3ST_ch6_init
},
10806 static struct hda_verb alc662_sixstack_ch6_init
[] = {
10807 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
10808 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, 0x00 },
10809 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10816 static struct hda_verb alc662_sixstack_ch8_init
[] = {
10817 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10818 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10819 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10823 static struct hda_channel_mode alc662_5stack_modes
[2] = {
10824 { 2, alc662_sixstack_ch6_init
},
10825 { 6, alc662_sixstack_ch8_init
},
10828 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10829 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10832 static struct snd_kcontrol_new alc662_base_mixer
[] = {
10833 /* output mixer control */
10834 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT
),
10835 HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT
),
10836 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT
),
10837 HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT
),
10838 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT
),
10839 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT
),
10840 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT
),
10841 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT
),
10842 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
10844 /*Input mixer control */
10845 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT
),
10846 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT
),
10847 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT
),
10848 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT
),
10849 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT
),
10850 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT
),
10851 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT
),
10852 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT
),
10854 /* Capture mixer control */
10855 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
10856 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
10858 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10859 .name
= "Capture Source",
10861 .info
= alc_mux_enum_info
,
10862 .get
= alc_mux_enum_get
,
10863 .put
= alc_mux_enum_put
,
10868 static struct snd_kcontrol_new alc662_3ST_2ch_mixer
[] = {
10869 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
10870 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT
),
10871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
10872 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
10873 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
10874 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
10875 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
10876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10878 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10879 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10880 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
10881 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
10882 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
10883 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
10885 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10886 /* .name = "Capture Source", */
10887 .name
= "Input Source",
10889 .info
= alc662_mux_enum_info
,
10890 .get
= alc662_mux_enum_get
,
10891 .put
= alc662_mux_enum_put
,
10896 static struct snd_kcontrol_new alc662_3ST_6ch_mixer
[] = {
10897 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
10898 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT
),
10899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
10900 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT
),
10901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT
),
10902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT
),
10903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT
),
10904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT
),
10905 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
10906 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT
),
10907 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT
),
10908 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
10909 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
10910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT
),
10911 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT
),
10912 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10913 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10914 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT
),
10915 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT
),
10916 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
10917 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
10919 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10920 /* .name = "Capture Source", */
10921 .name
= "Input Source",
10923 .info
= alc662_mux_enum_info
,
10924 .get
= alc662_mux_enum_get
,
10925 .put
= alc662_mux_enum_put
,
10930 static struct snd_kcontrol_new alc662_lenovo_101e_mixer
[] = {
10931 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT
),
10932 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT
),
10933 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT
),
10934 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT
),
10935 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT
),
10936 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT
),
10937 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT
),
10938 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT
),
10939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT
),
10940 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
10941 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
10943 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10944 /* .name = "Capture Source", */
10945 .name
= "Input Source",
10947 .info
= alc662_mux_enum_info
,
10948 .get
= alc662_mux_enum_get
,
10949 .put
= alc662_mux_enum_put
,
10954 static struct snd_kcontrol_new alc662_chmode_mixer
[] = {
10956 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
10957 .name
= "Channel Mode",
10958 .info
= alc_ch_mode_info
,
10959 .get
= alc_ch_mode_get
,
10960 .put
= alc_ch_mode_put
,
10965 static struct hda_verb alc662_init_verbs
[] = {
10966 /* ADC: mute amp left and right */
10967 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_MUTE(0)},
10968 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
10969 /* Front mixer: unmute input/output amp left and right (volume = 0) */
10971 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10972 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10973 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
10974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
10975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
10977 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10978 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10979 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10980 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10981 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
10982 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
10984 /* Front Pin: output 0 (0x0c) */
10985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10986 {0x14, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10988 /* Rear Pin: output 1 (0x0d) */
10989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10990 {0x15, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10992 /* CLFE Pin: output 2 (0x0e) */
10993 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_OUT
},
10994 {0x16, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
10996 /* Mic (rear) pin: input vref at 80% */
10997 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
10998 {0x18, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
10999 /* Front Mic pin: input vref at 80% */
11000 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_VREF80
},
11001 {0x19, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11002 /* Line In pin: input */
11003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
11004 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_MUTE
},
11005 /* Line-2 In: Headphone output (output 0 - 0x0c) */
11006 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_HP
},
11007 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
},
11008 {0x1b, AC_VERB_SET_CONNECT_SEL
, 0x00},
11009 /* CD pin widget for input */
11010 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL
, PIN_IN
},
11012 /* FIXME: use matrix-type input source selection */
11013 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11015 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11016 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11017 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
11018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
11022 static struct hda_verb alc662_sue_init_verbs
[] = {
11023 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_FRONT_EVENT
},
11024 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE
, AC_USRSP_EN
|ALC880_HP_EVENT
},
11029 * generic initialization of ADC, input mixers and output mixers
11031 static struct hda_verb alc662_auto_init_verbs
[] = {
11033 * Unmute ADC and set the default input to mic-in
11035 {0x09, AC_VERB_SET_CONNECT_SEL
, 0x00},
11036 {0x09, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11038 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11040 * Note: PASD motherboards uses the Line In 2 as the input for front
11041 * panel mic (mic 2)
11043 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11044 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11045 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
11047 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(3)},
11048 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
11051 * Set up output mixers (0x0c - 0x0f)
11053 /* set vol=0 to output mixers */
11054 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11055 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11056 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_ZERO
},
11058 /* set up input amps for analog loopback */
11059 /* Amp Indices: DAC = 0, mixer = 1 */
11060 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11061 {0x02, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11062 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11063 {0x03, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11064 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11065 {0x04, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11068 /* FIXME: use matrix-type input source selection */
11069 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(0)},
11072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(1)},
11073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(2)},
11074 /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/
11075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE
, AMP_IN_UNMUTE(4)},
11080 /* capture mixer elements */
11081 static struct snd_kcontrol_new alc662_capture_mixer
[] = {
11082 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT
),
11083 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT
),
11085 .iface
= SNDRV_CTL_ELEM_IFACE_MIXER
,
11086 /* The multiple "Capture Source" controls confuse alsamixer
11087 * So call somewhat different..
11088 * FIXME: the controls appear in the "playback" view!
11090 /* .name = "Capture Source", */
11091 .name
= "Input Source",
11093 .info
= alc882_mux_enum_info
,
11094 .get
= alc882_mux_enum_get
,
11095 .put
= alc882_mux_enum_put
,
11100 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec
*codec
)
11102 unsigned int present
;
11103 unsigned char bits
;
11105 present
= snd_hda_codec_read(codec
, 0x14, 0,
11106 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
11107 bits
= present
? HDA_AMP_MUTE
: 0;
11108 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
11109 HDA_AMP_MUTE
, bits
);
11112 static void alc662_lenovo_101e_all_automute(struct hda_codec
*codec
)
11114 unsigned int present
;
11115 unsigned char bits
;
11117 present
= snd_hda_codec_read(codec
, 0x1b, 0,
11118 AC_VERB_GET_PIN_SENSE
, 0) & 0x80000000;
11119 bits
= present
? HDA_AMP_MUTE
: 0;
11120 snd_hda_codec_amp_stereo(codec
, 0x15, HDA_OUTPUT
, 0,
11121 HDA_AMP_MUTE
, bits
);
11122 snd_hda_codec_amp_stereo(codec
, 0x14, HDA_OUTPUT
, 0,
11123 HDA_AMP_MUTE
, bits
);
11126 static void alc662_lenovo_101e_unsol_event(struct hda_codec
*codec
,
11129 if ((res
>> 26) == ALC880_HP_EVENT
)
11130 alc662_lenovo_101e_all_automute(codec
);
11131 if ((res
>> 26) == ALC880_FRONT_EVENT
)
11132 alc662_lenovo_101e_ispeaker_automute(codec
);
11136 /* pcm configuration: identiacal with ALC880 */
11137 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
11138 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
11139 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
11140 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
11143 * configuration and preset
11145 static const char *alc662_models
[ALC662_MODEL_LAST
] = {
11146 [ALC662_3ST_2ch_DIG
] = "3stack-dig",
11147 [ALC662_3ST_6ch_DIG
] = "3stack-6ch-dig",
11148 [ALC662_3ST_6ch
] = "3stack-6ch",
11149 [ALC662_5ST_DIG
] = "6stack-dig",
11150 [ALC662_LENOVO_101E
] = "lenovo-101e",
11151 [ALC662_AUTO
] = "auto",
11154 static struct snd_pci_quirk alc662_cfg_tbl
[] = {
11155 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E
),
11159 static struct alc_config_preset alc662_presets
[] = {
11160 [ALC662_3ST_2ch_DIG
] = {
11161 .mixers
= { alc662_3ST_2ch_mixer
},
11162 .init_verbs
= { alc662_init_verbs
},
11163 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
11164 .dac_nids
= alc662_dac_nids
,
11165 .dig_out_nid
= ALC662_DIGOUT_NID
,
11166 .num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
),
11167 .adc_nids
= alc662_adc_nids
,
11168 .dig_in_nid
= ALC662_DIGIN_NID
,
11169 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
11170 .channel_mode
= alc662_3ST_2ch_modes
,
11171 .input_mux
= &alc662_capture_source
,
11173 [ALC662_3ST_6ch_DIG
] = {
11174 .mixers
= { alc662_3ST_6ch_mixer
, alc662_chmode_mixer
},
11175 .init_verbs
= { alc662_init_verbs
},
11176 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
11177 .dac_nids
= alc662_dac_nids
,
11178 .dig_out_nid
= ALC662_DIGOUT_NID
,
11179 .num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
),
11180 .adc_nids
= alc662_adc_nids
,
11181 .dig_in_nid
= ALC662_DIGIN_NID
,
11182 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
11183 .channel_mode
= alc662_3ST_6ch_modes
,
11185 .input_mux
= &alc662_capture_source
,
11187 [ALC662_3ST_6ch
] = {
11188 .mixers
= { alc662_3ST_6ch_mixer
, alc662_chmode_mixer
},
11189 .init_verbs
= { alc662_init_verbs
},
11190 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
11191 .dac_nids
= alc662_dac_nids
,
11192 .num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
),
11193 .adc_nids
= alc662_adc_nids
,
11194 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_6ch_modes
),
11195 .channel_mode
= alc662_3ST_6ch_modes
,
11197 .input_mux
= &alc662_capture_source
,
11199 [ALC662_5ST_DIG
] = {
11200 .mixers
= { alc662_base_mixer
, alc662_chmode_mixer
},
11201 .init_verbs
= { alc662_init_verbs
},
11202 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
11203 .dac_nids
= alc662_dac_nids
,
11204 .dig_out_nid
= ALC662_DIGOUT_NID
,
11205 .num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
),
11206 .adc_nids
= alc662_adc_nids
,
11207 .dig_in_nid
= ALC662_DIGIN_NID
,
11208 .num_channel_mode
= ARRAY_SIZE(alc662_5stack_modes
),
11209 .channel_mode
= alc662_5stack_modes
,
11210 .input_mux
= &alc662_capture_source
,
11212 [ALC662_LENOVO_101E
] = {
11213 .mixers
= { alc662_lenovo_101e_mixer
},
11214 .init_verbs
= { alc662_init_verbs
, alc662_sue_init_verbs
},
11215 .num_dacs
= ARRAY_SIZE(alc662_dac_nids
),
11216 .dac_nids
= alc662_dac_nids
,
11217 .num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
),
11218 .adc_nids
= alc662_adc_nids
,
11219 .num_channel_mode
= ARRAY_SIZE(alc662_3ST_2ch_modes
),
11220 .channel_mode
= alc662_3ST_2ch_modes
,
11221 .input_mux
= &alc662_lenovo_101e_capture_source
,
11222 .unsol_event
= alc662_lenovo_101e_unsol_event
,
11223 .init_hook
= alc662_lenovo_101e_all_automute
,
11230 * BIOS auto configuration
11233 /* add playback controls from the parsed DAC table */
11234 static int alc662_auto_create_multi_out_ctls(struct alc_spec
*spec
,
11235 const struct auto_pin_cfg
*cfg
)
11238 static const char *chname
[4] = {
11239 "Front", "Surround", NULL
/*CLFE*/, "Side"
11244 for (i
= 0; i
< cfg
->line_outs
; i
++) {
11245 if (!spec
->multiout
.dac_nids
[i
])
11247 nid
= alc880_idx_to_mixer(i
);
11250 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
11251 "Center Playback Volume",
11252 HDA_COMPOSE_AMP_VAL(nid
, 1, 0,
11256 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
,
11257 "LFE Playback Volume",
11258 HDA_COMPOSE_AMP_VAL(nid
, 2, 0,
11262 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
11263 "Center Playback Switch",
11264 HDA_COMPOSE_AMP_VAL(nid
, 1, 2,
11268 err
= add_control(spec
, ALC_CTL_BIND_MUTE
,
11269 "LFE Playback Switch",
11270 HDA_COMPOSE_AMP_VAL(nid
, 2, 2,
11275 sprintf(name
, "%s Playback Volume", chname
[i
]);
11276 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
11277 HDA_COMPOSE_AMP_VAL(nid
, 3, 0,
11281 sprintf(name
, "%s Playback Switch", chname
[i
]);
11282 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
11283 HDA_COMPOSE_AMP_VAL(nid
, 3, 2,
11292 /* add playback controls for speaker and HP outputs */
11293 static int alc662_auto_create_extra_out(struct alc_spec
*spec
, hda_nid_t pin
,
11303 if (alc880_is_fixed_pin(pin
)) {
11304 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
11305 /* printk("DAC nid=%x\n",nid); */
11306 /* specify the DAC as the extra output */
11307 if (!spec
->multiout
.hp_nid
)
11308 spec
->multiout
.hp_nid
= nid
;
11310 spec
->multiout
.extra_out_nid
[0] = nid
;
11311 /* control HP volume/switch on the output mixer amp */
11312 nid
= alc880_idx_to_dac(alc880_fixed_pin_idx(pin
));
11313 sprintf(name
, "%s Playback Volume", pfx
);
11314 err
= add_control(spec
, ALC_CTL_WIDGET_VOL
, name
,
11315 HDA_COMPOSE_AMP_VAL(nid
, 3, 0, HDA_OUTPUT
));
11318 sprintf(name
, "%s Playback Switch", pfx
);
11319 err
= add_control(spec
, ALC_CTL_BIND_MUTE
, name
,
11320 HDA_COMPOSE_AMP_VAL(nid
, 3, 2, HDA_INPUT
));
11323 } else if (alc880_is_multi_pin(pin
)) {
11324 /* set manual connection */
11325 /* we have only a switch on HP-out PIN */
11326 sprintf(name
, "%s Playback Switch", pfx
);
11327 err
= add_control(spec
, ALC_CTL_WIDGET_MUTE
, name
,
11328 HDA_COMPOSE_AMP_VAL(pin
, 3, 0, HDA_OUTPUT
));
11335 /* create playback/capture controls for input pins */
11336 static int alc662_auto_create_analog_input_ctls(struct alc_spec
*spec
,
11337 const struct auto_pin_cfg
*cfg
)
11339 struct hda_input_mux
*imux
= &spec
->private_imux
;
11342 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
11343 if (alc880_is_input_pin(cfg
->input_pins
[i
])) {
11344 idx
= alc880_input_pin_idx(cfg
->input_pins
[i
]);
11345 err
= new_analog_input(spec
, cfg
->input_pins
[i
],
11346 auto_pin_cfg_labels
[i
],
11350 imux
->items
[imux
->num_items
].label
=
11351 auto_pin_cfg_labels
[i
];
11352 imux
->items
[imux
->num_items
].index
=
11353 alc880_input_pin_idx(cfg
->input_pins
[i
]);
11360 static void alc662_auto_set_output_and_unmute(struct hda_codec
*codec
,
11361 hda_nid_t nid
, int pin_type
,
11364 /* set as output */
11365 snd_hda_codec_write(codec
, nid
, 0,
11366 AC_VERB_SET_PIN_WIDGET_CONTROL
, pin_type
);
11367 snd_hda_codec_write(codec
, nid
, 0,
11368 AC_VERB_SET_AMP_GAIN_MUTE
, AMP_OUT_UNMUTE
);
11369 /* need the manual connection? */
11370 if (alc880_is_multi_pin(nid
)) {
11371 struct alc_spec
*spec
= codec
->spec
;
11372 int idx
= alc880_multi_pin_idx(nid
);
11373 snd_hda_codec_write(codec
, alc880_idx_to_selector(idx
), 0,
11374 AC_VERB_SET_CONNECT_SEL
,
11375 alc880_dac_to_idx(spec
->multiout
.dac_nids
[dac_idx
]));
11379 static void alc662_auto_init_multi_out(struct hda_codec
*codec
)
11381 struct alc_spec
*spec
= codec
->spec
;
11384 for (i
= 0; i
<= HDA_SIDE
; i
++) {
11385 hda_nid_t nid
= spec
->autocfg
.line_out_pins
[i
];
11386 int pin_type
= get_pin_type(spec
->autocfg
.line_out_type
);
11388 alc662_auto_set_output_and_unmute(codec
, nid
, pin_type
,
11393 static void alc662_auto_init_hp_out(struct hda_codec
*codec
)
11395 struct alc_spec
*spec
= codec
->spec
;
11398 pin
= spec
->autocfg
.hp_pins
[0];
11399 if (pin
) /* connect to front */
11401 alc662_auto_set_output_and_unmute(codec
, pin
, PIN_HP
, 0);
11404 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
11405 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
11407 static void alc662_auto_init_analog_input(struct hda_codec
*codec
)
11409 struct alc_spec
*spec
= codec
->spec
;
11412 for (i
= 0; i
< AUTO_PIN_LAST
; i
++) {
11413 hda_nid_t nid
= spec
->autocfg
.input_pins
[i
];
11414 if (alc662_is_input_pin(nid
)) {
11415 snd_hda_codec_write(codec
, nid
, 0,
11416 AC_VERB_SET_PIN_WIDGET_CONTROL
,
11417 (i
<= AUTO_PIN_FRONT_MIC
?
11418 PIN_VREF80
: PIN_IN
));
11419 if (nid
!= ALC662_PIN_CD_NID
)
11420 snd_hda_codec_write(codec
, nid
, 0,
11421 AC_VERB_SET_AMP_GAIN_MUTE
,
11427 static int alc662_parse_auto_config(struct hda_codec
*codec
)
11429 struct alc_spec
*spec
= codec
->spec
;
11431 static hda_nid_t alc662_ignore
[] = { 0x1d, 0 };
11433 err
= snd_hda_parse_pin_def_config(codec
, &spec
->autocfg
,
11437 if (!spec
->autocfg
.line_outs
)
11438 return 0; /* can't find valid BIOS pin config */
11440 err
= alc880_auto_fill_dac_nids(spec
, &spec
->autocfg
);
11443 err
= alc662_auto_create_multi_out_ctls(spec
, &spec
->autocfg
);
11446 err
= alc662_auto_create_extra_out(spec
,
11447 spec
->autocfg
.speaker_pins
[0],
11451 err
= alc662_auto_create_extra_out(spec
, spec
->autocfg
.hp_pins
[0],
11455 err
= alc662_auto_create_analog_input_ctls(spec
, &spec
->autocfg
);
11459 spec
->multiout
.max_channels
= spec
->multiout
.num_dacs
* 2;
11461 if (spec
->autocfg
.dig_out_pin
)
11462 spec
->multiout
.dig_out_nid
= ALC880_DIGOUT_NID
;
11464 if (spec
->kctl_alloc
)
11465 spec
->mixers
[spec
->num_mixers
++] = spec
->kctl_alloc
;
11467 spec
->num_mux_defs
= 1;
11468 spec
->input_mux
= &spec
->private_imux
;
11470 spec
->init_verbs
[spec
->num_init_verbs
++] = alc662_auto_init_verbs
;
11471 spec
->mixers
[spec
->num_mixers
] = alc662_capture_mixer
;
11472 spec
->num_mixers
++;
11476 /* additional initialization for auto-configuration model */
11477 static void alc662_auto_init(struct hda_codec
*codec
)
11479 alc662_auto_init_multi_out(codec
);
11480 alc662_auto_init_hp_out(codec
);
11481 alc662_auto_init_analog_input(codec
);
11484 static int patch_alc662(struct hda_codec
*codec
)
11486 struct alc_spec
*spec
;
11487 int err
, board_config
;
11489 spec
= kzalloc(sizeof(*spec
), GFP_KERNEL
);
11493 codec
->spec
= spec
;
11495 board_config
= snd_hda_check_board_config(codec
, ALC662_MODEL_LAST
,
11498 if (board_config
< 0) {
11499 printk(KERN_INFO
"hda_codec: Unknown model for ALC662, "
11500 "trying auto-probe from BIOS...\n");
11501 board_config
= ALC662_AUTO
;
11504 if (board_config
== ALC662_AUTO
) {
11505 /* automatic parse from the BIOS config */
11506 err
= alc662_parse_auto_config(codec
);
11512 "hda_codec: Cannot set up configuration "
11513 "from BIOS. Using base mode...\n");
11514 board_config
= ALC662_3ST_2ch_DIG
;
11518 if (board_config
!= ALC662_AUTO
)
11519 setup_preset(spec
, &alc662_presets
[board_config
]);
11521 spec
->stream_name_analog
= "ALC662 Analog";
11522 spec
->stream_analog_playback
= &alc662_pcm_analog_playback
;
11523 spec
->stream_analog_capture
= &alc662_pcm_analog_capture
;
11525 spec
->stream_name_digital
= "ALC662 Digital";
11526 spec
->stream_digital_playback
= &alc662_pcm_digital_playback
;
11527 spec
->stream_digital_capture
= &alc662_pcm_digital_capture
;
11529 if (!spec
->adc_nids
&& spec
->input_mux
) {
11530 spec
->adc_nids
= alc662_adc_nids
;
11531 spec
->num_adc_nids
= ARRAY_SIZE(alc662_adc_nids
);
11534 codec
->patch_ops
= alc_patch_ops
;
11535 if (board_config
== ALC662_AUTO
)
11536 spec
->init_hook
= alc662_auto_init
;
11544 struct hda_codec_preset snd_hda_preset_realtek
[] = {
11545 { .id
= 0x10ec0260, .name
= "ALC260", .patch
= patch_alc260
},
11546 { .id
= 0x10ec0262, .name
= "ALC262", .patch
= patch_alc262
},
11547 { .id
= 0x10ec0268, .name
= "ALC268", .patch
= patch_alc268
},
11548 { .id
= 0x10ec0861, .rev
= 0x100340, .name
= "ALC660",
11549 .patch
= patch_alc861
},
11550 { .id
= 0x10ec0660, .name
= "ALC660-VD", .patch
= patch_alc861vd
},
11551 { .id
= 0x10ec0861, .name
= "ALC861", .patch
= patch_alc861
},
11552 { .id
= 0x10ec0862, .name
= "ALC861-VD", .patch
= patch_alc861vd
},
11553 { .id
= 0x10ec0662, .rev
= 0x100002, .name
= "ALC662 rev2",
11554 .patch
= patch_alc883
},
11555 { .id
= 0x10ec0662, .rev
= 0x100101, .name
= "ALC662 rev1",
11556 .patch
= patch_alc662
},
11557 { .id
= 0x10ec0880, .name
= "ALC880", .patch
= patch_alc880
},
11558 { .id
= 0x10ec0882, .name
= "ALC882", .patch
= patch_alc882
},
11559 { .id
= 0x10ec0883, .name
= "ALC883", .patch
= patch_alc883
},
11560 { .id
= 0x10ec0885, .name
= "ALC885", .patch
= patch_alc882
},
11561 { .id
= 0x10ec0888, .name
= "ALC888", .patch
= patch_alc883
},
11562 {} /* terminator */