ALSA: hda: Fix quirk for Dell Inspiron 910
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / hda / patch_realtek.c
blob73ed47c0b3d1fa43dceb7641a7da0b5b60ec7c5e
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_beep.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 */
41 enum {
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
47 ALC880_Z71V,
48 ALC880_6ST,
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
54 ALC880_ASUS_DIG2,
55 ALC880_FUJITSU,
56 ALC880_UNIWILL_DIG,
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
61 ALC880_LG,
62 ALC880_LG_LW,
63 ALC880_MEDION_RIM,
64 #ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66 #endif
67 ALC880_AUTO,
68 ALC880_MODEL_LAST /* last tag */
71 /* ALC260 models */
72 enum {
73 ALC260_BASIC,
74 ALC260_HP,
75 ALC260_HP_DC7600,
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
78 ALC260_ACER,
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
81 ALC260_FAVORIT100,
82 #ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84 #endif
85 ALC260_AUTO,
86 ALC260_MODEL_LAST /* last tag */
89 /* ALC262 models */
90 enum {
91 ALC262_BASIC,
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
94 ALC262_FUJITSU,
95 ALC262_HP_BPC,
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
98 ALC262_HP_TC_T5735,
99 ALC262_HP_RP5700,
100 ALC262_BENQ_ED8,
101 ALC262_SONY_ASSAMD,
102 ALC262_BENQ_T31,
103 ALC262_ULTRA,
104 ALC262_LENOVO_3000,
105 ALC262_NEC,
106 ALC262_TOSHIBA_S06,
107 ALC262_TOSHIBA_RX1,
108 ALC262_TYAN,
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
113 /* ALC268 models */
114 enum {
115 ALC267_QUANTA_IL1,
116 ALC268_3ST,
117 ALC268_TOSHIBA,
118 ALC268_ACER,
119 ALC268_ACER_DMIC,
120 ALC268_ACER_ASPIRE_ONE,
121 ALC268_DELL,
122 ALC268_ZEPTO,
123 #ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125 #endif
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
130 /* ALC269 models */
131 enum {
132 ALC269_BASIC,
133 ALC269_QUANTA_FL1,
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
138 ALC269_FUJITSU,
139 ALC269_LIFEBOOK,
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
144 /* ALC861 models */
145 enum {
146 ALC861_3ST,
147 ALC660_3ST,
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
150 ALC861_UNIWILL_M31,
151 ALC861_TOSHIBA,
152 ALC861_ASUS,
153 ALC861_ASUS_LAPTOP,
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
158 /* ALC861-VD models */
159 enum {
160 ALC660VD_3ST,
161 ALC660VD_3ST_DIG,
162 ALC660VD_ASUS_V1S,
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
166 ALC861VD_LENOVO,
167 ALC861VD_DALLAS,
168 ALC861VD_HP,
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
173 /* ALC662 models */
174 enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
180 ALC662_ASUS_EEEPC_P701,
181 ALC662_ASUS_EEEPC_EP20,
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
197 ALC272_SAMSUNG_NC10,
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
202 /* ALC882 models */
203 enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
206 ALC882_ARIMA,
207 ALC882_W2JC,
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
210 ALC882_ASUS_A7M,
211 ALC885_MACPRO,
212 ALC885_MBA21,
213 ALC885_MBP3,
214 ALC885_MB5,
215 ALC885_MACMINI3,
216 ALC885_IMAC24,
217 ALC885_IMAC91,
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
224 ALC883_TARGA_8ch_DIG,
225 ALC883_ACER,
226 ALC883_ACER_ASPIRE,
227 ALC888_ACER_ASPIRE_4930G,
228 ALC888_ACER_ASPIRE_6530G,
229 ALC888_ACER_ASPIRE_8930G,
230 ALC888_ACER_ASPIRE_7730G,
231 ALC883_MEDION,
232 ALC883_MEDION_MD2,
233 ALC883_MEDION_WIM2160,
234 ALC883_LAPTOP_EAPD,
235 ALC883_LENOVO_101E_2ch,
236 ALC883_LENOVO_NB0763,
237 ALC888_LENOVO_MS7195_DIG,
238 ALC888_LENOVO_SKY,
239 ALC883_HAIER_W66,
240 ALC888_3ST_HP,
241 ALC888_6ST_DELL,
242 ALC883_MITAC,
243 ALC883_CLEVO_M540R,
244 ALC883_CLEVO_M720,
245 ALC883_FUJITSU_PI2515,
246 ALC888_FUJITSU_XA3530,
247 ALC883_3ST_6ch_INTEL,
248 ALC889A_INTEL,
249 ALC889_INTEL,
250 ALC888_ASUS_M90V,
251 ALC888_ASUS_EEE1601,
252 ALC889A_MB31,
253 ALC1200_ASUS_P5Q,
254 ALC883_SONY_VAIO_TT,
255 ALC882_AUTO,
256 ALC882_MODEL_LAST,
259 /* for GPIO Poll */
260 #define GPIO_MASK 0x03
262 /* extra amp-initialization sequence types */
263 enum {
264 ALC_INIT_NONE,
265 ALC_INIT_DEFAULT,
266 ALC_INIT_GPIO1,
267 ALC_INIT_GPIO2,
268 ALC_INIT_GPIO3,
271 struct alc_mic_route {
272 hda_nid_t pin;
273 unsigned char mux_idx;
274 unsigned char amix_idx;
277 #define MUX_IDX_UNDEF ((unsigned char)-1)
279 struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
291 struct alc_spec {
292 /* codec parameterization */
293 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
294 unsigned int num_mixers;
295 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
296 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
298 const struct hda_verb *init_verbs[10]; /* initialization verbs
299 * don't forget NULL
300 * termination!
302 unsigned int num_init_verbs;
304 char stream_name_analog[32]; /* analog PCM stream */
305 struct hda_pcm_stream *stream_analog_playback;
306 struct hda_pcm_stream *stream_analog_capture;
307 struct hda_pcm_stream *stream_analog_alt_playback;
308 struct hda_pcm_stream *stream_analog_alt_capture;
310 char stream_name_digital[32]; /* digital PCM stream */
311 struct hda_pcm_stream *stream_digital_playback;
312 struct hda_pcm_stream *stream_digital_capture;
314 /* playback */
315 struct hda_multi_out multiout; /* playback set-up
316 * max_channels, dacs must be set
317 * dig_out_nid and hp_nid are optional
319 hda_nid_t alt_dac_nid;
320 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
321 int dig_out_type;
323 /* capture */
324 unsigned int num_adc_nids;
325 hda_nid_t *adc_nids;
326 hda_nid_t *capsrc_nids;
327 hda_nid_t dig_in_nid; /* digital-in NID; optional */
329 /* capture source */
330 unsigned int num_mux_defs;
331 const struct hda_input_mux *input_mux;
332 unsigned int cur_mux[3];
333 struct alc_mic_route ext_mic;
334 struct alc_mic_route int_mic;
336 /* channel model */
337 const struct hda_channel_mode *channel_mode;
338 int num_channel_mode;
339 int need_dac_fix;
340 int const_channel_count;
341 int ext_channel_count;
343 /* PCM information */
344 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
346 /* dynamic controls, init_verbs and input_mux */
347 struct auto_pin_cfg autocfg;
348 struct alc_customize_define cdefine;
349 struct snd_array kctls;
350 struct hda_input_mux private_imux[3];
351 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
352 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
353 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
355 /* hooks */
356 void (*init_hook)(struct hda_codec *codec);
357 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
358 #ifdef CONFIG_SND_HDA_POWER_SAVE
359 void (*power_hook)(struct hda_codec *codec);
360 #endif
362 /* for pin sensing */
363 unsigned int sense_updated: 1;
364 unsigned int jack_present: 1;
365 unsigned int master_sw: 1;
366 unsigned int auto_mic:1;
368 /* other flags */
369 unsigned int no_analog :1; /* digital I/O only */
370 int init_amp;
372 /* for virtual master */
373 hda_nid_t vmaster_nid;
374 #ifdef CONFIG_SND_HDA_POWER_SAVE
375 struct hda_loopback_check loopback;
376 #endif
378 /* for PLL fix */
379 hda_nid_t pll_nid;
380 unsigned int pll_coef_idx, pll_coef_bit;
384 * configuration template - to be copied to the spec instance
386 struct alc_config_preset {
387 struct snd_kcontrol_new *mixers[5]; /* should be identical size
388 * with spec
390 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
391 const struct hda_verb *init_verbs[5];
392 unsigned int num_dacs;
393 hda_nid_t *dac_nids;
394 hda_nid_t dig_out_nid; /* optional */
395 hda_nid_t hp_nid; /* optional */
396 hda_nid_t *slave_dig_outs;
397 unsigned int num_adc_nids;
398 hda_nid_t *adc_nids;
399 hda_nid_t *capsrc_nids;
400 hda_nid_t dig_in_nid;
401 unsigned int num_channel_mode;
402 const struct hda_channel_mode *channel_mode;
403 int need_dac_fix;
404 int const_channel_count;
405 unsigned int num_mux_defs;
406 const struct hda_input_mux *input_mux;
407 void (*unsol_event)(struct hda_codec *, unsigned int);
408 void (*setup)(struct hda_codec *);
409 void (*init_hook)(struct hda_codec *);
410 #ifdef CONFIG_SND_HDA_POWER_SAVE
411 struct hda_amp_list *loopbacks;
412 void (*power_hook)(struct hda_codec *codec);
413 #endif
418 * input MUX handling
420 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
421 struct snd_ctl_elem_info *uinfo)
423 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
424 struct alc_spec *spec = codec->spec;
425 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
426 if (mux_idx >= spec->num_mux_defs)
427 mux_idx = 0;
428 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
429 mux_idx = 0;
430 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
433 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
434 struct snd_ctl_elem_value *ucontrol)
436 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
437 struct alc_spec *spec = codec->spec;
438 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
440 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
441 return 0;
444 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
445 struct snd_ctl_elem_value *ucontrol)
447 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
448 struct alc_spec *spec = codec->spec;
449 const struct hda_input_mux *imux;
450 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
451 unsigned int mux_idx;
452 hda_nid_t nid = spec->capsrc_nids ?
453 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
454 unsigned int type;
456 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
457 imux = &spec->input_mux[mux_idx];
458 if (!imux->num_items && mux_idx > 0)
459 imux = &spec->input_mux[0];
461 type = get_wcaps_type(get_wcaps(codec, nid));
462 if (type == AC_WID_AUD_MIX) {
463 /* Matrix-mixer style (e.g. ALC882) */
464 unsigned int *cur_val = &spec->cur_mux[adc_idx];
465 unsigned int i, idx;
467 idx = ucontrol->value.enumerated.item[0];
468 if (idx >= imux->num_items)
469 idx = imux->num_items - 1;
470 if (*cur_val == idx)
471 return 0;
472 for (i = 0; i < imux->num_items; i++) {
473 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
474 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
475 imux->items[i].index,
476 HDA_AMP_MUTE, v);
478 *cur_val = idx;
479 return 1;
480 } else {
481 /* MUX style (e.g. ALC880) */
482 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
483 &spec->cur_mux[adc_idx]);
488 * channel mode setting
490 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_info *uinfo)
493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
494 struct alc_spec *spec = codec->spec;
495 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
496 spec->num_channel_mode);
499 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
500 struct snd_ctl_elem_value *ucontrol)
502 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
503 struct alc_spec *spec = codec->spec;
504 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
505 spec->num_channel_mode,
506 spec->ext_channel_count);
509 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
510 struct snd_ctl_elem_value *ucontrol)
512 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
513 struct alc_spec *spec = codec->spec;
514 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
515 spec->num_channel_mode,
516 &spec->ext_channel_count);
517 if (err >= 0 && !spec->const_channel_count) {
518 spec->multiout.max_channels = spec->ext_channel_count;
519 if (spec->need_dac_fix)
520 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
522 return err;
526 * Control the mode of pin widget settings via the mixer. "pc" is used
527 * instead of "%" to avoid consequences of accidently treating the % as
528 * being part of a format specifier. Maximum allowed length of a value is
529 * 63 characters plus NULL terminator.
531 * Note: some retasking pin complexes seem to ignore requests for input
532 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
533 * are requested. Therefore order this list so that this behaviour will not
534 * cause problems when mixer clients move through the enum sequentially.
535 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
536 * March 2006.
538 static char *alc_pin_mode_names[] = {
539 "Mic 50pc bias", "Mic 80pc bias",
540 "Line in", "Line out", "Headphone out",
542 static unsigned char alc_pin_mode_values[] = {
543 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
545 /* The control can present all 5 options, or it can limit the options based
546 * in the pin being assumed to be exclusively an input or an output pin. In
547 * addition, "input" pins may or may not process the mic bias option
548 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
549 * accept requests for bias as of chip versions up to March 2006) and/or
550 * wiring in the computer.
552 #define ALC_PIN_DIR_IN 0x00
553 #define ALC_PIN_DIR_OUT 0x01
554 #define ALC_PIN_DIR_INOUT 0x02
555 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
556 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
558 /* Info about the pin modes supported by the different pin direction modes.
559 * For each direction the minimum and maximum values are given.
561 static signed char alc_pin_mode_dir_info[5][2] = {
562 { 0, 2 }, /* ALC_PIN_DIR_IN */
563 { 3, 4 }, /* ALC_PIN_DIR_OUT */
564 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
565 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
566 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
568 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
569 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
570 #define alc_pin_mode_n_items(_dir) \
571 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
573 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_info *uinfo)
576 unsigned int item_num = uinfo->value.enumerated.item;
577 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
579 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
580 uinfo->count = 1;
581 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
583 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
584 item_num = alc_pin_mode_min(dir);
585 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
586 return 0;
589 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
590 struct snd_ctl_elem_value *ucontrol)
592 unsigned int i;
593 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594 hda_nid_t nid = kcontrol->private_value & 0xffff;
595 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
596 long *valp = ucontrol->value.integer.value;
597 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
598 AC_VERB_GET_PIN_WIDGET_CONTROL,
599 0x00);
601 /* Find enumerated value for current pinctl setting */
602 i = alc_pin_mode_min(dir);
603 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
604 i++;
605 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
606 return 0;
609 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
610 struct snd_ctl_elem_value *ucontrol)
612 signed int change;
613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
614 hda_nid_t nid = kcontrol->private_value & 0xffff;
615 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
616 long val = *ucontrol->value.integer.value;
617 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
618 AC_VERB_GET_PIN_WIDGET_CONTROL,
619 0x00);
621 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
622 val = alc_pin_mode_min(dir);
624 change = pinctl != alc_pin_mode_values[val];
625 if (change) {
626 /* Set pin mode to that requested */
627 snd_hda_codec_write_cache(codec, nid, 0,
628 AC_VERB_SET_PIN_WIDGET_CONTROL,
629 alc_pin_mode_values[val]);
631 /* Also enable the retasking pin's input/output as required
632 * for the requested pin mode. Enum values of 2 or less are
633 * input modes.
635 * Dynamically switching the input/output buffers probably
636 * reduces noise slightly (particularly on input) so we'll
637 * do it. However, having both input and output buffers
638 * enabled simultaneously doesn't seem to be problematic if
639 * this turns out to be necessary in the future.
641 if (val <= 2) {
642 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
643 HDA_AMP_MUTE, HDA_AMP_MUTE);
644 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
645 HDA_AMP_MUTE, 0);
646 } else {
647 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
648 HDA_AMP_MUTE, HDA_AMP_MUTE);
649 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
650 HDA_AMP_MUTE, 0);
653 return change;
656 #define ALC_PIN_MODE(xname, nid, dir) \
657 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
658 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
659 .info = alc_pin_mode_info, \
660 .get = alc_pin_mode_get, \
661 .put = alc_pin_mode_put, \
662 .private_value = nid | (dir<<16) }
664 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
665 * together using a mask with more than one bit set. This control is
666 * currently used only by the ALC260 test model. At this stage they are not
667 * needed for any "production" models.
669 #ifdef CONFIG_SND_DEBUG
670 #define alc_gpio_data_info snd_ctl_boolean_mono_info
672 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 hda_nid_t nid = kcontrol->private_value & 0xffff;
677 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
678 long *valp = ucontrol->value.integer.value;
679 unsigned int val = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_GPIO_DATA, 0x00);
682 *valp = (val & mask) != 0;
683 return 0;
685 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
686 struct snd_ctl_elem_value *ucontrol)
688 signed int change;
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 hda_nid_t nid = kcontrol->private_value & 0xffff;
691 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
692 long val = *ucontrol->value.integer.value;
693 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA,
695 0x00);
697 /* Set/unset the masked GPIO bit(s) as needed */
698 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
699 if (val == 0)
700 gpio_data &= ~mask;
701 else
702 gpio_data |= mask;
703 snd_hda_codec_write_cache(codec, nid, 0,
704 AC_VERB_SET_GPIO_DATA, gpio_data);
706 return change;
708 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711 .info = alc_gpio_data_info, \
712 .get = alc_gpio_data_get, \
713 .put = alc_gpio_data_put, \
714 .private_value = nid | (mask<<16) }
715 #endif /* CONFIG_SND_DEBUG */
717 /* A switch control to allow the enabling of the digital IO pins on the
718 * ALC260. This is incredibly simplistic; the intention of this control is
719 * to provide something in the test model allowing digital outputs to be
720 * identified if present. If models are found which can utilise these
721 * outputs a more complete mixer control can be devised for those models if
722 * necessary.
724 #ifdef CONFIG_SND_DEBUG
725 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
727 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_value *ucontrol)
730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
731 hda_nid_t nid = kcontrol->private_value & 0xffff;
732 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
733 long *valp = ucontrol->value.integer.value;
734 unsigned int val = snd_hda_codec_read(codec, nid, 0,
735 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
737 *valp = (val & mask) != 0;
738 return 0;
740 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
741 struct snd_ctl_elem_value *ucontrol)
743 signed int change;
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 hda_nid_t nid = kcontrol->private_value & 0xffff;
746 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
747 long val = *ucontrol->value.integer.value;
748 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
749 AC_VERB_GET_DIGI_CONVERT_1,
750 0x00);
752 /* Set/unset the masked control bit(s) as needed */
753 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
754 if (val==0)
755 ctrl_data &= ~mask;
756 else
757 ctrl_data |= mask;
758 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
759 ctrl_data);
761 return change;
763 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
764 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
765 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
766 .info = alc_spdif_ctrl_info, \
767 .get = alc_spdif_ctrl_get, \
768 .put = alc_spdif_ctrl_put, \
769 .private_value = nid | (mask<<16) }
770 #endif /* CONFIG_SND_DEBUG */
772 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
773 * Again, this is only used in the ALC26x test models to help identify when
774 * the EAPD line must be asserted for features to work.
776 #ifdef CONFIG_SND_DEBUG
777 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
779 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
782 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783 hda_nid_t nid = kcontrol->private_value & 0xffff;
784 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785 long *valp = ucontrol->value.integer.value;
786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
787 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
789 *valp = (val & mask) != 0;
790 return 0;
793 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
796 int change;
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
802 AC_VERB_GET_EAPD_BTLENABLE,
803 0x00);
805 /* Set/unset the masked control bit(s) as needed */
806 change = (!val ? 0 : mask) != (ctrl_data & mask);
807 if (!val)
808 ctrl_data &= ~mask;
809 else
810 ctrl_data |= mask;
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
812 ctrl_data);
814 return change;
817 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
820 .info = alc_eapd_ctrl_info, \
821 .get = alc_eapd_ctrl_get, \
822 .put = alc_eapd_ctrl_put, \
823 .private_value = nid | (mask<<16) }
824 #endif /* CONFIG_SND_DEBUG */
827 * set up the input pin config (depending on the given auto-pin type)
829 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
830 int auto_pin_type)
832 unsigned int val = PIN_IN;
834 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
835 unsigned int pincap;
836 pincap = snd_hda_query_pin_caps(codec, nid);
837 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
838 if (pincap & AC_PINCAP_VREF_80)
839 val = PIN_VREF80;
840 else if (pincap & AC_PINCAP_VREF_50)
841 val = PIN_VREF50;
842 else if (pincap & AC_PINCAP_VREF_100)
843 val = PIN_VREF100;
844 else if (pincap & AC_PINCAP_VREF_GRD)
845 val = PIN_VREFGRD;
847 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
852 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
854 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
855 return;
856 spec->mixers[spec->num_mixers++] = mix;
859 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
861 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
862 return;
863 spec->init_verbs[spec->num_init_verbs++] = verb;
867 * set up from the preset table
869 static void setup_preset(struct hda_codec *codec,
870 const struct alc_config_preset *preset)
872 struct alc_spec *spec = codec->spec;
873 int i;
875 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
876 add_mixer(spec, preset->mixers[i]);
877 spec->cap_mixer = preset->cap_mixer;
878 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
879 i++)
880 add_verb(spec, preset->init_verbs[i]);
882 spec->channel_mode = preset->channel_mode;
883 spec->num_channel_mode = preset->num_channel_mode;
884 spec->need_dac_fix = preset->need_dac_fix;
885 spec->const_channel_count = preset->const_channel_count;
887 if (preset->const_channel_count)
888 spec->multiout.max_channels = preset->const_channel_count;
889 else
890 spec->multiout.max_channels = spec->channel_mode[0].channels;
891 spec->ext_channel_count = spec->channel_mode[0].channels;
893 spec->multiout.num_dacs = preset->num_dacs;
894 spec->multiout.dac_nids = preset->dac_nids;
895 spec->multiout.dig_out_nid = preset->dig_out_nid;
896 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
897 spec->multiout.hp_nid = preset->hp_nid;
899 spec->num_mux_defs = preset->num_mux_defs;
900 if (!spec->num_mux_defs)
901 spec->num_mux_defs = 1;
902 spec->input_mux = preset->input_mux;
904 spec->num_adc_nids = preset->num_adc_nids;
905 spec->adc_nids = preset->adc_nids;
906 spec->capsrc_nids = preset->capsrc_nids;
907 spec->dig_in_nid = preset->dig_in_nid;
909 spec->unsol_event = preset->unsol_event;
910 spec->init_hook = preset->init_hook;
911 #ifdef CONFIG_SND_HDA_POWER_SAVE
912 spec->power_hook = preset->power_hook;
913 spec->loopback.amplist = preset->loopbacks;
914 #endif
916 if (preset->setup)
917 preset->setup(codec);
920 /* Enable GPIO mask and set output */
921 static struct hda_verb alc_gpio1_init_verbs[] = {
922 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
923 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
924 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
928 static struct hda_verb alc_gpio2_init_verbs[] = {
929 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
930 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
931 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
935 static struct hda_verb alc_gpio3_init_verbs[] = {
936 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
937 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
938 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
943 * Fix hardware PLL issue
944 * On some codecs, the analog PLL gating control must be off while
945 * the default value is 1.
947 static void alc_fix_pll(struct hda_codec *codec)
949 struct alc_spec *spec = codec->spec;
950 unsigned int val;
952 if (!spec->pll_nid)
953 return;
954 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
955 spec->pll_coef_idx);
956 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
957 AC_VERB_GET_PROC_COEF, 0);
958 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
959 spec->pll_coef_idx);
960 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
961 val & ~(1 << spec->pll_coef_bit));
964 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
965 unsigned int coef_idx, unsigned int coef_bit)
967 struct alc_spec *spec = codec->spec;
968 spec->pll_nid = nid;
969 spec->pll_coef_idx = coef_idx;
970 spec->pll_coef_bit = coef_bit;
971 alc_fix_pll(codec);
974 static void alc_automute_pin(struct hda_codec *codec)
976 struct alc_spec *spec = codec->spec;
977 unsigned int nid = spec->autocfg.hp_pins[0];
978 int i;
980 if (!nid)
981 return;
982 spec->jack_present = snd_hda_jack_detect(codec, nid);
983 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
984 nid = spec->autocfg.speaker_pins[i];
985 if (!nid)
986 break;
987 snd_hda_codec_write(codec, nid, 0,
988 AC_VERB_SET_PIN_WIDGET_CONTROL,
989 spec->jack_present ? 0 : PIN_OUT);
993 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
994 hda_nid_t nid)
996 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
997 int i, nums;
999 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1000 for (i = 0; i < nums; i++)
1001 if (conn[i] == nid)
1002 return i;
1003 return -1;
1006 static void alc_mic_automute(struct hda_codec *codec)
1008 struct alc_spec *spec = codec->spec;
1009 struct alc_mic_route *dead, *alive;
1010 unsigned int present, type;
1011 hda_nid_t cap_nid;
1013 if (!spec->auto_mic)
1014 return;
1015 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1016 return;
1017 if (snd_BUG_ON(!spec->adc_nids))
1018 return;
1020 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1022 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1023 if (present) {
1024 alive = &spec->ext_mic;
1025 dead = &spec->int_mic;
1026 } else {
1027 alive = &spec->int_mic;
1028 dead = &spec->ext_mic;
1031 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1032 if (type == AC_WID_AUD_MIX) {
1033 /* Matrix-mixer style (e.g. ALC882) */
1034 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1035 alive->mux_idx,
1036 HDA_AMP_MUTE, 0);
1037 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1038 dead->mux_idx,
1039 HDA_AMP_MUTE, HDA_AMP_MUTE);
1040 } else {
1041 /* MUX style (e.g. ALC880) */
1042 snd_hda_codec_write_cache(codec, cap_nid, 0,
1043 AC_VERB_SET_CONNECT_SEL,
1044 alive->mux_idx);
1047 /* FIXME: analog mixer */
1050 /* unsolicited event for HP jack sensing */
1051 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1053 if (codec->vendor_id == 0x10ec0880)
1054 res >>= 28;
1055 else
1056 res >>= 26;
1057 switch (res) {
1058 case ALC880_HP_EVENT:
1059 alc_automute_pin(codec);
1060 break;
1061 case ALC880_MIC_EVENT:
1062 alc_mic_automute(codec);
1063 break;
1067 static void alc_inithook(struct hda_codec *codec)
1069 alc_automute_pin(codec);
1070 alc_mic_automute(codec);
1073 /* additional initialization for ALC888 variants */
1074 static void alc888_coef_init(struct hda_codec *codec)
1076 unsigned int tmp;
1078 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1079 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1080 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1081 if ((tmp & 0xf0) == 0x20)
1082 /* alc888S-VC */
1083 snd_hda_codec_read(codec, 0x20, 0,
1084 AC_VERB_SET_PROC_COEF, 0x830);
1085 else
1086 /* alc888-VB */
1087 snd_hda_codec_read(codec, 0x20, 0,
1088 AC_VERB_SET_PROC_COEF, 0x3030);
1091 static void alc889_coef_init(struct hda_codec *codec)
1093 unsigned int tmp;
1095 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1096 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1097 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1098 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1101 /* turn on/off EAPD control (only if available) */
1102 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1104 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1105 return;
1106 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1107 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1108 on ? 2 : 0);
1111 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1113 unsigned int tmp;
1115 switch (type) {
1116 case ALC_INIT_GPIO1:
1117 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1118 break;
1119 case ALC_INIT_GPIO2:
1120 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1121 break;
1122 case ALC_INIT_GPIO3:
1123 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1124 break;
1125 case ALC_INIT_DEFAULT:
1126 switch (codec->vendor_id) {
1127 case 0x10ec0260:
1128 set_eapd(codec, 0x0f, 1);
1129 set_eapd(codec, 0x10, 1);
1130 break;
1131 case 0x10ec0262:
1132 case 0x10ec0267:
1133 case 0x10ec0268:
1134 case 0x10ec0269:
1135 case 0x10ec0270:
1136 case 0x10ec0272:
1137 case 0x10ec0660:
1138 case 0x10ec0662:
1139 case 0x10ec0663:
1140 case 0x10ec0862:
1141 case 0x10ec0889:
1142 set_eapd(codec, 0x14, 1);
1143 set_eapd(codec, 0x15, 1);
1144 break;
1146 switch (codec->vendor_id) {
1147 case 0x10ec0260:
1148 snd_hda_codec_write(codec, 0x1a, 0,
1149 AC_VERB_SET_COEF_INDEX, 7);
1150 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1151 AC_VERB_GET_PROC_COEF, 0);
1152 snd_hda_codec_write(codec, 0x1a, 0,
1153 AC_VERB_SET_COEF_INDEX, 7);
1154 snd_hda_codec_write(codec, 0x1a, 0,
1155 AC_VERB_SET_PROC_COEF,
1156 tmp | 0x2010);
1157 break;
1158 case 0x10ec0262:
1159 case 0x10ec0880:
1160 case 0x10ec0882:
1161 case 0x10ec0883:
1162 case 0x10ec0885:
1163 case 0x10ec0887:
1164 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1165 alc889_coef_init(codec);
1166 break;
1167 case 0x10ec0888:
1168 alc888_coef_init(codec);
1169 break;
1170 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1171 case 0x10ec0267:
1172 case 0x10ec0268:
1173 snd_hda_codec_write(codec, 0x20, 0,
1174 AC_VERB_SET_COEF_INDEX, 7);
1175 tmp = snd_hda_codec_read(codec, 0x20, 0,
1176 AC_VERB_GET_PROC_COEF, 0);
1177 snd_hda_codec_write(codec, 0x20, 0,
1178 AC_VERB_SET_COEF_INDEX, 7);
1179 snd_hda_codec_write(codec, 0x20, 0,
1180 AC_VERB_SET_PROC_COEF,
1181 tmp | 0x3000);
1182 break;
1183 #endif /* XXX */
1185 break;
1189 static void alc_init_auto_hp(struct hda_codec *codec)
1191 struct alc_spec *spec = codec->spec;
1193 if (!spec->autocfg.hp_pins[0])
1194 return;
1196 if (!spec->autocfg.speaker_pins[0]) {
1197 if (spec->autocfg.line_out_pins[0] &&
1198 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1199 spec->autocfg.speaker_pins[0] =
1200 spec->autocfg.line_out_pins[0];
1201 else
1202 return;
1205 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1206 spec->autocfg.hp_pins[0]);
1207 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1208 AC_VERB_SET_UNSOLICITED_ENABLE,
1209 AC_USRSP_EN | ALC880_HP_EVENT);
1210 spec->unsol_event = alc_sku_unsol_event;
1213 static void alc_init_auto_mic(struct hda_codec *codec)
1215 struct alc_spec *spec = codec->spec;
1216 struct auto_pin_cfg *cfg = &spec->autocfg;
1217 hda_nid_t fixed, ext;
1218 int i;
1220 /* there must be only two mic inputs exclusively */
1221 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1222 if (cfg->input_pins[i])
1223 return;
1225 fixed = ext = 0;
1226 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1227 hda_nid_t nid = cfg->input_pins[i];
1228 unsigned int defcfg;
1229 if (!nid)
1230 return;
1231 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1232 switch (get_defcfg_connect(defcfg)) {
1233 case AC_JACK_PORT_FIXED:
1234 if (fixed)
1235 return; /* already occupied */
1236 fixed = nid;
1237 break;
1238 case AC_JACK_PORT_COMPLEX:
1239 if (ext)
1240 return; /* already occupied */
1241 ext = nid;
1242 break;
1243 default:
1244 return; /* invalid entry */
1247 if (!ext || !fixed)
1248 return;
1249 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1250 return; /* no unsol support */
1251 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1252 ext, fixed);
1253 spec->ext_mic.pin = ext;
1254 spec->int_mic.pin = fixed;
1255 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1256 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1257 spec->auto_mic = 1;
1258 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1259 AC_VERB_SET_UNSOLICITED_ENABLE,
1260 AC_USRSP_EN | ALC880_MIC_EVENT);
1261 spec->unsol_event = alc_sku_unsol_event;
1264 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1266 unsigned int ass, tmp, i;
1267 unsigned nid = 0;
1268 struct alc_spec *spec = codec->spec;
1270 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1272 ass = codec->subsystem_id & 0xffff;
1273 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1274 goto do_sku;
1276 nid = 0x1d;
1277 if (codec->vendor_id == 0x10ec0260)
1278 nid = 0x17;
1279 ass = snd_hda_codec_get_pincfg(codec, nid);
1281 if (!(ass & 1)) {
1282 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1283 codec->chip_name, ass);
1284 return -1;
1287 /* check sum */
1288 tmp = 0;
1289 for (i = 1; i < 16; i++) {
1290 if ((ass >> i) & 1)
1291 tmp++;
1293 if (((ass >> 16) & 0xf) != tmp)
1294 return -1;
1296 spec->cdefine.port_connectivity = ass >> 30;
1297 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1298 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1299 spec->cdefine.customization = ass >> 8;
1300 do_sku:
1301 spec->cdefine.sku_cfg = ass;
1302 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1303 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1304 spec->cdefine.swap = (ass & 0x2) >> 1;
1305 spec->cdefine.override = ass & 0x1;
1307 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1308 nid, spec->cdefine.sku_cfg);
1309 snd_printd("SKU: port_connectivity=0x%x\n",
1310 spec->cdefine.port_connectivity);
1311 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1312 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1313 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1314 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1315 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1316 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1317 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1319 return 0;
1322 /* check subsystem ID and set up device-specific initialization;
1323 * return 1 if initialized, 0 if invalid SSID
1325 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1326 * 31 ~ 16 : Manufacture ID
1327 * 15 ~ 8 : SKU ID
1328 * 7 ~ 0 : Assembly ID
1329 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1331 static int alc_subsystem_id(struct hda_codec *codec,
1332 hda_nid_t porta, hda_nid_t porte,
1333 hda_nid_t portd, hda_nid_t porti)
1335 unsigned int ass, tmp, i;
1336 unsigned nid;
1337 struct alc_spec *spec = codec->spec;
1339 ass = codec->subsystem_id & 0xffff;
1340 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1341 goto do_sku;
1343 /* invalid SSID, check the special NID pin defcfg instead */
1345 * 31~30 : port connectivity
1346 * 29~21 : reserve
1347 * 20 : PCBEEP input
1348 * 19~16 : Check sum (15:1)
1349 * 15~1 : Custom
1350 * 0 : override
1352 nid = 0x1d;
1353 if (codec->vendor_id == 0x10ec0260)
1354 nid = 0x17;
1355 ass = snd_hda_codec_get_pincfg(codec, nid);
1356 snd_printd("realtek: No valid SSID, "
1357 "checking pincfg 0x%08x for NID 0x%x\n",
1358 ass, nid);
1359 if (!(ass & 1))
1360 return 0;
1361 if ((ass >> 30) != 1) /* no physical connection */
1362 return 0;
1364 /* check sum */
1365 tmp = 0;
1366 for (i = 1; i < 16; i++) {
1367 if ((ass >> i) & 1)
1368 tmp++;
1370 if (((ass >> 16) & 0xf) != tmp)
1371 return 0;
1372 do_sku:
1373 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1374 ass & 0xffff, codec->vendor_id);
1376 * 0 : override
1377 * 1 : Swap Jack
1378 * 2 : 0 --> Desktop, 1 --> Laptop
1379 * 3~5 : External Amplifier control
1380 * 7~6 : Reserved
1382 tmp = (ass & 0x38) >> 3; /* external Amp control */
1383 switch (tmp) {
1384 case 1:
1385 spec->init_amp = ALC_INIT_GPIO1;
1386 break;
1387 case 3:
1388 spec->init_amp = ALC_INIT_GPIO2;
1389 break;
1390 case 7:
1391 spec->init_amp = ALC_INIT_GPIO3;
1392 break;
1393 case 5:
1394 default:
1395 spec->init_amp = ALC_INIT_DEFAULT;
1396 break;
1399 /* is laptop or Desktop and enable the function "Mute internal speaker
1400 * when the external headphone out jack is plugged"
1402 if (!(ass & 0x8000))
1403 return 1;
1405 * 10~8 : Jack location
1406 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1407 * 14~13: Resvered
1408 * 15 : 1 --> enable the function "Mute internal speaker
1409 * when the external headphone out jack is plugged"
1411 if (!spec->autocfg.hp_pins[0]) {
1412 hda_nid_t nid;
1413 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1414 if (tmp == 0)
1415 nid = porta;
1416 else if (tmp == 1)
1417 nid = porte;
1418 else if (tmp == 2)
1419 nid = portd;
1420 else if (tmp == 3)
1421 nid = porti;
1422 else
1423 return 1;
1424 for (i = 0; i < spec->autocfg.line_outs; i++)
1425 if (spec->autocfg.line_out_pins[i] == nid)
1426 return 1;
1427 spec->autocfg.hp_pins[0] = nid;
1430 alc_init_auto_hp(codec);
1431 alc_init_auto_mic(codec);
1432 return 1;
1435 static void alc_ssid_check(struct hda_codec *codec,
1436 hda_nid_t porta, hda_nid_t porte,
1437 hda_nid_t portd, hda_nid_t porti)
1439 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1440 struct alc_spec *spec = codec->spec;
1441 snd_printd("realtek: "
1442 "Enable default setup for auto mode as fallback\n");
1443 spec->init_amp = ALC_INIT_DEFAULT;
1444 alc_init_auto_hp(codec);
1445 alc_init_auto_mic(codec);
1450 * Fix-up pin default configurations and add default verbs
1453 struct alc_pincfg {
1454 hda_nid_t nid;
1455 u32 val;
1458 struct alc_fixup {
1459 const struct alc_pincfg *pins;
1460 const struct hda_verb *verbs;
1463 static void alc_pick_fixup(struct hda_codec *codec,
1464 const struct snd_pci_quirk *quirk,
1465 const struct alc_fixup *fix,
1466 int pre_init)
1468 const struct alc_pincfg *cfg;
1470 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1471 if (!quirk)
1472 return;
1473 fix += quirk->value;
1474 cfg = fix->pins;
1475 if (pre_init && cfg) {
1476 #ifdef CONFIG_SND_DEBUG_VERBOSE
1477 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1478 codec->chip_name, quirk->name);
1479 #endif
1480 for (; cfg->nid; cfg++)
1481 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1483 if (!pre_init && fix->verbs) {
1484 #ifdef CONFIG_SND_DEBUG_VERBOSE
1485 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1486 codec->chip_name, quirk->name);
1487 #endif
1488 add_verb(codec->spec, fix->verbs);
1492 static int alc_read_coef_idx(struct hda_codec *codec,
1493 unsigned int coef_idx)
1495 unsigned int val;
1496 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1497 coef_idx);
1498 val = snd_hda_codec_read(codec, 0x20, 0,
1499 AC_VERB_GET_PROC_COEF, 0);
1500 return val;
1504 * ALC888
1508 * 2ch mode
1510 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1511 /* Mic-in jack as mic in */
1512 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1513 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1514 /* Line-in jack as Line in */
1515 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1516 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1517 /* Line-Out as Front */
1518 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1519 { } /* end */
1523 * 4ch mode
1525 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1526 /* Mic-in jack as mic in */
1527 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1528 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1529 /* Line-in jack as Surround */
1530 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1531 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1532 /* Line-Out as Front */
1533 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1534 { } /* end */
1538 * 6ch mode
1540 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1541 /* Mic-in jack as CLFE */
1542 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1543 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1544 /* Line-in jack as Surround */
1545 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1546 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1547 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1548 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1549 { } /* end */
1553 * 8ch mode
1555 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1556 /* Mic-in jack as CLFE */
1557 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1558 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1559 /* Line-in jack as Surround */
1560 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1561 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1562 /* Line-Out as Side */
1563 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1564 { } /* end */
1567 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1568 { 2, alc888_4ST_ch2_intel_init },
1569 { 4, alc888_4ST_ch4_intel_init },
1570 { 6, alc888_4ST_ch6_intel_init },
1571 { 8, alc888_4ST_ch8_intel_init },
1575 * ALC888 Fujitsu Siemens Amillo xa3530
1578 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1579 /* Front Mic: set to PIN_IN (empty by default) */
1580 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1581 /* Connect Internal HP to Front */
1582 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1583 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1584 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1585 /* Connect Bass HP to Front */
1586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1587 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1588 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1589 /* Connect Line-Out side jack (SPDIF) to Side */
1590 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1591 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1592 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1593 /* Connect Mic jack to CLFE */
1594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1596 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1597 /* Connect Line-in jack to Surround */
1598 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1599 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1600 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1601 /* Connect HP out jack to Front */
1602 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1603 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1604 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1605 /* Enable unsolicited event for HP jack and Line-out jack */
1606 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1607 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1611 static void alc_automute_amp(struct hda_codec *codec)
1613 struct alc_spec *spec = codec->spec;
1614 unsigned int mute;
1615 hda_nid_t nid;
1616 int i;
1618 spec->jack_present = 0;
1619 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1620 nid = spec->autocfg.hp_pins[i];
1621 if (!nid)
1622 break;
1623 if (snd_hda_jack_detect(codec, nid)) {
1624 spec->jack_present = 1;
1625 break;
1629 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1630 /* Toggle internal speakers muting */
1631 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1632 nid = spec->autocfg.speaker_pins[i];
1633 if (!nid)
1634 break;
1635 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1636 HDA_AMP_MUTE, mute);
1640 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1641 unsigned int res)
1643 if (codec->vendor_id == 0x10ec0880)
1644 res >>= 28;
1645 else
1646 res >>= 26;
1647 if (res == ALC880_HP_EVENT)
1648 alc_automute_amp(codec);
1651 static void alc889_automute_setup(struct hda_codec *codec)
1653 struct alc_spec *spec = codec->spec;
1655 spec->autocfg.hp_pins[0] = 0x15;
1656 spec->autocfg.speaker_pins[0] = 0x14;
1657 spec->autocfg.speaker_pins[1] = 0x16;
1658 spec->autocfg.speaker_pins[2] = 0x17;
1659 spec->autocfg.speaker_pins[3] = 0x19;
1660 spec->autocfg.speaker_pins[4] = 0x1a;
1663 static void alc889_intel_init_hook(struct hda_codec *codec)
1665 alc889_coef_init(codec);
1666 alc_automute_amp(codec);
1669 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1671 struct alc_spec *spec = codec->spec;
1673 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1674 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1675 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1676 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1680 * ALC888 Acer Aspire 4930G model
1683 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1684 /* Front Mic: set to PIN_IN (empty by default) */
1685 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1686 /* Unselect Front Mic by default in input mixer 3 */
1687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1688 /* Enable unsolicited event for HP jack */
1689 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1690 /* Connect Internal HP to front */
1691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1693 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1694 /* Connect HP out to front */
1695 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1702 * ALC888 Acer Aspire 6530G model
1705 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1706 /* Route to built-in subwoofer as well as speakers */
1707 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1708 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1709 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1710 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1711 /* Bias voltage on for external mic port */
1712 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1713 /* Front Mic: set to PIN_IN (empty by default) */
1714 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1715 /* Unselect Front Mic by default in input mixer 3 */
1716 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1717 /* Enable unsolicited event for HP jack */
1718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1719 /* Enable speaker output */
1720 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1722 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1723 /* Enable headphone output */
1724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1726 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1727 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1732 * ALC889 Acer Aspire 8930G model
1735 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1736 /* Front Mic: set to PIN_IN (empty by default) */
1737 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1738 /* Unselect Front Mic by default in input mixer 3 */
1739 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1740 /* Enable unsolicited event for HP jack */
1741 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1742 /* Connect Internal Front to Front */
1743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1744 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1745 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1746 /* Connect Internal Rear to Rear */
1747 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1748 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1749 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1750 /* Connect Internal CLFE to CLFE */
1751 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1753 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1754 /* Connect HP out to Front */
1755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1758 /* Enable all DACs */
1759 /* DAC DISABLE/MUTE 1? */
1760 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1761 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1762 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1763 /* DAC DISABLE/MUTE 2? */
1764 /* some bit here disables the other DACs. Init=0x4900 */
1765 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1766 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1767 /* DMIC fix
1768 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1769 * which makes the stereo useless. However, either the mic or the ALC889
1770 * makes the signal become a difference/sum signal instead of standard
1771 * stereo, which is annoying. So instead we flip this bit which makes the
1772 * codec replicate the sum signal to both channels, turning it into a
1773 * normal mono mic.
1775 /* DMIC_CONTROL? Init value = 0x0001 */
1776 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1777 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1781 static struct hda_input_mux alc888_2_capture_sources[2] = {
1782 /* Front mic only available on one ADC */
1784 .num_items = 4,
1785 .items = {
1786 { "Mic", 0x0 },
1787 { "Line", 0x2 },
1788 { "CD", 0x4 },
1789 { "Front Mic", 0xb },
1793 .num_items = 3,
1794 .items = {
1795 { "Mic", 0x0 },
1796 { "Line", 0x2 },
1797 { "CD", 0x4 },
1802 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1803 /* Interal mic only available on one ADC */
1805 .num_items = 5,
1806 .items = {
1807 { "Ext Mic", 0x0 },
1808 { "Line In", 0x2 },
1809 { "CD", 0x4 },
1810 { "Input Mix", 0xa },
1811 { "Int Mic", 0xb },
1815 .num_items = 4,
1816 .items = {
1817 { "Ext Mic", 0x0 },
1818 { "Line In", 0x2 },
1819 { "CD", 0x4 },
1820 { "Input Mix", 0xa },
1825 static struct hda_input_mux alc889_capture_sources[3] = {
1826 /* Digital mic only available on first "ADC" */
1828 .num_items = 5,
1829 .items = {
1830 { "Mic", 0x0 },
1831 { "Line", 0x2 },
1832 { "CD", 0x4 },
1833 { "Front Mic", 0xb },
1834 { "Input Mix", 0xa },
1838 .num_items = 4,
1839 .items = {
1840 { "Mic", 0x0 },
1841 { "Line", 0x2 },
1842 { "CD", 0x4 },
1843 { "Input Mix", 0xa },
1847 .num_items = 4,
1848 .items = {
1849 { "Mic", 0x0 },
1850 { "Line", 0x2 },
1851 { "CD", 0x4 },
1852 { "Input Mix", 0xa },
1857 static struct snd_kcontrol_new alc888_base_mixer[] = {
1858 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1859 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1860 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1861 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1862 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1863 HDA_OUTPUT),
1864 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1865 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1866 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1867 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1868 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1869 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1870 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1871 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1872 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1874 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1876 { } /* end */
1879 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1882 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1883 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1884 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1885 HDA_OUTPUT),
1886 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1887 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1888 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1889 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1890 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1892 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1893 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1894 { } /* end */
1898 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1900 struct alc_spec *spec = codec->spec;
1902 spec->autocfg.hp_pins[0] = 0x15;
1903 spec->autocfg.speaker_pins[0] = 0x14;
1904 spec->autocfg.speaker_pins[1] = 0x16;
1905 spec->autocfg.speaker_pins[2] = 0x17;
1908 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1910 struct alc_spec *spec = codec->spec;
1912 spec->autocfg.hp_pins[0] = 0x15;
1913 spec->autocfg.speaker_pins[0] = 0x14;
1914 spec->autocfg.speaker_pins[1] = 0x16;
1915 spec->autocfg.speaker_pins[2] = 0x17;
1918 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1920 struct alc_spec *spec = codec->spec;
1922 spec->autocfg.hp_pins[0] = 0x15;
1923 spec->autocfg.speaker_pins[0] = 0x14;
1924 spec->autocfg.speaker_pins[1] = 0x16;
1925 spec->autocfg.speaker_pins[2] = 0x1b;
1929 * ALC880 3-stack model
1931 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1932 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1933 * F-Mic = 0x1b, HP = 0x19
1936 static hda_nid_t alc880_dac_nids[4] = {
1937 /* front, rear, clfe, rear_surr */
1938 0x02, 0x05, 0x04, 0x03
1941 static hda_nid_t alc880_adc_nids[3] = {
1942 /* ADC0-2 */
1943 0x07, 0x08, 0x09,
1946 /* The datasheet says the node 0x07 is connected from inputs,
1947 * but it shows zero connection in the real implementation on some devices.
1948 * Note: this is a 915GAV bug, fixed on 915GLV
1950 static hda_nid_t alc880_adc_nids_alt[2] = {
1951 /* ADC1-2 */
1952 0x08, 0x09,
1955 #define ALC880_DIGOUT_NID 0x06
1956 #define ALC880_DIGIN_NID 0x0a
1958 static struct hda_input_mux alc880_capture_source = {
1959 .num_items = 4,
1960 .items = {
1961 { "Mic", 0x0 },
1962 { "Front Mic", 0x3 },
1963 { "Line", 0x2 },
1964 { "CD", 0x4 },
1968 /* channel source setting (2/6 channel selection for 3-stack) */
1969 /* 2ch mode */
1970 static struct hda_verb alc880_threestack_ch2_init[] = {
1971 /* set line-in to input, mute it */
1972 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1973 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1974 /* set mic-in to input vref 80%, mute it */
1975 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1976 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1977 { } /* end */
1980 /* 6ch mode */
1981 static struct hda_verb alc880_threestack_ch6_init[] = {
1982 /* set line-in to output, unmute it */
1983 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1984 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1985 /* set mic-in to output, unmute it */
1986 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1987 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1988 { } /* end */
1991 static struct hda_channel_mode alc880_threestack_modes[2] = {
1992 { 2, alc880_threestack_ch2_init },
1993 { 6, alc880_threestack_ch6_init },
1996 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1997 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1998 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1999 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2000 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2001 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2003 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2004 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2009 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2011 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2012 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2016 .name = "Channel Mode",
2017 .info = alc_ch_mode_info,
2018 .get = alc_ch_mode_get,
2019 .put = alc_ch_mode_put,
2021 { } /* end */
2024 /* capture mixer elements */
2025 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2026 struct snd_ctl_elem_info *uinfo)
2028 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2029 struct alc_spec *spec = codec->spec;
2030 int err;
2032 mutex_lock(&codec->control_mutex);
2033 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2034 HDA_INPUT);
2035 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2036 mutex_unlock(&codec->control_mutex);
2037 return err;
2040 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2041 unsigned int size, unsigned int __user *tlv)
2043 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2044 struct alc_spec *spec = codec->spec;
2045 int err;
2047 mutex_lock(&codec->control_mutex);
2048 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2049 HDA_INPUT);
2050 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2051 mutex_unlock(&codec->control_mutex);
2052 return err;
2055 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2056 struct snd_ctl_elem_value *ucontrol);
2058 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2059 struct snd_ctl_elem_value *ucontrol,
2060 getput_call_t func)
2062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2063 struct alc_spec *spec = codec->spec;
2064 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2065 int err;
2067 mutex_lock(&codec->control_mutex);
2068 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2069 3, 0, HDA_INPUT);
2070 err = func(kcontrol, ucontrol);
2071 mutex_unlock(&codec->control_mutex);
2072 return err;
2075 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2076 struct snd_ctl_elem_value *ucontrol)
2078 return alc_cap_getput_caller(kcontrol, ucontrol,
2079 snd_hda_mixer_amp_volume_get);
2082 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2083 struct snd_ctl_elem_value *ucontrol)
2085 return alc_cap_getput_caller(kcontrol, ucontrol,
2086 snd_hda_mixer_amp_volume_put);
2089 /* capture mixer elements */
2090 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2092 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2093 struct snd_ctl_elem_value *ucontrol)
2095 return alc_cap_getput_caller(kcontrol, ucontrol,
2096 snd_hda_mixer_amp_switch_get);
2099 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2100 struct snd_ctl_elem_value *ucontrol)
2102 return alc_cap_getput_caller(kcontrol, ucontrol,
2103 snd_hda_mixer_amp_switch_put);
2106 #define _DEFINE_CAPMIX(num) \
2108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2109 .name = "Capture Switch", \
2110 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2111 .count = num, \
2112 .info = alc_cap_sw_info, \
2113 .get = alc_cap_sw_get, \
2114 .put = alc_cap_sw_put, \
2115 }, \
2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2118 .name = "Capture Volume", \
2119 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2120 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2121 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2122 .count = num, \
2123 .info = alc_cap_vol_info, \
2124 .get = alc_cap_vol_get, \
2125 .put = alc_cap_vol_put, \
2126 .tlv = { .c = alc_cap_vol_tlv }, \
2129 #define _DEFINE_CAPSRC(num) \
2131 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2132 /* .name = "Capture Source", */ \
2133 .name = "Input Source", \
2134 .count = num, \
2135 .info = alc_mux_enum_info, \
2136 .get = alc_mux_enum_get, \
2137 .put = alc_mux_enum_put, \
2140 #define DEFINE_CAPMIX(num) \
2141 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2142 _DEFINE_CAPMIX(num), \
2143 _DEFINE_CAPSRC(num), \
2144 { } /* end */ \
2147 #define DEFINE_CAPMIX_NOSRC(num) \
2148 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2149 _DEFINE_CAPMIX(num), \
2150 { } /* end */ \
2153 /* up to three ADCs */
2154 DEFINE_CAPMIX(1);
2155 DEFINE_CAPMIX(2);
2156 DEFINE_CAPMIX(3);
2157 DEFINE_CAPMIX_NOSRC(1);
2158 DEFINE_CAPMIX_NOSRC(2);
2159 DEFINE_CAPMIX_NOSRC(3);
2162 * ALC880 5-stack model
2164 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2165 * Side = 0x02 (0xd)
2166 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2167 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2170 /* additional mixers to alc880_three_stack_mixer */
2171 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2172 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2173 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2174 { } /* end */
2177 /* channel source setting (6/8 channel selection for 5-stack) */
2178 /* 6ch mode */
2179 static struct hda_verb alc880_fivestack_ch6_init[] = {
2180 /* set line-in to input, mute it */
2181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2182 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2183 { } /* end */
2186 /* 8ch mode */
2187 static struct hda_verb alc880_fivestack_ch8_init[] = {
2188 /* set line-in to output, unmute it */
2189 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2190 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2191 { } /* end */
2194 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2195 { 6, alc880_fivestack_ch6_init },
2196 { 8, alc880_fivestack_ch8_init },
2201 * ALC880 6-stack model
2203 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2204 * Side = 0x05 (0x0f)
2205 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2206 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2209 static hda_nid_t alc880_6st_dac_nids[4] = {
2210 /* front, rear, clfe, rear_surr */
2211 0x02, 0x03, 0x04, 0x05
2214 static struct hda_input_mux alc880_6stack_capture_source = {
2215 .num_items = 4,
2216 .items = {
2217 { "Mic", 0x0 },
2218 { "Front Mic", 0x1 },
2219 { "Line", 0x2 },
2220 { "CD", 0x4 },
2224 /* fixed 8-channels */
2225 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2226 { 8, NULL },
2229 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2230 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2231 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2232 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2233 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2234 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2235 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2236 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2237 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2239 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2240 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2241 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2242 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2243 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2246 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2247 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2250 .name = "Channel Mode",
2251 .info = alc_ch_mode_info,
2252 .get = alc_ch_mode_get,
2253 .put = alc_ch_mode_put,
2255 { } /* end */
2260 * ALC880 W810 model
2262 * W810 has rear IO for:
2263 * Front (DAC 02)
2264 * Surround (DAC 03)
2265 * Center/LFE (DAC 04)
2266 * Digital out (06)
2268 * The system also has a pair of internal speakers, and a headphone jack.
2269 * These are both connected to Line2 on the codec, hence to DAC 02.
2271 * There is a variable resistor to control the speaker or headphone
2272 * volume. This is a hardware-only device without a software API.
2274 * Plugging headphones in will disable the internal speakers. This is
2275 * implemented in hardware, not via the driver using jack sense. In
2276 * a similar fashion, plugging into the rear socket marked "front" will
2277 * disable both the speakers and headphones.
2279 * For input, there's a microphone jack, and an "audio in" jack.
2280 * These may not do anything useful with this driver yet, because I
2281 * haven't setup any initialization verbs for these yet...
2284 static hda_nid_t alc880_w810_dac_nids[3] = {
2285 /* front, rear/surround, clfe */
2286 0x02, 0x03, 0x04
2289 /* fixed 6 channels */
2290 static struct hda_channel_mode alc880_w810_modes[1] = {
2291 { 6, NULL }
2294 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2295 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2296 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2297 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2298 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2299 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2300 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2301 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2302 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2303 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2305 { } /* end */
2310 * Z710V model
2312 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2313 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2314 * Line = 0x1a
2317 static hda_nid_t alc880_z71v_dac_nids[1] = {
2318 0x02
2320 #define ALC880_Z71V_HP_DAC 0x03
2322 /* fixed 2 channels */
2323 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2324 { 2, NULL }
2327 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2328 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2329 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2330 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2331 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2332 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2333 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2334 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2335 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2336 { } /* end */
2341 * ALC880 F1734 model
2343 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2344 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2347 static hda_nid_t alc880_f1734_dac_nids[1] = {
2348 0x03
2350 #define ALC880_F1734_HP_DAC 0x02
2352 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2353 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2354 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2355 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2356 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2357 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2358 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2360 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2361 { } /* end */
2364 static struct hda_input_mux alc880_f1734_capture_source = {
2365 .num_items = 2,
2366 .items = {
2367 { "Mic", 0x1 },
2368 { "CD", 0x4 },
2374 * ALC880 ASUS model
2376 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2377 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2378 * Mic = 0x18, Line = 0x1a
2381 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2382 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2384 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2385 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2386 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2387 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2388 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2389 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2390 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2391 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2392 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2393 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2394 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2395 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2396 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2400 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2401 .name = "Channel Mode",
2402 .info = alc_ch_mode_info,
2403 .get = alc_ch_mode_get,
2404 .put = alc_ch_mode_put,
2406 { } /* end */
2410 * ALC880 ASUS W1V model
2412 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2413 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2414 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2417 /* additional mixers to alc880_asus_mixer */
2418 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2419 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2420 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2421 { } /* end */
2424 /* TCL S700 */
2425 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2426 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2427 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2428 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2429 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2430 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2433 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2434 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2435 { } /* end */
2438 /* Uniwill */
2439 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2441 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2442 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2443 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2444 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2445 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2446 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2447 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2448 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2449 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2450 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2451 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2452 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2458 .name = "Channel Mode",
2459 .info = alc_ch_mode_info,
2460 .get = alc_ch_mode_get,
2461 .put = alc_ch_mode_put,
2463 { } /* end */
2466 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2467 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2468 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2469 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2470 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2471 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2472 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2473 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2474 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2475 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2476 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2477 { } /* end */
2480 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2481 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2482 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2483 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2484 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2487 { } /* end */
2491 * virtual master controls
2495 * slave controls for virtual master
2497 static const char *alc_slave_vols[] = {
2498 "Front Playback Volume",
2499 "Surround Playback Volume",
2500 "Center Playback Volume",
2501 "LFE Playback Volume",
2502 "Side Playback Volume",
2503 "Headphone Playback Volume",
2504 "Speaker Playback Volume",
2505 "Mono Playback Volume",
2506 "Line-Out Playback Volume",
2507 "PCM Playback Volume",
2508 NULL,
2511 static const char *alc_slave_sws[] = {
2512 "Front Playback Switch",
2513 "Surround Playback Switch",
2514 "Center Playback Switch",
2515 "LFE Playback Switch",
2516 "Side Playback Switch",
2517 "Headphone Playback Switch",
2518 "Speaker Playback Switch",
2519 "Mono Playback Switch",
2520 "IEC958 Playback Switch",
2521 "Line-Out Playback Switch",
2522 "PCM Playback Switch",
2523 NULL,
2527 * build control elements
2530 #define NID_MAPPING (-1)
2532 #define SUBDEV_SPEAKER_ (0 << 6)
2533 #define SUBDEV_HP_ (1 << 6)
2534 #define SUBDEV_LINE_ (2 << 6)
2535 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2536 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2537 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2539 static void alc_free_kctls(struct hda_codec *codec);
2541 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2542 /* additional beep mixers; the actual parameters are overwritten at build */
2543 static struct snd_kcontrol_new alc_beep_mixer[] = {
2544 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2545 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2546 { } /* end */
2548 #endif
2550 static int alc_build_controls(struct hda_codec *codec)
2552 struct alc_spec *spec = codec->spec;
2553 struct snd_kcontrol *kctl = NULL;
2554 struct snd_kcontrol_new *knew;
2555 int i, j, err;
2556 unsigned int u;
2557 hda_nid_t nid;
2559 for (i = 0; i < spec->num_mixers; i++) {
2560 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2561 if (err < 0)
2562 return err;
2564 if (spec->cap_mixer) {
2565 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2566 if (err < 0)
2567 return err;
2569 if (spec->multiout.dig_out_nid) {
2570 err = snd_hda_create_spdif_out_ctls(codec,
2571 spec->multiout.dig_out_nid);
2572 if (err < 0)
2573 return err;
2574 if (!spec->no_analog) {
2575 err = snd_hda_create_spdif_share_sw(codec,
2576 &spec->multiout);
2577 if (err < 0)
2578 return err;
2579 spec->multiout.share_spdif = 1;
2582 if (spec->dig_in_nid) {
2583 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2584 if (err < 0)
2585 return err;
2588 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2589 /* create beep controls if needed */
2590 if (spec->beep_amp) {
2591 struct snd_kcontrol_new *knew;
2592 for (knew = alc_beep_mixer; knew->name; knew++) {
2593 struct snd_kcontrol *kctl;
2594 kctl = snd_ctl_new1(knew, codec);
2595 if (!kctl)
2596 return -ENOMEM;
2597 kctl->private_value = spec->beep_amp;
2598 err = snd_hda_ctl_add(codec, 0, kctl);
2599 if (err < 0)
2600 return err;
2603 #endif
2605 /* if we have no master control, let's create it */
2606 if (!spec->no_analog &&
2607 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2608 unsigned int vmaster_tlv[4];
2609 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2610 HDA_OUTPUT, vmaster_tlv);
2611 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2612 vmaster_tlv, alc_slave_vols);
2613 if (err < 0)
2614 return err;
2616 if (!spec->no_analog &&
2617 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2618 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2619 NULL, alc_slave_sws);
2620 if (err < 0)
2621 return err;
2624 /* assign Capture Source enums to NID */
2625 if (spec->capsrc_nids || spec->adc_nids) {
2626 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2627 if (!kctl)
2628 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2629 for (i = 0; kctl && i < kctl->count; i++) {
2630 hda_nid_t *nids = spec->capsrc_nids;
2631 if (!nids)
2632 nids = spec->adc_nids;
2633 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2634 if (err < 0)
2635 return err;
2638 if (spec->cap_mixer) {
2639 const char *kname = kctl ? kctl->id.name : NULL;
2640 for (knew = spec->cap_mixer; knew->name; knew++) {
2641 if (kname && strcmp(knew->name, kname) == 0)
2642 continue;
2643 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2644 for (i = 0; kctl && i < kctl->count; i++) {
2645 err = snd_hda_add_nid(codec, kctl, i,
2646 spec->adc_nids[i]);
2647 if (err < 0)
2648 return err;
2653 /* other nid->control mapping */
2654 for (i = 0; i < spec->num_mixers; i++) {
2655 for (knew = spec->mixers[i]; knew->name; knew++) {
2656 if (knew->iface != NID_MAPPING)
2657 continue;
2658 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2659 if (kctl == NULL)
2660 continue;
2661 u = knew->subdevice;
2662 for (j = 0; j < 4; j++, u >>= 8) {
2663 nid = u & 0x3f;
2664 if (nid == 0)
2665 continue;
2666 switch (u & 0xc0) {
2667 case SUBDEV_SPEAKER_:
2668 nid = spec->autocfg.speaker_pins[nid];
2669 break;
2670 case SUBDEV_LINE_:
2671 nid = spec->autocfg.line_out_pins[nid];
2672 break;
2673 case SUBDEV_HP_:
2674 nid = spec->autocfg.hp_pins[nid];
2675 break;
2676 default:
2677 continue;
2679 err = snd_hda_add_nid(codec, kctl, 0, nid);
2680 if (err < 0)
2681 return err;
2683 u = knew->private_value;
2684 for (j = 0; j < 4; j++, u >>= 8) {
2685 nid = u & 0xff;
2686 if (nid == 0)
2687 continue;
2688 err = snd_hda_add_nid(codec, kctl, 0, nid);
2689 if (err < 0)
2690 return err;
2695 alc_free_kctls(codec); /* no longer needed */
2697 return 0;
2702 * initialize the codec volumes, etc
2706 * generic initialization of ADC, input mixers and output mixers
2708 static struct hda_verb alc880_volume_init_verbs[] = {
2710 * Unmute ADC0-2 and set the default input to mic-in
2712 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2714 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2716 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2717 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2719 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2720 * mixer widget
2721 * Note: PASD motherboards uses the Line In 2 as the input for front
2722 * panel mic (mic 2)
2724 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2727 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2728 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2729 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2730 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2734 * Set up output mixers (0x0c - 0x0f)
2736 /* set vol=0 to output mixers */
2737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2740 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2741 /* set up input amps for analog loopback */
2742 /* Amp Indices: DAC = 0, mixer = 1 */
2743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2756 * 3-stack pin configuration:
2757 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2759 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2761 * preset connection lists of input pins
2762 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2764 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2765 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2766 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2769 * Set pin mode and muting
2771 /* set front pin widgets 0x14 for output */
2772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2774 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2776 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2777 /* Mic2 (as headphone out) for HP output */
2778 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2779 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2780 /* Line In pin widget for input */
2781 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2782 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2783 /* Line2 (as front mic) pin widget for input and vref at 80% */
2784 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2785 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2786 /* CD pin widget for input */
2787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2793 * 5-stack pin configuration:
2794 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2795 * line-in/side = 0x1a, f-mic = 0x1b
2797 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2799 * preset connection lists of input pins
2800 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2802 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2803 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2806 * Set pin mode and muting
2808 /* set pin widgets 0x14-0x17 for output */
2809 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2811 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2813 /* unmute pins for output (no gain on this amp) */
2814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2816 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2817 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2819 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2822 /* Mic2 (as headphone out) for HP output */
2823 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2825 /* Line In pin widget for input */
2826 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2828 /* Line2 (as front mic) pin widget for input and vref at 80% */
2829 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2831 /* CD pin widget for input */
2832 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2838 * W810 pin configuration:
2839 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2841 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2842 /* hphone/speaker input selector: front DAC */
2843 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2849 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2850 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2852 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2853 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2859 * Z71V pin configuration:
2860 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2862 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2863 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2864 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2865 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2868 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2869 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2871 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2877 * 6-stack pin configuration:
2878 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2879 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2881 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2882 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2885 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2888 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2889 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2890 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2891 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2893 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2894 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2895 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2896 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2897 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2898 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2900 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2907 * Uniwill pin configuration:
2908 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2909 * line = 0x1a
2911 static struct hda_verb alc880_uniwill_init_verbs[] = {
2912 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2915 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2916 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2919 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2921 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2922 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2923 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2924 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2925 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2926 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2927 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2929 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2930 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2931 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2932 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2933 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2934 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2935 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2936 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2937 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2939 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2940 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2946 * Uniwill P53
2947 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2949 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2950 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2956 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2957 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2965 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2966 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2967 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2968 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2969 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2970 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2972 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2973 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2978 static struct hda_verb alc880_beep_init_verbs[] = {
2979 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2983 /* auto-toggle front mic */
2984 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2986 unsigned int present;
2987 unsigned char bits;
2989 present = snd_hda_jack_detect(codec, 0x18);
2990 bits = present ? HDA_AMP_MUTE : 0;
2991 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2994 static void alc880_uniwill_setup(struct hda_codec *codec)
2996 struct alc_spec *spec = codec->spec;
2998 spec->autocfg.hp_pins[0] = 0x14;
2999 spec->autocfg.speaker_pins[0] = 0x15;
3000 spec->autocfg.speaker_pins[0] = 0x16;
3003 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3005 alc_automute_amp(codec);
3006 alc880_uniwill_mic_automute(codec);
3009 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3010 unsigned int res)
3012 /* Looks like the unsol event is incompatible with the standard
3013 * definition. 4bit tag is placed at 28 bit!
3015 switch (res >> 28) {
3016 case ALC880_MIC_EVENT:
3017 alc880_uniwill_mic_automute(codec);
3018 break;
3019 default:
3020 alc_automute_amp_unsol_event(codec, res);
3021 break;
3025 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3027 struct alc_spec *spec = codec->spec;
3029 spec->autocfg.hp_pins[0] = 0x14;
3030 spec->autocfg.speaker_pins[0] = 0x15;
3033 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3035 unsigned int present;
3037 present = snd_hda_codec_read(codec, 0x21, 0,
3038 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3039 present &= HDA_AMP_VOLMASK;
3040 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3041 HDA_AMP_VOLMASK, present);
3042 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3043 HDA_AMP_VOLMASK, present);
3046 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3047 unsigned int res)
3049 /* Looks like the unsol event is incompatible with the standard
3050 * definition. 4bit tag is placed at 28 bit!
3052 if ((res >> 28) == ALC880_DCVOL_EVENT)
3053 alc880_uniwill_p53_dcvol_automute(codec);
3054 else
3055 alc_automute_amp_unsol_event(codec, res);
3059 * F1734 pin configuration:
3060 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3062 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3063 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3064 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3065 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3066 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3067 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3071 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3072 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3076 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3077 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3078 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3082 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3084 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3085 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3091 * ASUS pin configuration:
3092 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3094 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3095 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3096 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3097 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3098 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3102 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3103 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3104 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3106 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3109 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3110 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3111 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3112 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3114 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3115 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3116 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3117 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3122 /* Enable GPIO mask and set output */
3123 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3124 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3125 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3127 /* Clevo m520g init */
3128 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3129 /* headphone output */
3130 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3131 /* line-out */
3132 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3133 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3134 /* Line-in */
3135 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3137 /* CD */
3138 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3139 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3140 /* Mic1 (rear panel) */
3141 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3142 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3143 /* Mic2 (front panel) */
3144 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3145 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3146 /* headphone */
3147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3148 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3149 /* change to EAPD mode */
3150 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3151 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3156 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3157 /* change to EAPD mode */
3158 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3159 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3161 /* Headphone output */
3162 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3163 /* Front output*/
3164 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3165 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3167 /* Line In pin widget for input */
3168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3169 /* CD pin widget for input */
3170 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3171 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3174 /* change to EAPD mode */
3175 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3176 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3182 * LG m1 express dual
3184 * Pin assignment:
3185 * Rear Line-In/Out (blue): 0x14
3186 * Build-in Mic-In: 0x15
3187 * Speaker-out: 0x17
3188 * HP-Out (green): 0x1b
3189 * Mic-In/Out (red): 0x19
3190 * SPDIF-Out: 0x1e
3193 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3194 static hda_nid_t alc880_lg_dac_nids[3] = {
3195 0x05, 0x02, 0x03
3198 /* seems analog CD is not working */
3199 static struct hda_input_mux alc880_lg_capture_source = {
3200 .num_items = 3,
3201 .items = {
3202 { "Mic", 0x1 },
3203 { "Line", 0x5 },
3204 { "Internal Mic", 0x6 },
3208 /* 2,4,6 channel modes */
3209 static struct hda_verb alc880_lg_ch2_init[] = {
3210 /* set line-in and mic-in to input */
3211 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3212 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3216 static struct hda_verb alc880_lg_ch4_init[] = {
3217 /* set line-in to out and mic-in to input */
3218 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3219 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3223 static struct hda_verb alc880_lg_ch6_init[] = {
3224 /* set line-in and mic-in to output */
3225 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3226 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3230 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3231 { 2, alc880_lg_ch2_init },
3232 { 4, alc880_lg_ch4_init },
3233 { 6, alc880_lg_ch6_init },
3236 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3237 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3238 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3239 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3240 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3241 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3242 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3243 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3244 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3246 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3249 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3250 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3252 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3253 .name = "Channel Mode",
3254 .info = alc_ch_mode_info,
3255 .get = alc_ch_mode_get,
3256 .put = alc_ch_mode_put,
3258 { } /* end */
3261 static struct hda_verb alc880_lg_init_verbs[] = {
3262 /* set capture source to mic-in */
3263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3266 /* mute all amp mixer inputs */
3267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3270 /* line-in to input */
3271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3273 /* built-in mic */
3274 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3275 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3276 /* speaker-out */
3277 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3278 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3279 /* mic-in to input */
3280 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3281 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3282 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3283 /* HP-out */
3284 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3286 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3287 /* jack sense */
3288 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3292 /* toggle speaker-output according to the hp-jack state */
3293 static void alc880_lg_setup(struct hda_codec *codec)
3295 struct alc_spec *spec = codec->spec;
3297 spec->autocfg.hp_pins[0] = 0x1b;
3298 spec->autocfg.speaker_pins[0] = 0x17;
3302 * LG LW20
3304 * Pin assignment:
3305 * Speaker-out: 0x14
3306 * Mic-In: 0x18
3307 * Built-in Mic-In: 0x19
3308 * Line-In: 0x1b
3309 * HP-Out: 0x1a
3310 * SPDIF-Out: 0x1e
3313 static struct hda_input_mux alc880_lg_lw_capture_source = {
3314 .num_items = 3,
3315 .items = {
3316 { "Mic", 0x0 },
3317 { "Internal Mic", 0x1 },
3318 { "Line In", 0x2 },
3322 #define alc880_lg_lw_modes alc880_threestack_modes
3324 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3325 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3326 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3327 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3328 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3329 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3330 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3331 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3332 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3337 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3338 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3340 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3341 .name = "Channel Mode",
3342 .info = alc_ch_mode_info,
3343 .get = alc_ch_mode_get,
3344 .put = alc_ch_mode_put,
3346 { } /* end */
3349 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3350 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3351 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3352 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3354 /* set capture source to mic-in */
3355 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3357 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3358 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3359 /* speaker-out */
3360 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3362 /* HP-out */
3363 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3364 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3365 /* mic-in to input */
3366 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3368 /* built-in mic */
3369 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3370 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3371 /* jack sense */
3372 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3376 /* toggle speaker-output according to the hp-jack state */
3377 static void alc880_lg_lw_setup(struct hda_codec *codec)
3379 struct alc_spec *spec = codec->spec;
3381 spec->autocfg.hp_pins[0] = 0x1b;
3382 spec->autocfg.speaker_pins[0] = 0x14;
3385 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3386 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3387 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3389 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3390 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3391 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3392 { } /* end */
3395 static struct hda_input_mux alc880_medion_rim_capture_source = {
3396 .num_items = 2,
3397 .items = {
3398 { "Mic", 0x0 },
3399 { "Internal Mic", 0x1 },
3403 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3404 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3407 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3409 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3410 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3411 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3412 /* Mic2 (as headphone out) for HP output */
3413 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3414 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3415 /* Internal Speaker */
3416 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3417 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3419 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3420 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3422 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3426 /* toggle speaker-output according to the hp-jack state */
3427 static void alc880_medion_rim_automute(struct hda_codec *codec)
3429 struct alc_spec *spec = codec->spec;
3430 alc_automute_amp(codec);
3431 /* toggle EAPD */
3432 if (spec->jack_present)
3433 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3434 else
3435 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3438 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3439 unsigned int res)
3441 /* Looks like the unsol event is incompatible with the standard
3442 * definition. 4bit tag is placed at 28 bit!
3444 if ((res >> 28) == ALC880_HP_EVENT)
3445 alc880_medion_rim_automute(codec);
3448 static void alc880_medion_rim_setup(struct hda_codec *codec)
3450 struct alc_spec *spec = codec->spec;
3452 spec->autocfg.hp_pins[0] = 0x14;
3453 spec->autocfg.speaker_pins[0] = 0x1b;
3456 #ifdef CONFIG_SND_HDA_POWER_SAVE
3457 static struct hda_amp_list alc880_loopbacks[] = {
3458 { 0x0b, HDA_INPUT, 0 },
3459 { 0x0b, HDA_INPUT, 1 },
3460 { 0x0b, HDA_INPUT, 2 },
3461 { 0x0b, HDA_INPUT, 3 },
3462 { 0x0b, HDA_INPUT, 4 },
3463 { } /* end */
3466 static struct hda_amp_list alc880_lg_loopbacks[] = {
3467 { 0x0b, HDA_INPUT, 1 },
3468 { 0x0b, HDA_INPUT, 6 },
3469 { 0x0b, HDA_INPUT, 7 },
3470 { } /* end */
3472 #endif
3475 * Common callbacks
3478 static int alc_init(struct hda_codec *codec)
3480 struct alc_spec *spec = codec->spec;
3481 unsigned int i;
3483 alc_fix_pll(codec);
3484 alc_auto_init_amp(codec, spec->init_amp);
3486 for (i = 0; i < spec->num_init_verbs; i++)
3487 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3489 if (spec->init_hook)
3490 spec->init_hook(codec);
3492 #ifdef CONFIG_SND_HDA_POWER_SAVE
3493 if (codec->patch_ops.check_power_status)
3494 codec->patch_ops.check_power_status(codec, 0x01);
3495 #endif
3496 return 0;
3499 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3501 struct alc_spec *spec = codec->spec;
3503 if (spec->unsol_event)
3504 spec->unsol_event(codec, res);
3507 #ifdef CONFIG_SND_HDA_POWER_SAVE
3508 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3510 struct alc_spec *spec = codec->spec;
3511 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3513 #endif
3516 * Analog playback callbacks
3518 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3519 struct hda_codec *codec,
3520 struct snd_pcm_substream *substream)
3522 struct alc_spec *spec = codec->spec;
3523 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3524 hinfo);
3527 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3528 struct hda_codec *codec,
3529 unsigned int stream_tag,
3530 unsigned int format,
3531 struct snd_pcm_substream *substream)
3533 struct alc_spec *spec = codec->spec;
3534 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3535 stream_tag, format, substream);
3538 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3539 struct hda_codec *codec,
3540 struct snd_pcm_substream *substream)
3542 struct alc_spec *spec = codec->spec;
3543 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3547 * Digital out
3549 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3550 struct hda_codec *codec,
3551 struct snd_pcm_substream *substream)
3553 struct alc_spec *spec = codec->spec;
3554 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3557 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3558 struct hda_codec *codec,
3559 unsigned int stream_tag,
3560 unsigned int format,
3561 struct snd_pcm_substream *substream)
3563 struct alc_spec *spec = codec->spec;
3564 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3565 stream_tag, format, substream);
3568 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3569 struct hda_codec *codec,
3570 struct snd_pcm_substream *substream)
3572 struct alc_spec *spec = codec->spec;
3573 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3576 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3577 struct hda_codec *codec,
3578 struct snd_pcm_substream *substream)
3580 struct alc_spec *spec = codec->spec;
3581 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3585 * Analog capture
3587 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3588 struct hda_codec *codec,
3589 unsigned int stream_tag,
3590 unsigned int format,
3591 struct snd_pcm_substream *substream)
3593 struct alc_spec *spec = codec->spec;
3595 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3596 stream_tag, 0, format);
3597 return 0;
3600 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3601 struct hda_codec *codec,
3602 struct snd_pcm_substream *substream)
3604 struct alc_spec *spec = codec->spec;
3606 snd_hda_codec_cleanup_stream(codec,
3607 spec->adc_nids[substream->number + 1]);
3608 return 0;
3614 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3615 .substreams = 1,
3616 .channels_min = 2,
3617 .channels_max = 8,
3618 /* NID is set in alc_build_pcms */
3619 .ops = {
3620 .open = alc880_playback_pcm_open,
3621 .prepare = alc880_playback_pcm_prepare,
3622 .cleanup = alc880_playback_pcm_cleanup
3626 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3627 .substreams = 1,
3628 .channels_min = 2,
3629 .channels_max = 2,
3630 /* NID is set in alc_build_pcms */
3633 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3634 .substreams = 1,
3635 .channels_min = 2,
3636 .channels_max = 2,
3637 /* NID is set in alc_build_pcms */
3640 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3641 .substreams = 2, /* can be overridden */
3642 .channels_min = 2,
3643 .channels_max = 2,
3644 /* NID is set in alc_build_pcms */
3645 .ops = {
3646 .prepare = alc880_alt_capture_pcm_prepare,
3647 .cleanup = alc880_alt_capture_pcm_cleanup
3651 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3652 .substreams = 1,
3653 .channels_min = 2,
3654 .channels_max = 2,
3655 /* NID is set in alc_build_pcms */
3656 .ops = {
3657 .open = alc880_dig_playback_pcm_open,
3658 .close = alc880_dig_playback_pcm_close,
3659 .prepare = alc880_dig_playback_pcm_prepare,
3660 .cleanup = alc880_dig_playback_pcm_cleanup
3664 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3665 .substreams = 1,
3666 .channels_min = 2,
3667 .channels_max = 2,
3668 /* NID is set in alc_build_pcms */
3671 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3672 static struct hda_pcm_stream alc_pcm_null_stream = {
3673 .substreams = 0,
3674 .channels_min = 0,
3675 .channels_max = 0,
3678 static int alc_build_pcms(struct hda_codec *codec)
3680 struct alc_spec *spec = codec->spec;
3681 struct hda_pcm *info = spec->pcm_rec;
3682 int i;
3684 codec->num_pcms = 1;
3685 codec->pcm_info = info;
3687 if (spec->no_analog)
3688 goto skip_analog;
3690 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3691 "%s Analog", codec->chip_name);
3692 info->name = spec->stream_name_analog;
3694 if (spec->stream_analog_playback) {
3695 if (snd_BUG_ON(!spec->multiout.dac_nids))
3696 return -EINVAL;
3697 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3698 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3700 if (spec->stream_analog_capture) {
3701 if (snd_BUG_ON(!spec->adc_nids))
3702 return -EINVAL;
3703 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3704 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3707 if (spec->channel_mode) {
3708 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3709 for (i = 0; i < spec->num_channel_mode; i++) {
3710 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3711 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3716 skip_analog:
3717 /* SPDIF for stream index #1 */
3718 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3719 snprintf(spec->stream_name_digital,
3720 sizeof(spec->stream_name_digital),
3721 "%s Digital", codec->chip_name);
3722 codec->num_pcms = 2;
3723 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3724 info = spec->pcm_rec + 1;
3725 info->name = spec->stream_name_digital;
3726 if (spec->dig_out_type)
3727 info->pcm_type = spec->dig_out_type;
3728 else
3729 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3730 if (spec->multiout.dig_out_nid &&
3731 spec->stream_digital_playback) {
3732 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3733 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3735 if (spec->dig_in_nid &&
3736 spec->stream_digital_capture) {
3737 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3738 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3740 /* FIXME: do we need this for all Realtek codec models? */
3741 codec->spdif_status_reset = 1;
3744 if (spec->no_analog)
3745 return 0;
3747 /* If the use of more than one ADC is requested for the current
3748 * model, configure a second analog capture-only PCM.
3750 /* Additional Analaog capture for index #2 */
3751 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3752 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3753 codec->num_pcms = 3;
3754 info = spec->pcm_rec + 2;
3755 info->name = spec->stream_name_analog;
3756 if (spec->alt_dac_nid) {
3757 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3758 *spec->stream_analog_alt_playback;
3759 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3760 spec->alt_dac_nid;
3761 } else {
3762 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3763 alc_pcm_null_stream;
3764 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3766 if (spec->num_adc_nids > 1) {
3767 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3768 *spec->stream_analog_alt_capture;
3769 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3770 spec->adc_nids[1];
3771 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3772 spec->num_adc_nids - 1;
3773 } else {
3774 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3775 alc_pcm_null_stream;
3776 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3780 return 0;
3783 static inline void alc_shutup(struct hda_codec *codec)
3785 snd_hda_shutup_pins(codec);
3788 static void alc_free_kctls(struct hda_codec *codec)
3790 struct alc_spec *spec = codec->spec;
3792 if (spec->kctls.list) {
3793 struct snd_kcontrol_new *kctl = spec->kctls.list;
3794 int i;
3795 for (i = 0; i < spec->kctls.used; i++)
3796 kfree(kctl[i].name);
3798 snd_array_free(&spec->kctls);
3801 static void alc_free(struct hda_codec *codec)
3803 struct alc_spec *spec = codec->spec;
3805 if (!spec)
3806 return;
3808 alc_shutup(codec);
3809 alc_free_kctls(codec);
3810 kfree(spec);
3811 snd_hda_detach_beep_device(codec);
3814 #ifdef CONFIG_SND_HDA_POWER_SAVE
3815 static void alc_power_eapd(struct hda_codec *codec)
3817 /* We currently only handle front, HP */
3818 switch (codec->vendor_id) {
3819 case 0x10ec0260:
3820 set_eapd(codec, 0x0f, 0);
3821 set_eapd(codec, 0x10, 0);
3822 break;
3823 case 0x10ec0262:
3824 case 0x10ec0267:
3825 case 0x10ec0268:
3826 case 0x10ec0269:
3827 case 0x10ec0270:
3828 case 0x10ec0272:
3829 case 0x10ec0660:
3830 case 0x10ec0662:
3831 case 0x10ec0663:
3832 case 0x10ec0862:
3833 case 0x10ec0889:
3834 set_eapd(codec, 0x14, 0);
3835 set_eapd(codec, 0x15, 0);
3836 break;
3840 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3842 struct alc_spec *spec = codec->spec;
3843 alc_shutup(codec);
3844 if (spec && spec->power_hook)
3845 spec->power_hook(codec);
3846 return 0;
3848 #endif
3850 #ifdef SND_HDA_NEEDS_RESUME
3851 static int alc_resume(struct hda_codec *codec)
3853 codec->patch_ops.init(codec);
3854 snd_hda_codec_resume_amp(codec);
3855 snd_hda_codec_resume_cache(codec);
3856 #ifdef CONFIG_SND_HDA_POWER_SAVE
3857 if (codec->patch_ops.check_power_status)
3858 codec->patch_ops.check_power_status(codec, 0x01);
3859 #endif
3860 return 0;
3862 #endif
3866 static struct hda_codec_ops alc_patch_ops = {
3867 .build_controls = alc_build_controls,
3868 .build_pcms = alc_build_pcms,
3869 .init = alc_init,
3870 .free = alc_free,
3871 .unsol_event = alc_unsol_event,
3872 #ifdef SND_HDA_NEEDS_RESUME
3873 .resume = alc_resume,
3874 #endif
3875 #ifdef CONFIG_SND_HDA_POWER_SAVE
3876 .suspend = alc_suspend,
3877 .check_power_status = alc_check_power_status,
3878 #endif
3879 .reboot_notify = alc_shutup,
3882 /* replace the codec chip_name with the given string */
3883 static int alc_codec_rename(struct hda_codec *codec, const char *name)
3885 kfree(codec->chip_name);
3886 codec->chip_name = kstrdup(name, GFP_KERNEL);
3887 if (!codec->chip_name) {
3888 alc_free(codec);
3889 return -ENOMEM;
3891 return 0;
3895 * Test configuration for debugging
3897 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3898 * enum controls.
3900 #ifdef CONFIG_SND_DEBUG
3901 static hda_nid_t alc880_test_dac_nids[4] = {
3902 0x02, 0x03, 0x04, 0x05
3905 static struct hda_input_mux alc880_test_capture_source = {
3906 .num_items = 7,
3907 .items = {
3908 { "In-1", 0x0 },
3909 { "In-2", 0x1 },
3910 { "In-3", 0x2 },
3911 { "In-4", 0x3 },
3912 { "CD", 0x4 },
3913 { "Front", 0x5 },
3914 { "Surround", 0x6 },
3918 static struct hda_channel_mode alc880_test_modes[4] = {
3919 { 2, NULL },
3920 { 4, NULL },
3921 { 6, NULL },
3922 { 8, NULL },
3925 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3926 struct snd_ctl_elem_info *uinfo)
3928 static char *texts[] = {
3929 "N/A", "Line Out", "HP Out",
3930 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3932 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3933 uinfo->count = 1;
3934 uinfo->value.enumerated.items = 8;
3935 if (uinfo->value.enumerated.item >= 8)
3936 uinfo->value.enumerated.item = 7;
3937 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3938 return 0;
3941 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3942 struct snd_ctl_elem_value *ucontrol)
3944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3945 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3946 unsigned int pin_ctl, item = 0;
3948 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3949 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3950 if (pin_ctl & AC_PINCTL_OUT_EN) {
3951 if (pin_ctl & AC_PINCTL_HP_EN)
3952 item = 2;
3953 else
3954 item = 1;
3955 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3956 switch (pin_ctl & AC_PINCTL_VREFEN) {
3957 case AC_PINCTL_VREF_HIZ: item = 3; break;
3958 case AC_PINCTL_VREF_50: item = 4; break;
3959 case AC_PINCTL_VREF_GRD: item = 5; break;
3960 case AC_PINCTL_VREF_80: item = 6; break;
3961 case AC_PINCTL_VREF_100: item = 7; break;
3964 ucontrol->value.enumerated.item[0] = item;
3965 return 0;
3968 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3969 struct snd_ctl_elem_value *ucontrol)
3971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3972 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3973 static unsigned int ctls[] = {
3974 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3975 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3976 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3977 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3978 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3979 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3981 unsigned int old_ctl, new_ctl;
3983 old_ctl = snd_hda_codec_read(codec, nid, 0,
3984 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3985 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3986 if (old_ctl != new_ctl) {
3987 int val;
3988 snd_hda_codec_write_cache(codec, nid, 0,
3989 AC_VERB_SET_PIN_WIDGET_CONTROL,
3990 new_ctl);
3991 val = ucontrol->value.enumerated.item[0] >= 3 ?
3992 HDA_AMP_MUTE : 0;
3993 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3994 HDA_AMP_MUTE, val);
3995 return 1;
3997 return 0;
4000 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4001 struct snd_ctl_elem_info *uinfo)
4003 static char *texts[] = {
4004 "Front", "Surround", "CLFE", "Side"
4006 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4007 uinfo->count = 1;
4008 uinfo->value.enumerated.items = 4;
4009 if (uinfo->value.enumerated.item >= 4)
4010 uinfo->value.enumerated.item = 3;
4011 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4012 return 0;
4015 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4016 struct snd_ctl_elem_value *ucontrol)
4018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4019 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4020 unsigned int sel;
4022 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4023 ucontrol->value.enumerated.item[0] = sel & 3;
4024 return 0;
4027 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4028 struct snd_ctl_elem_value *ucontrol)
4030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4031 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4032 unsigned int sel;
4034 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4035 if (ucontrol->value.enumerated.item[0] != sel) {
4036 sel = ucontrol->value.enumerated.item[0] & 3;
4037 snd_hda_codec_write_cache(codec, nid, 0,
4038 AC_VERB_SET_CONNECT_SEL, sel);
4039 return 1;
4041 return 0;
4044 #define PIN_CTL_TEST(xname,nid) { \
4045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4046 .name = xname, \
4047 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4048 .info = alc_test_pin_ctl_info, \
4049 .get = alc_test_pin_ctl_get, \
4050 .put = alc_test_pin_ctl_put, \
4051 .private_value = nid \
4054 #define PIN_SRC_TEST(xname,nid) { \
4055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4056 .name = xname, \
4057 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4058 .info = alc_test_pin_src_info, \
4059 .get = alc_test_pin_src_get, \
4060 .put = alc_test_pin_src_put, \
4061 .private_value = nid \
4064 static struct snd_kcontrol_new alc880_test_mixer[] = {
4065 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4066 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4067 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4068 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4070 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4071 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4072 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4073 PIN_CTL_TEST("Front Pin Mode", 0x14),
4074 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4075 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4076 PIN_CTL_TEST("Side Pin Mode", 0x17),
4077 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4078 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4079 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4080 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4081 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4082 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4083 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4084 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4085 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4086 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4087 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4088 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4089 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4090 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4091 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4092 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4093 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4094 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4096 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4097 .name = "Channel Mode",
4098 .info = alc_ch_mode_info,
4099 .get = alc_ch_mode_get,
4100 .put = alc_ch_mode_put,
4102 { } /* end */
4105 static struct hda_verb alc880_test_init_verbs[] = {
4106 /* Unmute inputs of 0x0c - 0x0f */
4107 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4108 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4109 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4110 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4111 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4112 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4113 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4115 /* Vol output for 0x0c-0x0f */
4116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4118 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4119 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4120 /* Set output pins 0x14-0x17 */
4121 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4122 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4123 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4124 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4125 /* Unmute output pins 0x14-0x17 */
4126 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4128 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4129 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4130 /* Set input pins 0x18-0x1c */
4131 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4133 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4134 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4135 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4136 /* Mute input pins 0x18-0x1b */
4137 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4138 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4141 /* ADC set up */
4142 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4143 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4144 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4145 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4146 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4147 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4148 /* Analog input/passthru */
4149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4156 #endif
4161 static const char *alc880_models[ALC880_MODEL_LAST] = {
4162 [ALC880_3ST] = "3stack",
4163 [ALC880_TCL_S700] = "tcl",
4164 [ALC880_3ST_DIG] = "3stack-digout",
4165 [ALC880_CLEVO] = "clevo",
4166 [ALC880_5ST] = "5stack",
4167 [ALC880_5ST_DIG] = "5stack-digout",
4168 [ALC880_W810] = "w810",
4169 [ALC880_Z71V] = "z71v",
4170 [ALC880_6ST] = "6stack",
4171 [ALC880_6ST_DIG] = "6stack-digout",
4172 [ALC880_ASUS] = "asus",
4173 [ALC880_ASUS_W1V] = "asus-w1v",
4174 [ALC880_ASUS_DIG] = "asus-dig",
4175 [ALC880_ASUS_DIG2] = "asus-dig2",
4176 [ALC880_UNIWILL_DIG] = "uniwill",
4177 [ALC880_UNIWILL_P53] = "uniwill-p53",
4178 [ALC880_FUJITSU] = "fujitsu",
4179 [ALC880_F1734] = "F1734",
4180 [ALC880_LG] = "lg",
4181 [ALC880_LG_LW] = "lg-lw",
4182 [ALC880_MEDION_RIM] = "medion",
4183 #ifdef CONFIG_SND_DEBUG
4184 [ALC880_TEST] = "test",
4185 #endif
4186 [ALC880_AUTO] = "auto",
4189 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4190 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4191 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4192 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4193 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4194 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4195 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4196 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4197 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4198 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4199 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4200 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4201 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4202 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4203 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4204 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4205 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4206 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4207 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4208 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4209 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4210 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4211 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4212 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4213 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4214 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4215 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4216 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4217 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4218 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4219 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4220 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4221 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4222 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4223 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4224 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4225 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4226 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4227 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4228 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4229 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4230 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4231 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4232 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4233 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4234 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4235 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4236 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4237 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4238 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4239 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4240 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4241 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4242 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4243 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4244 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4245 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4246 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4247 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4248 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4249 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4250 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4251 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4252 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4253 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4254 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4255 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4256 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4257 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4258 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4259 /* default Intel */
4260 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4261 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4262 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4267 * ALC880 codec presets
4269 static struct alc_config_preset alc880_presets[] = {
4270 [ALC880_3ST] = {
4271 .mixers = { alc880_three_stack_mixer },
4272 .init_verbs = { alc880_volume_init_verbs,
4273 alc880_pin_3stack_init_verbs },
4274 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4275 .dac_nids = alc880_dac_nids,
4276 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4277 .channel_mode = alc880_threestack_modes,
4278 .need_dac_fix = 1,
4279 .input_mux = &alc880_capture_source,
4281 [ALC880_3ST_DIG] = {
4282 .mixers = { alc880_three_stack_mixer },
4283 .init_verbs = { alc880_volume_init_verbs,
4284 alc880_pin_3stack_init_verbs },
4285 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4286 .dac_nids = alc880_dac_nids,
4287 .dig_out_nid = ALC880_DIGOUT_NID,
4288 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4289 .channel_mode = alc880_threestack_modes,
4290 .need_dac_fix = 1,
4291 .input_mux = &alc880_capture_source,
4293 [ALC880_TCL_S700] = {
4294 .mixers = { alc880_tcl_s700_mixer },
4295 .init_verbs = { alc880_volume_init_verbs,
4296 alc880_pin_tcl_S700_init_verbs,
4297 alc880_gpio2_init_verbs },
4298 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4299 .dac_nids = alc880_dac_nids,
4300 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4301 .num_adc_nids = 1, /* single ADC */
4302 .hp_nid = 0x03,
4303 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4304 .channel_mode = alc880_2_jack_modes,
4305 .input_mux = &alc880_capture_source,
4307 [ALC880_5ST] = {
4308 .mixers = { alc880_three_stack_mixer,
4309 alc880_five_stack_mixer},
4310 .init_verbs = { alc880_volume_init_verbs,
4311 alc880_pin_5stack_init_verbs },
4312 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4313 .dac_nids = alc880_dac_nids,
4314 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4315 .channel_mode = alc880_fivestack_modes,
4316 .input_mux = &alc880_capture_source,
4318 [ALC880_5ST_DIG] = {
4319 .mixers = { alc880_three_stack_mixer,
4320 alc880_five_stack_mixer },
4321 .init_verbs = { alc880_volume_init_verbs,
4322 alc880_pin_5stack_init_verbs },
4323 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4324 .dac_nids = alc880_dac_nids,
4325 .dig_out_nid = ALC880_DIGOUT_NID,
4326 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4327 .channel_mode = alc880_fivestack_modes,
4328 .input_mux = &alc880_capture_source,
4330 [ALC880_6ST] = {
4331 .mixers = { alc880_six_stack_mixer },
4332 .init_verbs = { alc880_volume_init_verbs,
4333 alc880_pin_6stack_init_verbs },
4334 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4335 .dac_nids = alc880_6st_dac_nids,
4336 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4337 .channel_mode = alc880_sixstack_modes,
4338 .input_mux = &alc880_6stack_capture_source,
4340 [ALC880_6ST_DIG] = {
4341 .mixers = { alc880_six_stack_mixer },
4342 .init_verbs = { alc880_volume_init_verbs,
4343 alc880_pin_6stack_init_verbs },
4344 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4345 .dac_nids = alc880_6st_dac_nids,
4346 .dig_out_nid = ALC880_DIGOUT_NID,
4347 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4348 .channel_mode = alc880_sixstack_modes,
4349 .input_mux = &alc880_6stack_capture_source,
4351 [ALC880_W810] = {
4352 .mixers = { alc880_w810_base_mixer },
4353 .init_verbs = { alc880_volume_init_verbs,
4354 alc880_pin_w810_init_verbs,
4355 alc880_gpio2_init_verbs },
4356 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4357 .dac_nids = alc880_w810_dac_nids,
4358 .dig_out_nid = ALC880_DIGOUT_NID,
4359 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4360 .channel_mode = alc880_w810_modes,
4361 .input_mux = &alc880_capture_source,
4363 [ALC880_Z71V] = {
4364 .mixers = { alc880_z71v_mixer },
4365 .init_verbs = { alc880_volume_init_verbs,
4366 alc880_pin_z71v_init_verbs },
4367 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4368 .dac_nids = alc880_z71v_dac_nids,
4369 .dig_out_nid = ALC880_DIGOUT_NID,
4370 .hp_nid = 0x03,
4371 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4372 .channel_mode = alc880_2_jack_modes,
4373 .input_mux = &alc880_capture_source,
4375 [ALC880_F1734] = {
4376 .mixers = { alc880_f1734_mixer },
4377 .init_verbs = { alc880_volume_init_verbs,
4378 alc880_pin_f1734_init_verbs },
4379 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4380 .dac_nids = alc880_f1734_dac_nids,
4381 .hp_nid = 0x02,
4382 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4383 .channel_mode = alc880_2_jack_modes,
4384 .input_mux = &alc880_f1734_capture_source,
4385 .unsol_event = alc880_uniwill_p53_unsol_event,
4386 .setup = alc880_uniwill_p53_setup,
4387 .init_hook = alc_automute_amp,
4389 [ALC880_ASUS] = {
4390 .mixers = { alc880_asus_mixer },
4391 .init_verbs = { alc880_volume_init_verbs,
4392 alc880_pin_asus_init_verbs,
4393 alc880_gpio1_init_verbs },
4394 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4395 .dac_nids = alc880_asus_dac_nids,
4396 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4397 .channel_mode = alc880_asus_modes,
4398 .need_dac_fix = 1,
4399 .input_mux = &alc880_capture_source,
4401 [ALC880_ASUS_DIG] = {
4402 .mixers = { alc880_asus_mixer },
4403 .init_verbs = { alc880_volume_init_verbs,
4404 alc880_pin_asus_init_verbs,
4405 alc880_gpio1_init_verbs },
4406 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4407 .dac_nids = alc880_asus_dac_nids,
4408 .dig_out_nid = ALC880_DIGOUT_NID,
4409 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4410 .channel_mode = alc880_asus_modes,
4411 .need_dac_fix = 1,
4412 .input_mux = &alc880_capture_source,
4414 [ALC880_ASUS_DIG2] = {
4415 .mixers = { alc880_asus_mixer },
4416 .init_verbs = { alc880_volume_init_verbs,
4417 alc880_pin_asus_init_verbs,
4418 alc880_gpio2_init_verbs }, /* use GPIO2 */
4419 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4420 .dac_nids = alc880_asus_dac_nids,
4421 .dig_out_nid = ALC880_DIGOUT_NID,
4422 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4423 .channel_mode = alc880_asus_modes,
4424 .need_dac_fix = 1,
4425 .input_mux = &alc880_capture_source,
4427 [ALC880_ASUS_W1V] = {
4428 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4429 .init_verbs = { alc880_volume_init_verbs,
4430 alc880_pin_asus_init_verbs,
4431 alc880_gpio1_init_verbs },
4432 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4433 .dac_nids = alc880_asus_dac_nids,
4434 .dig_out_nid = ALC880_DIGOUT_NID,
4435 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4436 .channel_mode = alc880_asus_modes,
4437 .need_dac_fix = 1,
4438 .input_mux = &alc880_capture_source,
4440 [ALC880_UNIWILL_DIG] = {
4441 .mixers = { alc880_asus_mixer },
4442 .init_verbs = { alc880_volume_init_verbs,
4443 alc880_pin_asus_init_verbs },
4444 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4445 .dac_nids = alc880_asus_dac_nids,
4446 .dig_out_nid = ALC880_DIGOUT_NID,
4447 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4448 .channel_mode = alc880_asus_modes,
4449 .need_dac_fix = 1,
4450 .input_mux = &alc880_capture_source,
4452 [ALC880_UNIWILL] = {
4453 .mixers = { alc880_uniwill_mixer },
4454 .init_verbs = { alc880_volume_init_verbs,
4455 alc880_uniwill_init_verbs },
4456 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4457 .dac_nids = alc880_asus_dac_nids,
4458 .dig_out_nid = ALC880_DIGOUT_NID,
4459 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4460 .channel_mode = alc880_threestack_modes,
4461 .need_dac_fix = 1,
4462 .input_mux = &alc880_capture_source,
4463 .unsol_event = alc880_uniwill_unsol_event,
4464 .setup = alc880_uniwill_setup,
4465 .init_hook = alc880_uniwill_init_hook,
4467 [ALC880_UNIWILL_P53] = {
4468 .mixers = { alc880_uniwill_p53_mixer },
4469 .init_verbs = { alc880_volume_init_verbs,
4470 alc880_uniwill_p53_init_verbs },
4471 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4472 .dac_nids = alc880_asus_dac_nids,
4473 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4474 .channel_mode = alc880_threestack_modes,
4475 .input_mux = &alc880_capture_source,
4476 .unsol_event = alc880_uniwill_p53_unsol_event,
4477 .setup = alc880_uniwill_p53_setup,
4478 .init_hook = alc_automute_amp,
4480 [ALC880_FUJITSU] = {
4481 .mixers = { alc880_fujitsu_mixer },
4482 .init_verbs = { alc880_volume_init_verbs,
4483 alc880_uniwill_p53_init_verbs,
4484 alc880_beep_init_verbs },
4485 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4486 .dac_nids = alc880_dac_nids,
4487 .dig_out_nid = ALC880_DIGOUT_NID,
4488 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4489 .channel_mode = alc880_2_jack_modes,
4490 .input_mux = &alc880_capture_source,
4491 .unsol_event = alc880_uniwill_p53_unsol_event,
4492 .setup = alc880_uniwill_p53_setup,
4493 .init_hook = alc_automute_amp,
4495 [ALC880_CLEVO] = {
4496 .mixers = { alc880_three_stack_mixer },
4497 .init_verbs = { alc880_volume_init_verbs,
4498 alc880_pin_clevo_init_verbs },
4499 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4500 .dac_nids = alc880_dac_nids,
4501 .hp_nid = 0x03,
4502 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4503 .channel_mode = alc880_threestack_modes,
4504 .need_dac_fix = 1,
4505 .input_mux = &alc880_capture_source,
4507 [ALC880_LG] = {
4508 .mixers = { alc880_lg_mixer },
4509 .init_verbs = { alc880_volume_init_verbs,
4510 alc880_lg_init_verbs },
4511 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4512 .dac_nids = alc880_lg_dac_nids,
4513 .dig_out_nid = ALC880_DIGOUT_NID,
4514 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4515 .channel_mode = alc880_lg_ch_modes,
4516 .need_dac_fix = 1,
4517 .input_mux = &alc880_lg_capture_source,
4518 .unsol_event = alc_automute_amp_unsol_event,
4519 .setup = alc880_lg_setup,
4520 .init_hook = alc_automute_amp,
4521 #ifdef CONFIG_SND_HDA_POWER_SAVE
4522 .loopbacks = alc880_lg_loopbacks,
4523 #endif
4525 [ALC880_LG_LW] = {
4526 .mixers = { alc880_lg_lw_mixer },
4527 .init_verbs = { alc880_volume_init_verbs,
4528 alc880_lg_lw_init_verbs },
4529 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4530 .dac_nids = alc880_dac_nids,
4531 .dig_out_nid = ALC880_DIGOUT_NID,
4532 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4533 .channel_mode = alc880_lg_lw_modes,
4534 .input_mux = &alc880_lg_lw_capture_source,
4535 .unsol_event = alc_automute_amp_unsol_event,
4536 .setup = alc880_lg_lw_setup,
4537 .init_hook = alc_automute_amp,
4539 [ALC880_MEDION_RIM] = {
4540 .mixers = { alc880_medion_rim_mixer },
4541 .init_verbs = { alc880_volume_init_verbs,
4542 alc880_medion_rim_init_verbs,
4543 alc_gpio2_init_verbs },
4544 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4545 .dac_nids = alc880_dac_nids,
4546 .dig_out_nid = ALC880_DIGOUT_NID,
4547 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4548 .channel_mode = alc880_2_jack_modes,
4549 .input_mux = &alc880_medion_rim_capture_source,
4550 .unsol_event = alc880_medion_rim_unsol_event,
4551 .setup = alc880_medion_rim_setup,
4552 .init_hook = alc880_medion_rim_automute,
4554 #ifdef CONFIG_SND_DEBUG
4555 [ALC880_TEST] = {
4556 .mixers = { alc880_test_mixer },
4557 .init_verbs = { alc880_test_init_verbs },
4558 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4559 .dac_nids = alc880_test_dac_nids,
4560 .dig_out_nid = ALC880_DIGOUT_NID,
4561 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4562 .channel_mode = alc880_test_modes,
4563 .input_mux = &alc880_test_capture_source,
4565 #endif
4569 * Automatic parse of I/O pins from the BIOS configuration
4572 enum {
4573 ALC_CTL_WIDGET_VOL,
4574 ALC_CTL_WIDGET_MUTE,
4575 ALC_CTL_BIND_MUTE,
4577 static struct snd_kcontrol_new alc880_control_templates[] = {
4578 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4579 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4580 HDA_BIND_MUTE(NULL, 0, 0, 0),
4583 /* add dynamic controls */
4584 static int add_control(struct alc_spec *spec, int type, const char *name,
4585 unsigned long val)
4587 struct snd_kcontrol_new *knew;
4589 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4590 knew = snd_array_new(&spec->kctls);
4591 if (!knew)
4592 return -ENOMEM;
4593 *knew = alc880_control_templates[type];
4594 knew->name = kstrdup(name, GFP_KERNEL);
4595 if (!knew->name)
4596 return -ENOMEM;
4597 if (get_amp_nid_(val))
4598 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4599 knew->private_value = val;
4600 return 0;
4603 static int add_control_with_pfx(struct alc_spec *spec, int type,
4604 const char *pfx, const char *dir,
4605 const char *sfx, unsigned long val)
4607 char name[32];
4608 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4609 return add_control(spec, type, name, val);
4612 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4613 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4614 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4615 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4617 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4618 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4619 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4620 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4621 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4622 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4623 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4624 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4625 #define ALC880_PIN_CD_NID 0x1c
4627 /* fill in the dac_nids table from the parsed pin configuration */
4628 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4629 const struct auto_pin_cfg *cfg)
4631 hda_nid_t nid;
4632 int assigned[4];
4633 int i, j;
4635 memset(assigned, 0, sizeof(assigned));
4636 spec->multiout.dac_nids = spec->private_dac_nids;
4638 /* check the pins hardwired to audio widget */
4639 for (i = 0; i < cfg->line_outs; i++) {
4640 nid = cfg->line_out_pins[i];
4641 if (alc880_is_fixed_pin(nid)) {
4642 int idx = alc880_fixed_pin_idx(nid);
4643 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4644 assigned[idx] = 1;
4647 /* left pins can be connect to any audio widget */
4648 for (i = 0; i < cfg->line_outs; i++) {
4649 nid = cfg->line_out_pins[i];
4650 if (alc880_is_fixed_pin(nid))
4651 continue;
4652 /* search for an empty channel */
4653 for (j = 0; j < cfg->line_outs; j++) {
4654 if (!assigned[j]) {
4655 spec->multiout.dac_nids[i] =
4656 alc880_idx_to_dac(j);
4657 assigned[j] = 1;
4658 break;
4662 spec->multiout.num_dacs = cfg->line_outs;
4663 return 0;
4666 /* add playback controls from the parsed DAC table */
4667 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4668 const struct auto_pin_cfg *cfg)
4670 static const char *chname[4] = {
4671 "Front", "Surround", NULL /*CLFE*/, "Side"
4673 hda_nid_t nid;
4674 int i, err;
4676 for (i = 0; i < cfg->line_outs; i++) {
4677 if (!spec->multiout.dac_nids[i])
4678 continue;
4679 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4680 if (i == 2) {
4681 /* Center/LFE */
4682 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4683 "Center",
4684 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4685 HDA_OUTPUT));
4686 if (err < 0)
4687 return err;
4688 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4689 "LFE",
4690 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4691 HDA_OUTPUT));
4692 if (err < 0)
4693 return err;
4694 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4695 "Center",
4696 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4697 HDA_INPUT));
4698 if (err < 0)
4699 return err;
4700 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4701 "LFE",
4702 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4703 HDA_INPUT));
4704 if (err < 0)
4705 return err;
4706 } else {
4707 const char *pfx;
4708 if (cfg->line_outs == 1 &&
4709 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4710 pfx = "Speaker";
4711 else
4712 pfx = chname[i];
4713 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4714 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4715 HDA_OUTPUT));
4716 if (err < 0)
4717 return err;
4718 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4719 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4720 HDA_INPUT));
4721 if (err < 0)
4722 return err;
4725 return 0;
4728 /* add playback controls for speaker and HP outputs */
4729 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4730 const char *pfx)
4732 hda_nid_t nid;
4733 int err;
4735 if (!pin)
4736 return 0;
4738 if (alc880_is_fixed_pin(pin)) {
4739 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4740 /* specify the DAC as the extra output */
4741 if (!spec->multiout.hp_nid)
4742 spec->multiout.hp_nid = nid;
4743 else
4744 spec->multiout.extra_out_nid[0] = nid;
4745 /* control HP volume/switch on the output mixer amp */
4746 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4747 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4748 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4749 if (err < 0)
4750 return err;
4751 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4752 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4753 if (err < 0)
4754 return err;
4755 } else if (alc880_is_multi_pin(pin)) {
4756 /* set manual connection */
4757 /* we have only a switch on HP-out PIN */
4758 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4759 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4760 if (err < 0)
4761 return err;
4763 return 0;
4766 /* create input playback/capture controls for the given pin */
4767 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4768 const char *ctlname,
4769 int idx, hda_nid_t mix_nid)
4771 int err;
4773 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4774 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4775 if (err < 0)
4776 return err;
4777 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4778 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4779 if (err < 0)
4780 return err;
4781 return 0;
4784 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4786 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4787 return (pincap & AC_PINCAP_IN) != 0;
4790 /* create playback/capture controls for input pins */
4791 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4792 const struct auto_pin_cfg *cfg,
4793 hda_nid_t mixer,
4794 hda_nid_t cap1, hda_nid_t cap2)
4796 struct alc_spec *spec = codec->spec;
4797 struct hda_input_mux *imux = &spec->private_imux[0];
4798 int i, err, idx;
4800 for (i = 0; i < AUTO_PIN_LAST; i++) {
4801 hda_nid_t pin;
4803 pin = cfg->input_pins[i];
4804 if (!alc_is_input_pin(codec, pin))
4805 continue;
4807 if (mixer) {
4808 idx = get_connection_index(codec, mixer, pin);
4809 if (idx >= 0) {
4810 err = new_analog_input(spec, pin,
4811 auto_pin_cfg_labels[i],
4812 idx, mixer);
4813 if (err < 0)
4814 return err;
4818 if (!cap1)
4819 continue;
4820 idx = get_connection_index(codec, cap1, pin);
4821 if (idx < 0 && cap2)
4822 idx = get_connection_index(codec, cap2, pin);
4823 if (idx >= 0) {
4824 imux->items[imux->num_items].label =
4825 auto_pin_cfg_labels[i];
4826 imux->items[imux->num_items].index = idx;
4827 imux->num_items++;
4830 return 0;
4833 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4834 const struct auto_pin_cfg *cfg)
4836 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4839 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4840 unsigned int pin_type)
4842 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4843 pin_type);
4844 /* unmute pin */
4845 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4846 AMP_OUT_UNMUTE);
4849 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4850 hda_nid_t nid, int pin_type,
4851 int dac_idx)
4853 alc_set_pin_output(codec, nid, pin_type);
4854 /* need the manual connection? */
4855 if (alc880_is_multi_pin(nid)) {
4856 struct alc_spec *spec = codec->spec;
4857 int idx = alc880_multi_pin_idx(nid);
4858 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4859 AC_VERB_SET_CONNECT_SEL,
4860 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4864 static int get_pin_type(int line_out_type)
4866 if (line_out_type == AUTO_PIN_HP_OUT)
4867 return PIN_HP;
4868 else
4869 return PIN_OUT;
4872 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4874 struct alc_spec *spec = codec->spec;
4875 int i;
4877 for (i = 0; i < spec->autocfg.line_outs; i++) {
4878 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4879 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4880 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4884 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4886 struct alc_spec *spec = codec->spec;
4887 hda_nid_t pin;
4889 pin = spec->autocfg.speaker_pins[0];
4890 if (pin) /* connect to front */
4891 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4892 pin = spec->autocfg.hp_pins[0];
4893 if (pin) /* connect to front */
4894 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4897 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4899 struct alc_spec *spec = codec->spec;
4900 int i;
4902 for (i = 0; i < AUTO_PIN_LAST; i++) {
4903 hda_nid_t nid = spec->autocfg.input_pins[i];
4904 if (alc_is_input_pin(codec, nid)) {
4905 alc_set_input_pin(codec, nid, i);
4906 if (nid != ALC880_PIN_CD_NID &&
4907 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4908 snd_hda_codec_write(codec, nid, 0,
4909 AC_VERB_SET_AMP_GAIN_MUTE,
4910 AMP_OUT_MUTE);
4915 static void alc880_auto_init_input_src(struct hda_codec *codec)
4917 struct alc_spec *spec = codec->spec;
4918 int c;
4920 for (c = 0; c < spec->num_adc_nids; c++) {
4921 unsigned int mux_idx;
4922 const struct hda_input_mux *imux;
4923 mux_idx = c >= spec->num_mux_defs ? 0 : c;
4924 imux = &spec->input_mux[mux_idx];
4925 if (!imux->num_items && mux_idx > 0)
4926 imux = &spec->input_mux[0];
4927 if (imux)
4928 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
4929 AC_VERB_SET_CONNECT_SEL,
4930 imux->items[0].index);
4934 /* parse the BIOS configuration and set up the alc_spec */
4935 /* return 1 if successful, 0 if the proper config is not found,
4936 * or a negative error code
4938 static int alc880_parse_auto_config(struct hda_codec *codec)
4940 struct alc_spec *spec = codec->spec;
4941 int i, err;
4942 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4944 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4945 alc880_ignore);
4946 if (err < 0)
4947 return err;
4948 if (!spec->autocfg.line_outs)
4949 return 0; /* can't find valid BIOS pin config */
4951 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4952 if (err < 0)
4953 return err;
4954 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4955 if (err < 0)
4956 return err;
4957 err = alc880_auto_create_extra_out(spec,
4958 spec->autocfg.speaker_pins[0],
4959 "Speaker");
4960 if (err < 0)
4961 return err;
4962 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4963 "Headphone");
4964 if (err < 0)
4965 return err;
4966 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4967 if (err < 0)
4968 return err;
4970 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4972 /* check multiple SPDIF-out (for recent codecs) */
4973 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4974 hda_nid_t dig_nid;
4975 err = snd_hda_get_connections(codec,
4976 spec->autocfg.dig_out_pins[i],
4977 &dig_nid, 1);
4978 if (err < 0)
4979 continue;
4980 if (!i)
4981 spec->multiout.dig_out_nid = dig_nid;
4982 else {
4983 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4984 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4985 break;
4986 spec->slave_dig_outs[i - 1] = dig_nid;
4989 if (spec->autocfg.dig_in_pin)
4990 spec->dig_in_nid = ALC880_DIGIN_NID;
4992 if (spec->kctls.list)
4993 add_mixer(spec, spec->kctls.list);
4995 add_verb(spec, alc880_volume_init_verbs);
4997 spec->num_mux_defs = 1;
4998 spec->input_mux = &spec->private_imux[0];
5000 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5002 return 1;
5005 /* additional initialization for auto-configuration model */
5006 static void alc880_auto_init(struct hda_codec *codec)
5008 struct alc_spec *spec = codec->spec;
5009 alc880_auto_init_multi_out(codec);
5010 alc880_auto_init_extra_out(codec);
5011 alc880_auto_init_analog_input(codec);
5012 alc880_auto_init_input_src(codec);
5013 if (spec->unsol_event)
5014 alc_inithook(codec);
5017 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5018 * one of two digital mic pins, e.g. on ALC272
5020 static void fixup_automic_adc(struct hda_codec *codec)
5022 struct alc_spec *spec = codec->spec;
5023 int i;
5025 for (i = 0; i < spec->num_adc_nids; i++) {
5026 hda_nid_t cap = spec->capsrc_nids ?
5027 spec->capsrc_nids[i] : spec->adc_nids[i];
5028 int iidx, eidx;
5030 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5031 if (iidx < 0)
5032 continue;
5033 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5034 if (eidx < 0)
5035 continue;
5036 spec->int_mic.mux_idx = iidx;
5037 spec->ext_mic.mux_idx = eidx;
5038 if (spec->capsrc_nids)
5039 spec->capsrc_nids += i;
5040 spec->adc_nids += i;
5041 spec->num_adc_nids = 1;
5042 return;
5044 snd_printd(KERN_INFO "hda_codec: %s: "
5045 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5046 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5047 spec->auto_mic = 0; /* disable auto-mic to be sure */
5050 /* choose the ADC/MUX containing the input pin and initialize the setup */
5051 static void fixup_single_adc(struct hda_codec *codec)
5053 struct alc_spec *spec = codec->spec;
5054 hda_nid_t pin = 0;
5055 int i;
5057 /* search for the input pin; there must be only one */
5058 for (i = 0; i < AUTO_PIN_LAST; i++) {
5059 if (spec->autocfg.input_pins[i]) {
5060 pin = spec->autocfg.input_pins[i];
5061 break;
5064 if (!pin)
5065 return;
5067 /* set the default connection to that pin */
5068 for (i = 0; i < spec->num_adc_nids; i++) {
5069 hda_nid_t cap = spec->capsrc_nids ?
5070 spec->capsrc_nids[i] : spec->adc_nids[i];
5071 int idx;
5073 idx = get_connection_index(codec, cap, pin);
5074 if (idx < 0)
5075 continue;
5076 /* use only this ADC */
5077 if (spec->capsrc_nids)
5078 spec->capsrc_nids += i;
5079 spec->adc_nids += i;
5080 spec->num_adc_nids = 1;
5081 /* select or unmute this route */
5082 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5083 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5084 HDA_AMP_MUTE, 0);
5085 } else {
5086 snd_hda_codec_write_cache(codec, cap, 0,
5087 AC_VERB_SET_CONNECT_SEL, idx);
5089 return;
5093 static void set_capture_mixer(struct hda_codec *codec)
5095 struct alc_spec *spec = codec->spec;
5096 static struct snd_kcontrol_new *caps[2][3] = {
5097 { alc_capture_mixer_nosrc1,
5098 alc_capture_mixer_nosrc2,
5099 alc_capture_mixer_nosrc3 },
5100 { alc_capture_mixer1,
5101 alc_capture_mixer2,
5102 alc_capture_mixer3 },
5104 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5105 int mux = 0;
5106 if (spec->auto_mic)
5107 fixup_automic_adc(codec);
5108 else if (spec->input_mux) {
5109 if (spec->input_mux->num_items > 1)
5110 mux = 1;
5111 else if (spec->input_mux->num_items == 1)
5112 fixup_single_adc(codec);
5114 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
5118 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5119 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5120 int num_nids)
5122 struct alc_spec *spec = codec->spec;
5123 int n;
5124 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5126 for (n = 0; n < num_nids; n++) {
5127 hda_nid_t adc, cap;
5128 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5129 int nconns, i, j;
5131 adc = nids[n];
5132 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5133 continue;
5134 cap = adc;
5135 nconns = snd_hda_get_connections(codec, cap, conn,
5136 ARRAY_SIZE(conn));
5137 if (nconns == 1) {
5138 cap = conn[0];
5139 nconns = snd_hda_get_connections(codec, cap, conn,
5140 ARRAY_SIZE(conn));
5142 if (nconns <= 0)
5143 continue;
5144 if (!fallback_adc) {
5145 fallback_adc = adc;
5146 fallback_cap = cap;
5148 for (i = 0; i < AUTO_PIN_LAST; i++) {
5149 hda_nid_t nid = spec->autocfg.input_pins[i];
5150 if (!nid)
5151 continue;
5152 for (j = 0; j < nconns; j++) {
5153 if (conn[j] == nid)
5154 break;
5156 if (j >= nconns)
5157 break;
5159 if (i >= AUTO_PIN_LAST) {
5160 int num_adcs = spec->num_adc_nids;
5161 spec->private_adc_nids[num_adcs] = adc;
5162 spec->private_capsrc_nids[num_adcs] = cap;
5163 spec->num_adc_nids++;
5164 spec->adc_nids = spec->private_adc_nids;
5165 if (adc != cap)
5166 spec->capsrc_nids = spec->private_capsrc_nids;
5169 if (!spec->num_adc_nids) {
5170 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5171 " using fallback 0x%x\n",
5172 codec->chip_name, fallback_adc);
5173 spec->private_adc_nids[0] = fallback_adc;
5174 spec->adc_nids = spec->private_adc_nids;
5175 if (fallback_adc != fallback_cap) {
5176 spec->private_capsrc_nids[0] = fallback_cap;
5177 spec->capsrc_nids = spec->private_adc_nids;
5182 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5183 #define set_beep_amp(spec, nid, idx, dir) \
5184 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5186 static struct snd_pci_quirk beep_white_list[] = {
5187 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5188 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5192 static inline int has_cdefine_beep(struct hda_codec *codec)
5194 struct alc_spec *spec = codec->spec;
5195 const struct snd_pci_quirk *q;
5196 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5197 if (q)
5198 return q->value;
5199 return spec->cdefine.enable_pcbeep;
5201 #else
5202 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5203 #define has_cdefine_beep(codec) 0
5204 #endif
5207 * OK, here we have finally the patch for ALC880
5210 static int patch_alc880(struct hda_codec *codec)
5212 struct alc_spec *spec;
5213 int board_config;
5214 int err;
5216 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5217 if (spec == NULL)
5218 return -ENOMEM;
5220 codec->spec = spec;
5222 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5223 alc880_models,
5224 alc880_cfg_tbl);
5225 if (board_config < 0) {
5226 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5227 codec->chip_name);
5228 board_config = ALC880_AUTO;
5231 if (board_config == ALC880_AUTO) {
5232 /* automatic parse from the BIOS config */
5233 err = alc880_parse_auto_config(codec);
5234 if (err < 0) {
5235 alc_free(codec);
5236 return err;
5237 } else if (!err) {
5238 printk(KERN_INFO
5239 "hda_codec: Cannot set up configuration "
5240 "from BIOS. Using 3-stack mode...\n");
5241 board_config = ALC880_3ST;
5245 err = snd_hda_attach_beep_device(codec, 0x1);
5246 if (err < 0) {
5247 alc_free(codec);
5248 return err;
5251 if (board_config != ALC880_AUTO)
5252 setup_preset(codec, &alc880_presets[board_config]);
5254 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5255 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5256 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5258 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5259 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5261 if (!spec->adc_nids && spec->input_mux) {
5262 /* check whether NID 0x07 is valid */
5263 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5264 /* get type */
5265 wcap = get_wcaps_type(wcap);
5266 if (wcap != AC_WID_AUD_IN) {
5267 spec->adc_nids = alc880_adc_nids_alt;
5268 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5269 } else {
5270 spec->adc_nids = alc880_adc_nids;
5271 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5274 set_capture_mixer(codec);
5275 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5277 spec->vmaster_nid = 0x0c;
5279 codec->patch_ops = alc_patch_ops;
5280 if (board_config == ALC880_AUTO)
5281 spec->init_hook = alc880_auto_init;
5282 #ifdef CONFIG_SND_HDA_POWER_SAVE
5283 if (!spec->loopback.amplist)
5284 spec->loopback.amplist = alc880_loopbacks;
5285 #endif
5287 return 0;
5292 * ALC260 support
5295 static hda_nid_t alc260_dac_nids[1] = {
5296 /* front */
5297 0x02,
5300 static hda_nid_t alc260_adc_nids[1] = {
5301 /* ADC0 */
5302 0x04,
5305 static hda_nid_t alc260_adc_nids_alt[1] = {
5306 /* ADC1 */
5307 0x05,
5310 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5311 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5313 static hda_nid_t alc260_dual_adc_nids[2] = {
5314 /* ADC0, ADC1 */
5315 0x04, 0x05
5318 #define ALC260_DIGOUT_NID 0x03
5319 #define ALC260_DIGIN_NID 0x06
5321 static struct hda_input_mux alc260_capture_source = {
5322 .num_items = 4,
5323 .items = {
5324 { "Mic", 0x0 },
5325 { "Front Mic", 0x1 },
5326 { "Line", 0x2 },
5327 { "CD", 0x4 },
5331 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5332 * headphone jack and the internal CD lines since these are the only pins at
5333 * which audio can appear. For flexibility, also allow the option of
5334 * recording the mixer output on the second ADC (ADC0 doesn't have a
5335 * connection to the mixer output).
5337 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5339 .num_items = 3,
5340 .items = {
5341 { "Mic/Line", 0x0 },
5342 { "CD", 0x4 },
5343 { "Headphone", 0x2 },
5347 .num_items = 4,
5348 .items = {
5349 { "Mic/Line", 0x0 },
5350 { "CD", 0x4 },
5351 { "Headphone", 0x2 },
5352 { "Mixer", 0x5 },
5358 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5359 * the Fujitsu S702x, but jacks are marked differently.
5361 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5363 .num_items = 4,
5364 .items = {
5365 { "Mic", 0x0 },
5366 { "Line", 0x2 },
5367 { "CD", 0x4 },
5368 { "Headphone", 0x5 },
5372 .num_items = 5,
5373 .items = {
5374 { "Mic", 0x0 },
5375 { "Line", 0x2 },
5376 { "CD", 0x4 },
5377 { "Headphone", 0x6 },
5378 { "Mixer", 0x5 },
5383 /* Maxdata Favorit 100XS */
5384 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5386 .num_items = 2,
5387 .items = {
5388 { "Line/Mic", 0x0 },
5389 { "CD", 0x4 },
5393 .num_items = 3,
5394 .items = {
5395 { "Line/Mic", 0x0 },
5396 { "CD", 0x4 },
5397 { "Mixer", 0x5 },
5403 * This is just place-holder, so there's something for alc_build_pcms to look
5404 * at when it calculates the maximum number of channels. ALC260 has no mixer
5405 * element which allows changing the channel mode, so the verb list is
5406 * never used.
5408 static struct hda_channel_mode alc260_modes[1] = {
5409 { 2, NULL },
5413 /* Mixer combinations
5415 * basic: base_output + input + pc_beep + capture
5416 * HP: base_output + input + capture_alt
5417 * HP_3013: hp_3013 + input + capture
5418 * fujitsu: fujitsu + capture
5419 * acer: acer + capture
5422 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5423 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5424 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5425 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5426 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5427 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5428 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5429 { } /* end */
5432 static struct snd_kcontrol_new alc260_input_mixer[] = {
5433 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5434 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5435 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5436 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5438 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5439 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5440 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5441 { } /* end */
5444 /* update HP, line and mono out pins according to the master switch */
5445 static void alc260_hp_master_update(struct hda_codec *codec,
5446 hda_nid_t hp, hda_nid_t line,
5447 hda_nid_t mono)
5449 struct alc_spec *spec = codec->spec;
5450 unsigned int val = spec->master_sw ? PIN_HP : 0;
5451 /* change HP and line-out pins */
5452 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5453 val);
5454 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5455 val);
5456 /* mono (speaker) depending on the HP jack sense */
5457 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5458 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5459 val);
5462 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5463 struct snd_ctl_elem_value *ucontrol)
5465 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5466 struct alc_spec *spec = codec->spec;
5467 *ucontrol->value.integer.value = spec->master_sw;
5468 return 0;
5471 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5472 struct snd_ctl_elem_value *ucontrol)
5474 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5475 struct alc_spec *spec = codec->spec;
5476 int val = !!*ucontrol->value.integer.value;
5477 hda_nid_t hp, line, mono;
5479 if (val == spec->master_sw)
5480 return 0;
5481 spec->master_sw = val;
5482 hp = (kcontrol->private_value >> 16) & 0xff;
5483 line = (kcontrol->private_value >> 8) & 0xff;
5484 mono = kcontrol->private_value & 0xff;
5485 alc260_hp_master_update(codec, hp, line, mono);
5486 return 1;
5489 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5492 .name = "Master Playback Switch",
5493 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5494 .info = snd_ctl_boolean_mono_info,
5495 .get = alc260_hp_master_sw_get,
5496 .put = alc260_hp_master_sw_put,
5497 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5499 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5500 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5501 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5502 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5503 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5504 HDA_OUTPUT),
5505 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5506 { } /* end */
5509 static struct hda_verb alc260_hp_unsol_verbs[] = {
5510 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5514 static void alc260_hp_automute(struct hda_codec *codec)
5516 struct alc_spec *spec = codec->spec;
5518 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5519 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5522 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5524 if ((res >> 26) == ALC880_HP_EVENT)
5525 alc260_hp_automute(codec);
5528 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5531 .name = "Master Playback Switch",
5532 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5533 .info = snd_ctl_boolean_mono_info,
5534 .get = alc260_hp_master_sw_get,
5535 .put = alc260_hp_master_sw_put,
5536 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5538 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5539 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5540 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5541 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5544 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5545 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5546 { } /* end */
5549 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5550 .ops = &snd_hda_bind_vol,
5551 .values = {
5552 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5553 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5554 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5559 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5560 .ops = &snd_hda_bind_sw,
5561 .values = {
5562 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5563 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5568 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5569 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5570 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5571 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5572 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5573 { } /* end */
5576 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5577 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5581 static void alc260_hp_3013_automute(struct hda_codec *codec)
5583 struct alc_spec *spec = codec->spec;
5585 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5586 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5589 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5590 unsigned int res)
5592 if ((res >> 26) == ALC880_HP_EVENT)
5593 alc260_hp_3013_automute(codec);
5596 static void alc260_hp_3012_automute(struct hda_codec *codec)
5598 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5600 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5601 bits);
5602 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5603 bits);
5604 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5605 bits);
5608 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5609 unsigned int res)
5611 if ((res >> 26) == ALC880_HP_EVENT)
5612 alc260_hp_3012_automute(codec);
5615 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5616 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5618 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5619 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5620 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5621 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5622 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5623 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5624 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5625 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5626 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5627 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5628 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5629 { } /* end */
5632 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5633 * versions of the ALC260 don't act on requests to enable mic bias from NID
5634 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5635 * datasheet doesn't mention this restriction. At this stage it's not clear
5636 * whether this behaviour is intentional or is a hardware bug in chip
5637 * revisions available in early 2006. Therefore for now allow the
5638 * "Headphone Jack Mode" control to span all choices, but if it turns out
5639 * that the lack of mic bias for this NID is intentional we could change the
5640 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5642 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5643 * don't appear to make the mic bias available from the "line" jack, even
5644 * though the NID used for this jack (0x14) can supply it. The theory is
5645 * that perhaps Acer have included blocking capacitors between the ALC260
5646 * and the output jack. If this turns out to be the case for all such
5647 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5648 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5650 * The C20x Tablet series have a mono internal speaker which is controlled
5651 * via the chip's Mono sum widget and pin complex, so include the necessary
5652 * controls for such models. On models without a "mono speaker" the control
5653 * won't do anything.
5655 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5656 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5657 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5658 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5659 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5660 HDA_OUTPUT),
5661 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5662 HDA_INPUT),
5663 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5664 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5666 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5667 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5668 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5669 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5670 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5671 { } /* end */
5674 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5676 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5677 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5678 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5679 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5680 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5681 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5682 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5683 { } /* end */
5686 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5687 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5689 static struct snd_kcontrol_new alc260_will_mixer[] = {
5690 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5691 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5693 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5694 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5695 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5696 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5697 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5698 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5699 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5700 { } /* end */
5703 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5704 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5706 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5707 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5708 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5710 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5711 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5712 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5713 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5714 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5715 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5716 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5717 { } /* end */
5721 * initialization verbs
5723 static struct hda_verb alc260_init_verbs[] = {
5724 /* Line In pin widget for input */
5725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5726 /* CD pin widget for input */
5727 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5728 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5729 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5730 /* Mic2 (front panel) pin widget for input and vref at 80% */
5731 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5732 /* LINE-2 is used for line-out in rear */
5733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5734 /* select line-out */
5735 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5736 /* LINE-OUT pin */
5737 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5738 /* enable HP */
5739 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5740 /* enable Mono */
5741 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5742 /* mute capture amp left and right */
5743 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5744 /* set connection select to line in (default select for this ADC) */
5745 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5746 /* mute capture amp left and right */
5747 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5748 /* set connection select to line in (default select for this ADC) */
5749 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5750 /* set vol=0 Line-Out mixer amp left and right */
5751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5752 /* unmute pin widget amp left and right (no gain on this amp) */
5753 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5754 /* set vol=0 HP mixer amp left and right */
5755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5756 /* unmute pin widget amp left and right (no gain on this amp) */
5757 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5758 /* set vol=0 Mono mixer amp left and right */
5759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5760 /* unmute pin widget amp left and right (no gain on this amp) */
5761 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5762 /* unmute LINE-2 out pin */
5763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5764 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5765 * Line In 2 = 0x03
5767 /* mute analog inputs */
5768 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5769 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5771 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5772 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5773 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5774 /* mute Front out path */
5775 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5776 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5777 /* mute Headphone out path */
5778 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5780 /* mute Mono out path */
5781 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5782 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5786 #if 0 /* should be identical with alc260_init_verbs? */
5787 static struct hda_verb alc260_hp_init_verbs[] = {
5788 /* Headphone and output */
5789 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5790 /* mono output */
5791 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5792 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5793 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5794 /* Mic2 (front panel) pin widget for input and vref at 80% */
5795 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5796 /* Line In pin widget for input */
5797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5798 /* Line-2 pin widget for output */
5799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5800 /* CD pin widget for input */
5801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5802 /* unmute amp left and right */
5803 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5804 /* set connection select to line in (default select for this ADC) */
5805 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5806 /* unmute Line-Out mixer amp left and right (volume = 0) */
5807 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5808 /* mute pin widget amp left and right (no gain on this amp) */
5809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5810 /* unmute HP mixer amp left and right (volume = 0) */
5811 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5812 /* mute pin widget amp left and right (no gain on this amp) */
5813 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5814 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5815 * Line In 2 = 0x03
5817 /* mute analog inputs */
5818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5823 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5824 /* Unmute Front out path */
5825 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5826 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5827 /* Unmute Headphone out path */
5828 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5830 /* Unmute Mono out path */
5831 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5832 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5835 #endif
5837 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5838 /* Line out and output */
5839 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5840 /* mono output */
5841 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5842 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5843 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5844 /* Mic2 (front panel) pin widget for input and vref at 80% */
5845 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5846 /* Line In pin widget for input */
5847 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5848 /* Headphone pin widget for output */
5849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5850 /* CD pin widget for input */
5851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5852 /* unmute amp left and right */
5853 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5854 /* set connection select to line in (default select for this ADC) */
5855 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5856 /* unmute Line-Out mixer amp left and right (volume = 0) */
5857 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5858 /* mute pin widget amp left and right (no gain on this amp) */
5859 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5860 /* unmute HP mixer amp left and right (volume = 0) */
5861 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5862 /* mute pin widget amp left and right (no gain on this amp) */
5863 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5864 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5865 * Line In 2 = 0x03
5867 /* mute analog inputs */
5868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5869 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5870 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5871 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5873 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5874 /* Unmute Front out path */
5875 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5876 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5877 /* Unmute Headphone out path */
5878 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5879 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5880 /* Unmute Mono out path */
5881 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5882 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5886 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5887 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5888 * audio = 0x16, internal speaker = 0x10.
5890 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5891 /* Disable all GPIOs */
5892 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5893 /* Internal speaker is connected to headphone pin */
5894 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5895 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5897 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5898 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5899 /* Ensure all other unused pins are disabled and muted. */
5900 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5901 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5902 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5903 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5904 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5905 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5909 /* Disable digital (SPDIF) pins */
5910 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5911 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5913 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5914 * when acting as an output.
5916 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5918 /* Start with output sum widgets muted and their output gains at min */
5919 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5920 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5921 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5922 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5923 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5924 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5925 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5926 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5927 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5929 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5930 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5931 /* Unmute Line1 pin widget output buffer since it starts as an output.
5932 * If the pin mode is changed by the user the pin mode control will
5933 * take care of enabling the pin's input/output buffers as needed.
5934 * Therefore there's no need to enable the input buffer at this
5935 * stage.
5937 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5938 /* Unmute input buffer of pin widget used for Line-in (no equiv
5939 * mixer ctrl)
5941 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5943 /* Mute capture amp left and right */
5944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5945 /* Set ADC connection select to match default mixer setting - line
5946 * in (on mic1 pin)
5948 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5950 /* Do the same for the second ADC: mute capture input amp and
5951 * set ADC connection to line in (on mic1 pin)
5953 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5954 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5956 /* Mute all inputs to mixer widget (even unconnected ones) */
5957 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5964 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5969 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5970 * similar laptops (adapted from Fujitsu init verbs).
5972 static struct hda_verb alc260_acer_init_verbs[] = {
5973 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5974 * the headphone jack. Turn this on and rely on the standard mute
5975 * methods whenever the user wants to turn these outputs off.
5977 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5978 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5979 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5980 /* Internal speaker/Headphone jack is connected to Line-out pin */
5981 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5982 /* Internal microphone/Mic jack is connected to Mic1 pin */
5983 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5984 /* Line In jack is connected to Line1 pin */
5985 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5986 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5987 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5988 /* Ensure all other unused pins are disabled and muted. */
5989 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5990 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5991 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5992 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5995 /* Disable digital (SPDIF) pins */
5996 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5997 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5999 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6000 * bus when acting as outputs.
6002 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6003 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6005 /* Start with output sum widgets muted and their output gains at min */
6006 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6007 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6009 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6010 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6011 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6012 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6013 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6014 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6016 /* Unmute Line-out pin widget amp left and right
6017 * (no equiv mixer ctrl)
6019 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6020 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6021 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6022 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6023 * inputs. If the pin mode is changed by the user the pin mode control
6024 * will take care of enabling the pin's input/output buffers as needed.
6025 * Therefore there's no need to enable the input buffer at this
6026 * stage.
6028 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6029 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6031 /* Mute capture amp left and right */
6032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6033 /* Set ADC connection select to match default mixer setting - mic
6034 * (on mic1 pin)
6036 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6038 /* Do similar with the second ADC: mute capture input amp and
6039 * set ADC connection to mic to match ALSA's default state.
6041 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6042 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6044 /* Mute all inputs to mixer widget (even unconnected ones) */
6045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6048 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6049 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6051 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6052 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6057 /* Initialisation sequence for Maxdata Favorit 100XS
6058 * (adapted from Acer init verbs).
6060 static struct hda_verb alc260_favorit100_init_verbs[] = {
6061 /* GPIO 0 enables the output jack.
6062 * Turn this on and rely on the standard mute
6063 * methods whenever the user wants to turn these outputs off.
6065 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6066 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6067 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6068 /* Line/Mic input jack is connected to Mic1 pin */
6069 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6070 /* Ensure all other unused pins are disabled and muted. */
6071 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6072 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6073 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6074 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6075 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6076 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6077 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6080 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6081 /* Disable digital (SPDIF) pins */
6082 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6083 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6085 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6086 * bus when acting as outputs.
6088 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6089 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6091 /* Start with output sum widgets muted and their output gains at min */
6092 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6093 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6094 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6095 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6096 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6097 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6098 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6099 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6100 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6102 /* Unmute Line-out pin widget amp left and right
6103 * (no equiv mixer ctrl)
6105 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6106 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6107 * inputs. If the pin mode is changed by the user the pin mode control
6108 * will take care of enabling the pin's input/output buffers as needed.
6109 * Therefore there's no need to enable the input buffer at this
6110 * stage.
6112 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6114 /* Mute capture amp left and right */
6115 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6116 /* Set ADC connection select to match default mixer setting - mic
6117 * (on mic1 pin)
6119 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6121 /* Do similar with the second ADC: mute capture input amp and
6122 * set ADC connection to mic to match ALSA's default state.
6124 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6125 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6127 /* Mute all inputs to mixer widget (even unconnected ones) */
6128 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6133 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6134 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6135 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6140 static struct hda_verb alc260_will_verbs[] = {
6141 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6142 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6143 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6144 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6145 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6146 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6150 static struct hda_verb alc260_replacer_672v_verbs[] = {
6151 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6152 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6153 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6155 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6156 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6157 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6159 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6163 /* toggle speaker-output according to the hp-jack state */
6164 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6166 unsigned int present;
6168 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6169 present = snd_hda_jack_detect(codec, 0x0f);
6170 if (present) {
6171 snd_hda_codec_write_cache(codec, 0x01, 0,
6172 AC_VERB_SET_GPIO_DATA, 1);
6173 snd_hda_codec_write_cache(codec, 0x0f, 0,
6174 AC_VERB_SET_PIN_WIDGET_CONTROL,
6175 PIN_HP);
6176 } else {
6177 snd_hda_codec_write_cache(codec, 0x01, 0,
6178 AC_VERB_SET_GPIO_DATA, 0);
6179 snd_hda_codec_write_cache(codec, 0x0f, 0,
6180 AC_VERB_SET_PIN_WIDGET_CONTROL,
6181 PIN_OUT);
6185 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6186 unsigned int res)
6188 if ((res >> 26) == ALC880_HP_EVENT)
6189 alc260_replacer_672v_automute(codec);
6192 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6193 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6194 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6195 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6196 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6197 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6199 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6200 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6201 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6202 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6206 /* Test configuration for debugging, modelled after the ALC880 test
6207 * configuration.
6209 #ifdef CONFIG_SND_DEBUG
6210 static hda_nid_t alc260_test_dac_nids[1] = {
6211 0x02,
6213 static hda_nid_t alc260_test_adc_nids[2] = {
6214 0x04, 0x05,
6216 /* For testing the ALC260, each input MUX needs its own definition since
6217 * the signal assignments are different. This assumes that the first ADC
6218 * is NID 0x04.
6220 static struct hda_input_mux alc260_test_capture_sources[2] = {
6222 .num_items = 7,
6223 .items = {
6224 { "MIC1 pin", 0x0 },
6225 { "MIC2 pin", 0x1 },
6226 { "LINE1 pin", 0x2 },
6227 { "LINE2 pin", 0x3 },
6228 { "CD pin", 0x4 },
6229 { "LINE-OUT pin", 0x5 },
6230 { "HP-OUT pin", 0x6 },
6234 .num_items = 8,
6235 .items = {
6236 { "MIC1 pin", 0x0 },
6237 { "MIC2 pin", 0x1 },
6238 { "LINE1 pin", 0x2 },
6239 { "LINE2 pin", 0x3 },
6240 { "CD pin", 0x4 },
6241 { "Mixer", 0x5 },
6242 { "LINE-OUT pin", 0x6 },
6243 { "HP-OUT pin", 0x7 },
6247 static struct snd_kcontrol_new alc260_test_mixer[] = {
6248 /* Output driver widgets */
6249 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6250 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6251 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6252 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6253 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6254 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6256 /* Modes for retasking pin widgets
6257 * Note: the ALC260 doesn't seem to act on requests to enable mic
6258 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6259 * mention this restriction. At this stage it's not clear whether
6260 * this behaviour is intentional or is a hardware bug in chip
6261 * revisions available at least up until early 2006. Therefore for
6262 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6263 * choices, but if it turns out that the lack of mic bias for these
6264 * NIDs is intentional we could change their modes from
6265 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6267 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6268 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6269 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6270 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6271 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6272 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6274 /* Loopback mixer controls */
6275 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6276 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6277 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6278 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6279 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6280 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6281 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6282 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6283 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6284 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6285 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6286 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6287 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6288 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6290 /* Controls for GPIO pins, assuming they are configured as outputs */
6291 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6292 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6293 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6294 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6296 /* Switches to allow the digital IO pins to be enabled. The datasheet
6297 * is ambigious as to which NID is which; testing on laptops which
6298 * make this output available should provide clarification.
6300 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6301 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6303 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6304 * this output to turn on an external amplifier.
6306 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6307 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6309 { } /* end */
6311 static struct hda_verb alc260_test_init_verbs[] = {
6312 /* Enable all GPIOs as outputs with an initial value of 0 */
6313 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6314 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6315 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6317 /* Enable retasking pins as output, initially without power amp */
6318 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6319 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6320 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6321 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6322 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6323 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6325 /* Disable digital (SPDIF) pins initially, but users can enable
6326 * them via a mixer switch. In the case of SPDIF-out, this initverb
6327 * payload also sets the generation to 0, output to be in "consumer"
6328 * PCM format, copyright asserted, no pre-emphasis and no validity
6329 * control.
6331 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6332 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6334 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6335 * OUT1 sum bus when acting as an output.
6337 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6338 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6339 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6340 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6342 /* Start with output sum widgets muted and their output gains at min */
6343 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6344 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6345 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6346 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6347 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6348 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6349 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6350 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6351 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6353 /* Unmute retasking pin widget output buffers since the default
6354 * state appears to be output. As the pin mode is changed by the
6355 * user the pin mode control will take care of enabling the pin's
6356 * input/output buffers as needed.
6358 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6359 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6360 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6361 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6362 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6363 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6364 /* Also unmute the mono-out pin widget */
6365 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367 /* Mute capture amp left and right */
6368 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6369 /* Set ADC connection select to match default mixer setting (mic1
6370 * pin)
6372 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6374 /* Do the same for the second ADC: mute capture input amp and
6375 * set ADC connection to mic1 pin
6377 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6378 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6380 /* Mute all inputs to mixer widget (even unconnected ones) */
6381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6383 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6386 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6387 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6388 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6392 #endif
6394 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6395 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6397 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6398 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6401 * for BIOS auto-configuration
6404 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6405 const char *pfx, int *vol_bits)
6407 hda_nid_t nid_vol;
6408 unsigned long vol_val, sw_val;
6409 int err;
6411 if (nid >= 0x0f && nid < 0x11) {
6412 nid_vol = nid - 0x7;
6413 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6414 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6415 } else if (nid == 0x11) {
6416 nid_vol = nid - 0x7;
6417 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6418 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6419 } else if (nid >= 0x12 && nid <= 0x15) {
6420 nid_vol = 0x08;
6421 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6422 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6423 } else
6424 return 0; /* N/A */
6426 if (!(*vol_bits & (1 << nid_vol))) {
6427 /* first control for the volume widget */
6428 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6429 if (err < 0)
6430 return err;
6431 *vol_bits |= (1 << nid_vol);
6433 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6434 if (err < 0)
6435 return err;
6436 return 1;
6439 /* add playback controls from the parsed DAC table */
6440 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6441 const struct auto_pin_cfg *cfg)
6443 hda_nid_t nid;
6444 int err;
6445 int vols = 0;
6447 spec->multiout.num_dacs = 1;
6448 spec->multiout.dac_nids = spec->private_dac_nids;
6449 spec->multiout.dac_nids[0] = 0x02;
6451 nid = cfg->line_out_pins[0];
6452 if (nid) {
6453 const char *pfx;
6454 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6455 pfx = "Master";
6456 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6457 pfx = "Speaker";
6458 else
6459 pfx = "Front";
6460 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6461 if (err < 0)
6462 return err;
6465 nid = cfg->speaker_pins[0];
6466 if (nid) {
6467 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6468 if (err < 0)
6469 return err;
6472 nid = cfg->hp_pins[0];
6473 if (nid) {
6474 err = alc260_add_playback_controls(spec, nid, "Headphone",
6475 &vols);
6476 if (err < 0)
6477 return err;
6479 return 0;
6482 /* create playback/capture controls for input pins */
6483 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6484 const struct auto_pin_cfg *cfg)
6486 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6489 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6490 hda_nid_t nid, int pin_type,
6491 int sel_idx)
6493 alc_set_pin_output(codec, nid, pin_type);
6494 /* need the manual connection? */
6495 if (nid >= 0x12) {
6496 int idx = nid - 0x12;
6497 snd_hda_codec_write(codec, idx + 0x0b, 0,
6498 AC_VERB_SET_CONNECT_SEL, sel_idx);
6502 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6504 struct alc_spec *spec = codec->spec;
6505 hda_nid_t nid;
6507 nid = spec->autocfg.line_out_pins[0];
6508 if (nid) {
6509 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6510 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6513 nid = spec->autocfg.speaker_pins[0];
6514 if (nid)
6515 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6517 nid = spec->autocfg.hp_pins[0];
6518 if (nid)
6519 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6522 #define ALC260_PIN_CD_NID 0x16
6523 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6525 struct alc_spec *spec = codec->spec;
6526 int i;
6528 for (i = 0; i < AUTO_PIN_LAST; i++) {
6529 hda_nid_t nid = spec->autocfg.input_pins[i];
6530 if (nid >= 0x12) {
6531 alc_set_input_pin(codec, nid, i);
6532 if (nid != ALC260_PIN_CD_NID &&
6533 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6534 snd_hda_codec_write(codec, nid, 0,
6535 AC_VERB_SET_AMP_GAIN_MUTE,
6536 AMP_OUT_MUTE);
6541 #define alc260_auto_init_input_src alc880_auto_init_input_src
6544 * generic initialization of ADC, input mixers and output mixers
6546 static struct hda_verb alc260_volume_init_verbs[] = {
6548 * Unmute ADC0-1 and set the default input to mic-in
6550 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6551 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6552 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6553 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6555 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6556 * mixer widget
6557 * Note: PASD motherboards uses the Line In 2 as the input for
6558 * front panel mic (mic 2)
6560 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6561 /* mute analog inputs */
6562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6564 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6569 * Set up output mixers (0x08 - 0x0a)
6571 /* set vol=0 to output mixers */
6572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6574 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6575 /* set up input amps for analog loopback */
6576 /* Amp Indices: DAC = 0, mixer = 1 */
6577 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6579 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6580 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6581 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6582 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6587 static int alc260_parse_auto_config(struct hda_codec *codec)
6589 struct alc_spec *spec = codec->spec;
6590 int err;
6591 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6593 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6594 alc260_ignore);
6595 if (err < 0)
6596 return err;
6597 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6598 if (err < 0)
6599 return err;
6600 if (!spec->kctls.list)
6601 return 0; /* can't find valid BIOS pin config */
6602 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6603 if (err < 0)
6604 return err;
6606 spec->multiout.max_channels = 2;
6608 if (spec->autocfg.dig_outs)
6609 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6610 if (spec->kctls.list)
6611 add_mixer(spec, spec->kctls.list);
6613 add_verb(spec, alc260_volume_init_verbs);
6615 spec->num_mux_defs = 1;
6616 spec->input_mux = &spec->private_imux[0];
6618 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6620 return 1;
6623 /* additional initialization for auto-configuration model */
6624 static void alc260_auto_init(struct hda_codec *codec)
6626 struct alc_spec *spec = codec->spec;
6627 alc260_auto_init_multi_out(codec);
6628 alc260_auto_init_analog_input(codec);
6629 alc260_auto_init_input_src(codec);
6630 if (spec->unsol_event)
6631 alc_inithook(codec);
6634 #ifdef CONFIG_SND_HDA_POWER_SAVE
6635 static struct hda_amp_list alc260_loopbacks[] = {
6636 { 0x07, HDA_INPUT, 0 },
6637 { 0x07, HDA_INPUT, 1 },
6638 { 0x07, HDA_INPUT, 2 },
6639 { 0x07, HDA_INPUT, 3 },
6640 { 0x07, HDA_INPUT, 4 },
6641 { } /* end */
6643 #endif
6646 * ALC260 configurations
6648 static const char *alc260_models[ALC260_MODEL_LAST] = {
6649 [ALC260_BASIC] = "basic",
6650 [ALC260_HP] = "hp",
6651 [ALC260_HP_3013] = "hp-3013",
6652 [ALC260_HP_DC7600] = "hp-dc7600",
6653 [ALC260_FUJITSU_S702X] = "fujitsu",
6654 [ALC260_ACER] = "acer",
6655 [ALC260_WILL] = "will",
6656 [ALC260_REPLACER_672V] = "replacer",
6657 [ALC260_FAVORIT100] = "favorit100",
6658 #ifdef CONFIG_SND_DEBUG
6659 [ALC260_TEST] = "test",
6660 #endif
6661 [ALC260_AUTO] = "auto",
6664 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6665 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6666 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6667 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6668 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6669 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6670 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6671 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6672 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6673 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6674 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6675 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6676 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6677 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6678 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6679 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6680 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6681 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6682 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6683 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6684 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6688 static struct alc_config_preset alc260_presets[] = {
6689 [ALC260_BASIC] = {
6690 .mixers = { alc260_base_output_mixer,
6691 alc260_input_mixer },
6692 .init_verbs = { alc260_init_verbs },
6693 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6694 .dac_nids = alc260_dac_nids,
6695 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6696 .adc_nids = alc260_dual_adc_nids,
6697 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6698 .channel_mode = alc260_modes,
6699 .input_mux = &alc260_capture_source,
6701 [ALC260_HP] = {
6702 .mixers = { alc260_hp_output_mixer,
6703 alc260_input_mixer },
6704 .init_verbs = { alc260_init_verbs,
6705 alc260_hp_unsol_verbs },
6706 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6707 .dac_nids = alc260_dac_nids,
6708 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6709 .adc_nids = alc260_adc_nids_alt,
6710 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6711 .channel_mode = alc260_modes,
6712 .input_mux = &alc260_capture_source,
6713 .unsol_event = alc260_hp_unsol_event,
6714 .init_hook = alc260_hp_automute,
6716 [ALC260_HP_DC7600] = {
6717 .mixers = { alc260_hp_dc7600_mixer,
6718 alc260_input_mixer },
6719 .init_verbs = { alc260_init_verbs,
6720 alc260_hp_dc7600_verbs },
6721 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6722 .dac_nids = alc260_dac_nids,
6723 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6724 .adc_nids = alc260_adc_nids_alt,
6725 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6726 .channel_mode = alc260_modes,
6727 .input_mux = &alc260_capture_source,
6728 .unsol_event = alc260_hp_3012_unsol_event,
6729 .init_hook = alc260_hp_3012_automute,
6731 [ALC260_HP_3013] = {
6732 .mixers = { alc260_hp_3013_mixer,
6733 alc260_input_mixer },
6734 .init_verbs = { alc260_hp_3013_init_verbs,
6735 alc260_hp_3013_unsol_verbs },
6736 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6737 .dac_nids = alc260_dac_nids,
6738 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6739 .adc_nids = alc260_adc_nids_alt,
6740 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6741 .channel_mode = alc260_modes,
6742 .input_mux = &alc260_capture_source,
6743 .unsol_event = alc260_hp_3013_unsol_event,
6744 .init_hook = alc260_hp_3013_automute,
6746 [ALC260_FUJITSU_S702X] = {
6747 .mixers = { alc260_fujitsu_mixer },
6748 .init_verbs = { alc260_fujitsu_init_verbs },
6749 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6750 .dac_nids = alc260_dac_nids,
6751 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6752 .adc_nids = alc260_dual_adc_nids,
6753 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6754 .channel_mode = alc260_modes,
6755 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6756 .input_mux = alc260_fujitsu_capture_sources,
6758 [ALC260_ACER] = {
6759 .mixers = { alc260_acer_mixer },
6760 .init_verbs = { alc260_acer_init_verbs },
6761 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6762 .dac_nids = alc260_dac_nids,
6763 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6764 .adc_nids = alc260_dual_adc_nids,
6765 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6766 .channel_mode = alc260_modes,
6767 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6768 .input_mux = alc260_acer_capture_sources,
6770 [ALC260_FAVORIT100] = {
6771 .mixers = { alc260_favorit100_mixer },
6772 .init_verbs = { alc260_favorit100_init_verbs },
6773 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6774 .dac_nids = alc260_dac_nids,
6775 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6776 .adc_nids = alc260_dual_adc_nids,
6777 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6778 .channel_mode = alc260_modes,
6779 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6780 .input_mux = alc260_favorit100_capture_sources,
6782 [ALC260_WILL] = {
6783 .mixers = { alc260_will_mixer },
6784 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6785 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6786 .dac_nids = alc260_dac_nids,
6787 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6788 .adc_nids = alc260_adc_nids,
6789 .dig_out_nid = ALC260_DIGOUT_NID,
6790 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6791 .channel_mode = alc260_modes,
6792 .input_mux = &alc260_capture_source,
6794 [ALC260_REPLACER_672V] = {
6795 .mixers = { alc260_replacer_672v_mixer },
6796 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6797 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6798 .dac_nids = alc260_dac_nids,
6799 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6800 .adc_nids = alc260_adc_nids,
6801 .dig_out_nid = ALC260_DIGOUT_NID,
6802 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6803 .channel_mode = alc260_modes,
6804 .input_mux = &alc260_capture_source,
6805 .unsol_event = alc260_replacer_672v_unsol_event,
6806 .init_hook = alc260_replacer_672v_automute,
6808 #ifdef CONFIG_SND_DEBUG
6809 [ALC260_TEST] = {
6810 .mixers = { alc260_test_mixer },
6811 .init_verbs = { alc260_test_init_verbs },
6812 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6813 .dac_nids = alc260_test_dac_nids,
6814 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6815 .adc_nids = alc260_test_adc_nids,
6816 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6817 .channel_mode = alc260_modes,
6818 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6819 .input_mux = alc260_test_capture_sources,
6821 #endif
6824 static int patch_alc260(struct hda_codec *codec)
6826 struct alc_spec *spec;
6827 int err, board_config;
6829 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6830 if (spec == NULL)
6831 return -ENOMEM;
6833 codec->spec = spec;
6835 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6836 alc260_models,
6837 alc260_cfg_tbl);
6838 if (board_config < 0) {
6839 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6840 codec->chip_name);
6841 board_config = ALC260_AUTO;
6844 if (board_config == ALC260_AUTO) {
6845 /* automatic parse from the BIOS config */
6846 err = alc260_parse_auto_config(codec);
6847 if (err < 0) {
6848 alc_free(codec);
6849 return err;
6850 } else if (!err) {
6851 printk(KERN_INFO
6852 "hda_codec: Cannot set up configuration "
6853 "from BIOS. Using base mode...\n");
6854 board_config = ALC260_BASIC;
6858 err = snd_hda_attach_beep_device(codec, 0x1);
6859 if (err < 0) {
6860 alc_free(codec);
6861 return err;
6864 if (board_config != ALC260_AUTO)
6865 setup_preset(codec, &alc260_presets[board_config]);
6867 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6868 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6869 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
6871 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6872 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6874 if (!spec->adc_nids && spec->input_mux) {
6875 /* check whether NID 0x04 is valid */
6876 unsigned int wcap = get_wcaps(codec, 0x04);
6877 wcap = get_wcaps_type(wcap);
6878 /* get type */
6879 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6880 spec->adc_nids = alc260_adc_nids_alt;
6881 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6882 } else {
6883 spec->adc_nids = alc260_adc_nids;
6884 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6887 set_capture_mixer(codec);
6888 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6890 spec->vmaster_nid = 0x08;
6892 codec->patch_ops = alc_patch_ops;
6893 if (board_config == ALC260_AUTO)
6894 spec->init_hook = alc260_auto_init;
6895 #ifdef CONFIG_SND_HDA_POWER_SAVE
6896 if (!spec->loopback.amplist)
6897 spec->loopback.amplist = alc260_loopbacks;
6898 #endif
6900 return 0;
6905 * ALC882/883/885/888/889 support
6907 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6908 * configuration. Each pin widget can choose any input DACs and a mixer.
6909 * Each ADC is connected from a mixer of all inputs. This makes possible
6910 * 6-channel independent captures.
6912 * In addition, an independent DAC for the multi-playback (not used in this
6913 * driver yet).
6915 #define ALC882_DIGOUT_NID 0x06
6916 #define ALC882_DIGIN_NID 0x0a
6917 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6918 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6919 #define ALC1200_DIGOUT_NID 0x10
6922 static struct hda_channel_mode alc882_ch_modes[1] = {
6923 { 8, NULL }
6926 /* DACs */
6927 static hda_nid_t alc882_dac_nids[4] = {
6928 /* front, rear, clfe, rear_surr */
6929 0x02, 0x03, 0x04, 0x05
6931 #define alc883_dac_nids alc882_dac_nids
6933 /* ADCs */
6934 #define alc882_adc_nids alc880_adc_nids
6935 #define alc882_adc_nids_alt alc880_adc_nids_alt
6936 #define alc883_adc_nids alc882_adc_nids_alt
6937 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6938 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6939 #define alc889_adc_nids alc880_adc_nids
6941 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6942 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6943 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6944 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6945 #define alc889_capsrc_nids alc882_capsrc_nids
6947 /* input MUX */
6948 /* FIXME: should be a matrix-type input source selection */
6950 static struct hda_input_mux alc882_capture_source = {
6951 .num_items = 4,
6952 .items = {
6953 { "Mic", 0x0 },
6954 { "Front Mic", 0x1 },
6955 { "Line", 0x2 },
6956 { "CD", 0x4 },
6960 #define alc883_capture_source alc882_capture_source
6962 static struct hda_input_mux alc889_capture_source = {
6963 .num_items = 3,
6964 .items = {
6965 { "Front Mic", 0x0 },
6966 { "Mic", 0x3 },
6967 { "Line", 0x2 },
6971 static struct hda_input_mux mb5_capture_source = {
6972 .num_items = 3,
6973 .items = {
6974 { "Mic", 0x1 },
6975 { "Line", 0x7 },
6976 { "CD", 0x4 },
6980 static struct hda_input_mux macmini3_capture_source = {
6981 .num_items = 2,
6982 .items = {
6983 { "Line", 0x2 },
6984 { "CD", 0x4 },
6988 static struct hda_input_mux alc883_3stack_6ch_intel = {
6989 .num_items = 4,
6990 .items = {
6991 { "Mic", 0x1 },
6992 { "Front Mic", 0x0 },
6993 { "Line", 0x2 },
6994 { "CD", 0x4 },
6998 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6999 .num_items = 2,
7000 .items = {
7001 { "Mic", 0x1 },
7002 { "Line", 0x2 },
7006 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7007 .num_items = 4,
7008 .items = {
7009 { "Mic", 0x0 },
7010 { "Int Mic", 0x1 },
7011 { "Line", 0x2 },
7012 { "CD", 0x4 },
7016 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7017 .num_items = 2,
7018 .items = {
7019 { "Mic", 0x0 },
7020 { "Int Mic", 0x1 },
7024 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7025 .num_items = 3,
7026 .items = {
7027 { "Mic", 0x0 },
7028 { "Front Mic", 0x1 },
7029 { "Line", 0x4 },
7033 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7034 .num_items = 2,
7035 .items = {
7036 { "Mic", 0x0 },
7037 { "Line", 0x2 },
7041 static struct hda_input_mux alc889A_mb31_capture_source = {
7042 .num_items = 2,
7043 .items = {
7044 { "Mic", 0x0 },
7045 /* Front Mic (0x01) unused */
7046 { "Line", 0x2 },
7047 /* Line 2 (0x03) unused */
7048 /* CD (0x04) unused? */
7052 static struct hda_input_mux alc889A_imac91_capture_source = {
7053 .num_items = 2,
7054 .items = {
7055 { "Mic", 0x01 },
7056 { "Line", 0x2 }, /* Not sure! */
7061 * 2ch mode
7063 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7064 { 2, NULL }
7068 * 2ch mode
7070 static struct hda_verb alc882_3ST_ch2_init[] = {
7071 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7072 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7073 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7074 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7075 { } /* end */
7079 * 4ch mode
7081 static struct hda_verb alc882_3ST_ch4_init[] = {
7082 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7083 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7084 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7085 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7086 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7087 { } /* end */
7091 * 6ch mode
7093 static struct hda_verb alc882_3ST_ch6_init[] = {
7094 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7095 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7096 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7097 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7098 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7099 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7100 { } /* end */
7103 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7104 { 2, alc882_3ST_ch2_init },
7105 { 4, alc882_3ST_ch4_init },
7106 { 6, alc882_3ST_ch6_init },
7109 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7112 * 2ch mode
7114 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7115 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7116 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7117 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7118 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7119 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7120 { } /* end */
7124 * 4ch mode
7126 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7127 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7130 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7131 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7132 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7133 { } /* end */
7137 * 6ch mode
7139 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7140 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7141 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7142 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7143 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7144 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7145 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7146 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7147 { } /* end */
7150 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7151 { 2, alc883_3ST_ch2_clevo_init },
7152 { 4, alc883_3ST_ch4_clevo_init },
7153 { 6, alc883_3ST_ch6_clevo_init },
7158 * 6ch mode
7160 static struct hda_verb alc882_sixstack_ch6_init[] = {
7161 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7162 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7163 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7164 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7165 { } /* end */
7169 * 8ch mode
7171 static struct hda_verb alc882_sixstack_ch8_init[] = {
7172 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7173 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7174 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7175 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7176 { } /* end */
7179 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7180 { 6, alc882_sixstack_ch6_init },
7181 { 8, alc882_sixstack_ch8_init },
7185 /* Macbook Air 2,1 */
7187 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7188 { 2, NULL },
7192 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7196 * 2ch mode
7198 static struct hda_verb alc885_mbp_ch2_init[] = {
7199 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7200 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7201 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7202 { } /* end */
7206 * 4ch mode
7208 static struct hda_verb alc885_mbp_ch4_init[] = {
7209 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7210 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7211 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
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 { } /* end */
7217 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7218 { 2, alc885_mbp_ch2_init },
7219 { 4, alc885_mbp_ch4_init },
7223 * 2ch
7224 * Speakers/Woofer/HP = Front
7225 * LineIn = Input
7227 static struct hda_verb alc885_mb5_ch2_init[] = {
7228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7229 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7230 { } /* end */
7234 * 6ch mode
7235 * Speakers/HP = Front
7236 * Woofer = LFE
7237 * LineIn = Surround
7239 static struct hda_verb alc885_mb5_ch6_init[] = {
7240 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7241 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7242 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7243 { } /* end */
7246 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7247 { 2, alc885_mb5_ch2_init },
7248 { 6, alc885_mb5_ch6_init },
7251 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7254 * 2ch mode
7256 static struct hda_verb alc883_4ST_ch2_init[] = {
7257 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7258 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7259 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7260 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7261 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7262 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7263 { } /* end */
7267 * 4ch mode
7269 static struct hda_verb alc883_4ST_ch4_init[] = {
7270 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7271 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7272 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7273 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7274 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7275 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7276 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7277 { } /* end */
7281 * 6ch mode
7283 static struct hda_verb alc883_4ST_ch6_init[] = {
7284 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7285 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7286 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7287 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7288 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7289 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7290 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7291 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7292 { } /* end */
7296 * 8ch mode
7298 static struct hda_verb alc883_4ST_ch8_init[] = {
7299 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7300 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7301 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7302 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7303 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7304 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7305 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7307 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7308 { } /* end */
7311 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7312 { 2, alc883_4ST_ch2_init },
7313 { 4, alc883_4ST_ch4_init },
7314 { 6, alc883_4ST_ch6_init },
7315 { 8, alc883_4ST_ch8_init },
7320 * 2ch mode
7322 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7323 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7324 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7325 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7326 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7327 { } /* end */
7331 * 4ch mode
7333 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7334 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7335 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7336 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7337 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7338 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7339 { } /* end */
7343 * 6ch mode
7345 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7346 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7347 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7348 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7349 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7350 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7351 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7352 { } /* end */
7355 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7356 { 2, alc883_3ST_ch2_intel_init },
7357 { 4, alc883_3ST_ch4_intel_init },
7358 { 6, alc883_3ST_ch6_intel_init },
7362 * 2ch mode
7364 static struct hda_verb alc889_ch2_intel_init[] = {
7365 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7366 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7367 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7368 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7369 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7370 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7371 { } /* end */
7375 * 6ch mode
7377 static struct hda_verb alc889_ch6_intel_init[] = {
7378 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7379 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7380 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7381 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7382 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7383 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7384 { } /* end */
7388 * 8ch mode
7390 static struct hda_verb alc889_ch8_intel_init[] = {
7391 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7392 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7393 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7394 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7395 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7396 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7397 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7398 { } /* end */
7401 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7402 { 2, alc889_ch2_intel_init },
7403 { 6, alc889_ch6_intel_init },
7404 { 8, alc889_ch8_intel_init },
7408 * 6ch mode
7410 static struct hda_verb alc883_sixstack_ch6_init[] = {
7411 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7412 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7413 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7414 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7415 { } /* end */
7419 * 8ch mode
7421 static struct hda_verb alc883_sixstack_ch8_init[] = {
7422 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7423 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7424 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7425 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { } /* end */
7429 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7430 { 6, alc883_sixstack_ch6_init },
7431 { 8, alc883_sixstack_ch8_init },
7435 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7436 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7438 static struct snd_kcontrol_new alc882_base_mixer[] = {
7439 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7440 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7441 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7442 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7443 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7444 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7445 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7446 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7447 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7448 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7449 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7450 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7451 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7452 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7453 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7455 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7458 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7460 { } /* end */
7463 /* Macbook Air 2,1 same control for HP and internal Speaker */
7465 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7466 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7467 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7472 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7473 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7474 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7475 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7476 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7477 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7478 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7479 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7481 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7482 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7484 { } /* end */
7487 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7488 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7489 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7491 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7492 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7493 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7494 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7495 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7496 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7497 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7499 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7500 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7501 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7502 { } /* end */
7505 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7506 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7507 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7508 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7509 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7510 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7511 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7512 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7513 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7515 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7516 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7517 { } /* end */
7520 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7521 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7522 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7523 { } /* end */
7527 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7529 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7535 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7537 { } /* end */
7540 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7543 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7545 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7547 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7551 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7552 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7553 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7554 { } /* end */
7557 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7558 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7560 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7561 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7562 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7563 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7564 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7565 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7566 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7567 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7568 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7569 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7570 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7571 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7572 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7573 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7574 { } /* end */
7577 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7578 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7579 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7580 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7586 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7588 { } /* end */
7591 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7593 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7594 .name = "Channel Mode",
7595 .info = alc_ch_mode_info,
7596 .get = alc_ch_mode_get,
7597 .put = alc_ch_mode_put,
7599 { } /* end */
7602 static struct hda_verb alc882_base_init_verbs[] = {
7603 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7606 /* Rear mixer */
7607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7609 /* CLFE mixer */
7610 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7612 /* Side mixer */
7613 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7616 /* Front Pin: output 0 (0x0c) */
7617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7618 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7619 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 /* Rear Pin: output 1 (0x0d) */
7621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7623 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7624 /* CLFE Pin: output 2 (0x0e) */
7625 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7626 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7627 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7628 /* Side Pin: output 3 (0x0f) */
7629 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7631 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7632 /* Mic (rear) pin: input vref at 80% */
7633 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7634 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7635 /* Front Mic pin: input vref at 80% */
7636 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7637 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7638 /* Line In pin: input */
7639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7640 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7641 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7642 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7643 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7644 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7645 /* CD pin widget for input */
7646 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7648 /* FIXME: use matrix-type input source selection */
7649 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7650 /* Input mixer2 */
7651 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7652 /* Input mixer3 */
7653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7654 /* ADC2: mute amp left and right */
7655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7656 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7657 /* ADC3: mute amp left and right */
7658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7659 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7664 static struct hda_verb alc882_adc1_init_verbs[] = {
7665 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7670 /* ADC1: mute amp left and right */
7671 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7672 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7676 static struct hda_verb alc882_eapd_verbs[] = {
7677 /* change to EAPD mode */
7678 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7679 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7683 static struct hda_verb alc889_eapd_verbs[] = {
7684 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7685 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7689 static struct hda_verb alc_hp15_unsol_verbs[] = {
7690 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7695 static struct hda_verb alc885_init_verbs[] = {
7696 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7697 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7698 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7699 /* Rear mixer */
7700 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7701 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7702 /* CLFE mixer */
7703 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7704 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7705 /* Side mixer */
7706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7707 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7709 /* Front HP Pin: output 0 (0x0c) */
7710 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7711 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7712 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7713 /* Front Pin: output 0 (0x0c) */
7714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7716 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7717 /* Rear Pin: output 1 (0x0d) */
7718 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7720 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7721 /* CLFE Pin: output 2 (0x0e) */
7722 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7723 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7724 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7725 /* Side Pin: output 3 (0x0f) */
7726 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7727 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7728 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7729 /* Mic (rear) pin: input vref at 80% */
7730 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7731 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7732 /* Front Mic pin: input vref at 80% */
7733 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7734 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7735 /* Line In pin: input */
7736 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7739 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7740 /* Input mixer1 */
7741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7742 /* Input mixer2 */
7743 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7744 /* Input mixer3 */
7745 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7746 /* ADC2: mute amp left and right */
7747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7748 /* ADC3: mute amp left and right */
7749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7754 static struct hda_verb alc885_init_input_verbs[] = {
7755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7756 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7757 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7762 /* Unmute Selector 24h and set the default input to front mic */
7763 static struct hda_verb alc889_init_input_verbs[] = {
7764 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7770 #define alc883_init_verbs alc882_base_init_verbs
7772 /* Mac Pro test */
7773 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7774 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7776 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7777 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7778 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7779 /* FIXME: this looks suspicious...
7780 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7781 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7783 { } /* end */
7786 static struct hda_verb alc882_macpro_init_verbs[] = {
7787 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7791 /* Front Pin: output 0 (0x0c) */
7792 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7794 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7795 /* Front Mic pin: input vref at 80% */
7796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7798 /* Speaker: output */
7799 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7801 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7802 /* Headphone output (output 0 - 0x0c) */
7803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7805 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7807 /* FIXME: use matrix-type input source selection */
7808 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7809 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7812 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7813 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7814 /* Input mixer2 */
7815 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7816 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7817 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7818 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7819 /* Input mixer3 */
7820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7824 /* ADC1: mute amp left and right */
7825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7826 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7827 /* ADC2: mute amp left and right */
7828 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7829 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7830 /* ADC3: mute amp left and right */
7831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7832 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7837 /* Macbook 5,1 */
7838 static struct hda_verb alc885_mb5_init_verbs[] = {
7839 /* DACs */
7840 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7841 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7842 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7843 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7844 /* Front mixer */
7845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7847 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7848 /* Surround mixer */
7849 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7851 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7852 /* LFE mixer */
7853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7854 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7855 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7856 /* HP mixer */
7857 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7858 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7859 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7860 /* Front Pin (0x0c) */
7861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7862 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7863 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7864 /* LFE Pin (0x0e) */
7865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7867 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7868 /* HP Pin (0x0f) */
7869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7871 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7872 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7873 /* Front Mic pin: input vref at 80% */
7874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7875 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7876 /* Line In pin */
7877 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7880 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
7881 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
7882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
7886 /* Macmini 3,1 */
7887 static struct hda_verb alc885_macmini3_init_verbs[] = {
7888 /* DACs */
7889 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7890 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7892 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7893 /* Front mixer */
7894 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7895 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7896 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7897 /* Surround mixer */
7898 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7899 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7901 /* LFE mixer */
7902 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7905 /* HP mixer */
7906 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7907 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7908 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7909 /* Front Pin (0x0c) */
7910 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7911 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7912 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7913 /* LFE Pin (0x0e) */
7914 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7915 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7916 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7917 /* HP Pin (0x0f) */
7918 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7919 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7920 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7921 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7922 /* Line In pin */
7923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7929 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7934 static struct hda_verb alc885_mba21_init_verbs[] = {
7935 /*Internal and HP Speaker Mixer*/
7936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7937 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7938 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7939 /*Internal Speaker Pin (0x0c)*/
7940 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7941 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7943 /* HP Pin: output 0 (0x0e) */
7944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7945 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7946 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7947 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7948 /* Line in (is hp when jack connected)*/
7949 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7950 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7956 /* Macbook Pro rev3 */
7957 static struct hda_verb alc885_mbp3_init_verbs[] = {
7958 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7961 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7962 /* Rear mixer */
7963 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7964 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7966 /* HP mixer */
7967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7968 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7970 /* Front Pin: output 0 (0x0c) */
7971 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7972 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7973 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7974 /* HP Pin: output 0 (0x0e) */
7975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7979 /* Mic (rear) pin: input vref at 80% */
7980 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7981 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7982 /* Front Mic pin: input vref at 80% */
7983 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7984 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7985 /* Line In pin: use output 1 when in LineOut mode */
7986 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7987 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7988 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7990 /* FIXME: use matrix-type input source selection */
7991 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7992 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7997 /* Input mixer2 */
7998 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8002 /* Input mixer3 */
8003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8007 /* ADC1: mute amp left and right */
8008 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8009 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8010 /* ADC2: mute amp left and right */
8011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8012 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8013 /* ADC3: mute amp left and right */
8014 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8015 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8020 /* iMac 9,1 */
8021 static struct hda_verb alc885_imac91_init_verbs[] = {
8022 /* Internal Speaker Pin (0x0c) */
8023 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8024 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8025 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8026 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8028 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8029 /* HP Pin: Rear */
8030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8031 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8033 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8034 /* Line in Rear */
8035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8037 /* Front Mic pin: input vref at 80% */
8038 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8039 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8040 /* Rear mixer */
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8042 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8043 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8044 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8048 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8049 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8051 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8052 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8053 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8058 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8063 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8065 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8066 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8067 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8068 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8069 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8070 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8071 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8075 /* iMac 24 mixer. */
8076 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8077 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8078 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8079 { } /* end */
8082 /* iMac 24 init verbs. */
8083 static struct hda_verb alc885_imac24_init_verbs[] = {
8084 /* Internal speakers: output 0 (0x0c) */
8085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8086 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8087 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 /* Internal speakers: output 0 (0x0c) */
8089 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8090 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8091 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8092 /* Headphone: output 0 (0x0c) */
8093 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8094 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8095 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8096 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8097 /* Front Mic: input vref at 80% */
8098 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8103 /* Toggle speaker-output according to the hp-jack state */
8104 static void alc885_imac24_setup(struct hda_codec *codec)
8106 struct alc_spec *spec = codec->spec;
8108 spec->autocfg.hp_pins[0] = 0x14;
8109 spec->autocfg.speaker_pins[0] = 0x18;
8110 spec->autocfg.speaker_pins[1] = 0x1a;
8113 #define alc885_mb5_setup alc885_imac24_setup
8114 #define alc885_macmini3_setup alc885_imac24_setup
8116 /* Macbook Air 2,1 */
8117 static void alc885_mba21_setup(struct hda_codec *codec)
8119 struct alc_spec *spec = codec->spec;
8121 spec->autocfg.hp_pins[0] = 0x14;
8122 spec->autocfg.speaker_pins[0] = 0x18;
8127 static void alc885_mbp3_setup(struct hda_codec *codec)
8129 struct alc_spec *spec = codec->spec;
8131 spec->autocfg.hp_pins[0] = 0x15;
8132 spec->autocfg.speaker_pins[0] = 0x14;
8135 static void alc885_imac91_setup(struct hda_codec *codec)
8137 struct alc_spec *spec = codec->spec;
8139 spec->autocfg.hp_pins[0] = 0x14;
8140 spec->autocfg.speaker_pins[0] = 0x18;
8141 spec->autocfg.speaker_pins[1] = 0x1a;
8144 static struct hda_verb alc882_targa_verbs[] = {
8145 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8146 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8151 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8152 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8153 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8155 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8156 { } /* end */
8159 /* toggle speaker-output according to the hp-jack state */
8160 static void alc882_targa_automute(struct hda_codec *codec)
8162 struct alc_spec *spec = codec->spec;
8163 alc_automute_amp(codec);
8164 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8165 spec->jack_present ? 1 : 3);
8168 static void alc882_targa_setup(struct hda_codec *codec)
8170 struct alc_spec *spec = codec->spec;
8172 spec->autocfg.hp_pins[0] = 0x14;
8173 spec->autocfg.speaker_pins[0] = 0x1b;
8176 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8178 if ((res >> 26) == ALC880_HP_EVENT)
8179 alc882_targa_automute(codec);
8182 static struct hda_verb alc882_asus_a7j_verbs[] = {
8183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8187 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8188 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8190 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8191 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8192 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8194 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8195 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8196 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8197 { } /* end */
8200 static struct hda_verb alc882_asus_a7m_verbs[] = {
8201 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8202 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8208 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8209 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8210 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8212 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8213 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8214 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8215 { } /* end */
8218 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8220 unsigned int gpiostate, gpiomask, gpiodir;
8222 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8223 AC_VERB_GET_GPIO_DATA, 0);
8225 if (!muted)
8226 gpiostate |= (1 << pin);
8227 else
8228 gpiostate &= ~(1 << pin);
8230 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8231 AC_VERB_GET_GPIO_MASK, 0);
8232 gpiomask |= (1 << pin);
8234 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8235 AC_VERB_GET_GPIO_DIRECTION, 0);
8236 gpiodir |= (1 << pin);
8239 snd_hda_codec_write(codec, codec->afg, 0,
8240 AC_VERB_SET_GPIO_MASK, gpiomask);
8241 snd_hda_codec_write(codec, codec->afg, 0,
8242 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8244 msleep(1);
8246 snd_hda_codec_write(codec, codec->afg, 0,
8247 AC_VERB_SET_GPIO_DATA, gpiostate);
8250 /* set up GPIO at initialization */
8251 static void alc885_macpro_init_hook(struct hda_codec *codec)
8253 alc882_gpio_mute(codec, 0, 0);
8254 alc882_gpio_mute(codec, 1, 0);
8257 /* set up GPIO and update auto-muting at initialization */
8258 static void alc885_imac24_init_hook(struct hda_codec *codec)
8260 alc885_macpro_init_hook(codec);
8261 alc_automute_amp(codec);
8265 * generic initialization of ADC, input mixers and output mixers
8267 static struct hda_verb alc883_auto_init_verbs[] = {
8269 * Unmute ADC0-2 and set the default input to mic-in
8271 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8272 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8273 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8274 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8277 * Set up output mixers (0x0c - 0x0f)
8279 /* set vol=0 to output mixers */
8280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8281 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8282 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8283 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8284 /* set up input amps for analog loopback */
8285 /* Amp Indices: DAC = 0, mixer = 1 */
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8288 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8289 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8290 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8291 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8292 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8293 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8294 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8295 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8297 /* FIXME: use matrix-type input source selection */
8298 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8299 /* Input mixer2 */
8300 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8301 /* Input mixer3 */
8302 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8306 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8307 static struct hda_verb alc889A_mb31_ch2_init[] = {
8308 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8309 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8310 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8311 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8312 { } /* end */
8315 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8316 static struct hda_verb alc889A_mb31_ch4_init[] = {
8317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8318 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8319 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8321 { } /* end */
8324 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8325 static struct hda_verb alc889A_mb31_ch5_init[] = {
8326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8327 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8328 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8329 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8330 { } /* end */
8333 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8334 static struct hda_verb alc889A_mb31_ch6_init[] = {
8335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8336 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8337 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8338 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8339 { } /* end */
8342 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8343 { 2, alc889A_mb31_ch2_init },
8344 { 4, alc889A_mb31_ch4_init },
8345 { 5, alc889A_mb31_ch5_init },
8346 { 6, alc889A_mb31_ch6_init },
8349 static struct hda_verb alc883_medion_eapd_verbs[] = {
8350 /* eanable EAPD on medion laptop */
8351 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8352 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8356 #define alc883_base_mixer alc882_base_mixer
8358 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8359 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8360 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8361 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8362 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8363 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8364 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8367 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8369 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8370 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8372 { } /* end */
8375 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8376 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8377 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8378 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8379 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8381 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8383 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8384 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8385 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8386 { } /* end */
8389 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8390 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8391 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8392 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8393 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8395 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8397 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8398 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8399 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8400 { } /* end */
8403 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8404 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8405 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8407 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8408 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8409 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8410 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8411 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8414 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8415 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8416 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8417 { } /* end */
8420 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8421 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8422 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8423 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8424 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8425 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8426 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8427 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8428 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8430 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8431 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8432 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8433 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8436 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8438 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8439 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8440 { } /* end */
8443 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8444 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8445 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8446 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8447 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8448 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8449 HDA_OUTPUT),
8450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8451 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8452 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8453 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8454 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8455 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8456 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8457 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8459 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8460 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8461 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8462 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8463 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8464 { } /* end */
8467 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8468 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8469 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8470 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8471 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8472 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8473 HDA_OUTPUT),
8474 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8475 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8476 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8477 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8478 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8479 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8480 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8481 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8482 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8483 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8484 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8485 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8486 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8487 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8488 { } /* end */
8491 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8495 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8496 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8497 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8498 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8500 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8501 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8502 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8506 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8508 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8509 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8510 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8511 { } /* end */
8514 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8515 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8516 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8517 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8519 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8520 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8521 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8522 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8523 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8524 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8525 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8526 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8527 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8528 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8530 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8531 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8532 { } /* end */
8535 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8536 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8537 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8539 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8540 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8541 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8543 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8544 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8545 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8546 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8547 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8548 { } /* end */
8551 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8552 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8553 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8554 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8555 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8556 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8557 { } /* end */
8560 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8561 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8562 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8563 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8564 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8565 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8567 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8568 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8569 { } /* end */
8572 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8573 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8574 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8576 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8577 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8580 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8581 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8582 { } /* end */
8585 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8586 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8587 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8588 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8589 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8590 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8592 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8595 { } /* end */
8598 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8599 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8600 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8601 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8602 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8603 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8604 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8605 { } /* end */
8608 static struct hda_verb alc883_medion_wim2160_verbs[] = {
8609 /* Unmute front mixer */
8610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8613 /* Set speaker pin to front mixer */
8614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8616 /* Init headphone pin */
8617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8619 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8620 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8622 { } /* end */
8625 /* toggle speaker-output according to the hp-jack state */
8626 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8628 struct alc_spec *spec = codec->spec;
8630 spec->autocfg.hp_pins[0] = 0x1a;
8631 spec->autocfg.speaker_pins[0] = 0x15;
8634 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8635 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8636 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8638 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8639 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8640 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8641 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8643 { } /* end */
8646 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8648 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8649 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8650 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8654 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8655 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8656 { } /* end */
8659 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8660 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8661 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8662 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8663 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8664 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8665 0x0d, 1, 0x0, HDA_OUTPUT),
8666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8667 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8668 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8669 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8670 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8679 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8680 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8681 { } /* end */
8684 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8685 /* Output mixers */
8686 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8687 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8688 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8689 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8690 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8691 HDA_OUTPUT),
8692 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8693 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8694 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8695 /* Output switches */
8696 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8697 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8698 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8699 /* Boost mixers */
8700 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8701 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8702 /* Input mixers */
8703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8707 { } /* end */
8710 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8711 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8712 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8715 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8717 { } /* end */
8720 static struct hda_bind_ctls alc883_bind_cap_vol = {
8721 .ops = &snd_hda_bind_vol,
8722 .values = {
8723 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8724 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8729 static struct hda_bind_ctls alc883_bind_cap_switch = {
8730 .ops = &snd_hda_bind_sw,
8731 .values = {
8732 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8733 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8738 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8739 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8740 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8741 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8742 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8743 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8745 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8747 { } /* end */
8750 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8751 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8752 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8755 /* .name = "Capture Source", */
8756 .name = "Input Source",
8757 .count = 1,
8758 .info = alc_mux_enum_info,
8759 .get = alc_mux_enum_get,
8760 .put = alc_mux_enum_put,
8762 { } /* end */
8765 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8768 .name = "Channel Mode",
8769 .info = alc_ch_mode_info,
8770 .get = alc_ch_mode_get,
8771 .put = alc_ch_mode_put,
8773 { } /* end */
8776 /* toggle speaker-output according to the hp-jack state */
8777 static void alc883_mitac_setup(struct hda_codec *codec)
8779 struct alc_spec *spec = codec->spec;
8781 spec->autocfg.hp_pins[0] = 0x15;
8782 spec->autocfg.speaker_pins[0] = 0x14;
8783 spec->autocfg.speaker_pins[1] = 0x17;
8786 /* auto-toggle front mic */
8788 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8790 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8792 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8796 static struct hda_verb alc883_mitac_verbs[] = {
8797 /* HP */
8798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8800 /* Subwoofer */
8801 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8802 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8804 /* enable unsolicited event */
8805 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8806 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8808 { } /* end */
8811 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8812 /* HP */
8813 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8814 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8815 /* Int speaker */
8816 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8818 /* enable unsolicited event */
8820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8824 { } /* end */
8827 static struct hda_verb alc883_clevo_m720_verbs[] = {
8828 /* HP */
8829 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8831 /* Int speaker */
8832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8833 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8835 /* enable unsolicited event */
8836 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8839 { } /* end */
8842 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8843 /* HP */
8844 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8846 /* Subwoofer */
8847 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8848 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8850 /* enable unsolicited event */
8851 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8853 { } /* end */
8856 static struct hda_verb alc883_targa_verbs[] = {
8857 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8858 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8861 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8863 /* Connect Line-Out side jack (SPDIF) to Side */
8864 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8865 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8866 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8867 /* Connect Mic jack to CLFE */
8868 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8869 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8870 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8871 /* Connect Line-in jack to Surround */
8872 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8873 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8874 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8875 /* Connect HP out jack to Front */
8876 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8877 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8878 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8880 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8882 { } /* end */
8885 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8886 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8887 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8888 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8889 { } /* end */
8892 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8894 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8895 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8897 { } /* end */
8900 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8901 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8903 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8904 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8905 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8906 { } /* end */
8909 static struct hda_verb alc883_haier_w66_verbs[] = {
8910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8913 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8915 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8917 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8919 { } /* end */
8922 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8923 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8924 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8925 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8926 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8927 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8929 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8931 { } /* end */
8934 static struct hda_verb alc888_6st_dell_verbs[] = {
8935 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8939 static struct hda_verb alc883_vaiott_verbs[] = {
8940 /* HP */
8941 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8944 /* enable unsolicited event */
8945 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947 { } /* end */
8950 static void alc888_3st_hp_setup(struct hda_codec *codec)
8952 struct alc_spec *spec = codec->spec;
8954 spec->autocfg.hp_pins[0] = 0x1b;
8955 spec->autocfg.speaker_pins[0] = 0x14;
8956 spec->autocfg.speaker_pins[1] = 0x16;
8957 spec->autocfg.speaker_pins[2] = 0x18;
8960 static struct hda_verb alc888_3st_hp_verbs[] = {
8961 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8962 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8963 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8965 { } /* end */
8969 * 2ch mode
8971 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8972 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8973 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8974 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8975 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8976 { } /* end */
8980 * 4ch mode
8982 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8983 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8984 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8985 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8986 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8987 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8988 { } /* end */
8992 * 6ch mode
8994 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8995 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8996 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8997 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8998 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8999 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9000 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9001 { } /* end */
9004 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9005 { 2, alc888_3st_hp_2ch_init },
9006 { 4, alc888_3st_hp_4ch_init },
9007 { 6, alc888_3st_hp_6ch_init },
9010 /* toggle front-jack and RCA according to the hp-jack state */
9011 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9013 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9015 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9016 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9017 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9018 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9021 /* toggle RCA according to the front-jack state */
9022 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9024 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9026 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9027 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9030 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9031 unsigned int res)
9033 if ((res >> 26) == ALC880_HP_EVENT)
9034 alc888_lenovo_ms7195_front_automute(codec);
9035 if ((res >> 26) == ALC880_FRONT_EVENT)
9036 alc888_lenovo_ms7195_rca_automute(codec);
9039 static struct hda_verb alc883_medion_md2_verbs[] = {
9040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9041 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9043 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9046 { } /* end */
9049 /* toggle speaker-output according to the hp-jack state */
9050 static void alc883_medion_md2_setup(struct hda_codec *codec)
9052 struct alc_spec *spec = codec->spec;
9054 spec->autocfg.hp_pins[0] = 0x14;
9055 spec->autocfg.speaker_pins[0] = 0x15;
9058 /* toggle speaker-output according to the hp-jack state */
9059 #define alc883_targa_init_hook alc882_targa_init_hook
9060 #define alc883_targa_unsol_event alc882_targa_unsol_event
9062 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9064 unsigned int present;
9066 present = snd_hda_jack_detect(codec, 0x18);
9067 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9068 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9071 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9073 struct alc_spec *spec = codec->spec;
9075 spec->autocfg.hp_pins[0] = 0x15;
9076 spec->autocfg.speaker_pins[0] = 0x14;
9079 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9081 alc_automute_amp(codec);
9082 alc883_clevo_m720_mic_automute(codec);
9085 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9086 unsigned int res)
9088 switch (res >> 26) {
9089 case ALC880_MIC_EVENT:
9090 alc883_clevo_m720_mic_automute(codec);
9091 break;
9092 default:
9093 alc_automute_amp_unsol_event(codec, res);
9094 break;
9098 /* toggle speaker-output according to the hp-jack state */
9099 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9101 struct alc_spec *spec = codec->spec;
9103 spec->autocfg.hp_pins[0] = 0x14;
9104 spec->autocfg.speaker_pins[0] = 0x15;
9107 static void alc883_haier_w66_setup(struct hda_codec *codec)
9109 struct alc_spec *spec = codec->spec;
9111 spec->autocfg.hp_pins[0] = 0x1b;
9112 spec->autocfg.speaker_pins[0] = 0x14;
9115 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9117 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9119 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9120 HDA_AMP_MUTE, bits);
9123 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9125 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9127 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9128 HDA_AMP_MUTE, bits);
9129 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9130 HDA_AMP_MUTE, bits);
9133 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9134 unsigned int res)
9136 if ((res >> 26) == ALC880_HP_EVENT)
9137 alc883_lenovo_101e_all_automute(codec);
9138 if ((res >> 26) == ALC880_FRONT_EVENT)
9139 alc883_lenovo_101e_ispeaker_automute(codec);
9142 /* toggle speaker-output according to the hp-jack state */
9143 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9145 struct alc_spec *spec = codec->spec;
9147 spec->autocfg.hp_pins[0] = 0x14;
9148 spec->autocfg.speaker_pins[0] = 0x15;
9149 spec->autocfg.speaker_pins[1] = 0x16;
9152 static struct hda_verb alc883_acer_eapd_verbs[] = {
9153 /* HP Pin: output 0 (0x0c) */
9154 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9155 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9157 /* Front Pin: output 0 (0x0c) */
9158 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9159 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9160 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9161 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9162 /* eanable EAPD on medion laptop */
9163 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9164 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9165 /* enable unsolicited event */
9166 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9170 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9171 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9172 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9173 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9174 { } /* end */
9177 static void alc888_6st_dell_setup(struct hda_codec *codec)
9179 struct alc_spec *spec = codec->spec;
9181 spec->autocfg.hp_pins[0] = 0x1b;
9182 spec->autocfg.speaker_pins[0] = 0x14;
9183 spec->autocfg.speaker_pins[1] = 0x15;
9184 spec->autocfg.speaker_pins[2] = 0x16;
9185 spec->autocfg.speaker_pins[3] = 0x17;
9188 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9190 struct alc_spec *spec = codec->spec;
9192 spec->autocfg.hp_pins[0] = 0x1b;
9193 spec->autocfg.speaker_pins[0] = 0x14;
9194 spec->autocfg.speaker_pins[1] = 0x15;
9195 spec->autocfg.speaker_pins[2] = 0x16;
9196 spec->autocfg.speaker_pins[3] = 0x17;
9197 spec->autocfg.speaker_pins[4] = 0x1a;
9200 static void alc883_vaiott_setup(struct hda_codec *codec)
9202 struct alc_spec *spec = codec->spec;
9204 spec->autocfg.hp_pins[0] = 0x15;
9205 spec->autocfg.speaker_pins[0] = 0x14;
9206 spec->autocfg.speaker_pins[1] = 0x17;
9209 static struct hda_verb alc888_asus_m90v_verbs[] = {
9210 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9211 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9212 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9213 /* enable unsolicited event */
9214 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9215 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9216 { } /* end */
9219 static void alc883_mode2_setup(struct hda_codec *codec)
9221 struct alc_spec *spec = codec->spec;
9223 spec->autocfg.hp_pins[0] = 0x1b;
9224 spec->autocfg.speaker_pins[0] = 0x14;
9225 spec->autocfg.speaker_pins[1] = 0x15;
9226 spec->autocfg.speaker_pins[2] = 0x16;
9227 spec->ext_mic.pin = 0x18;
9228 spec->int_mic.pin = 0x19;
9229 spec->ext_mic.mux_idx = 0;
9230 spec->int_mic.mux_idx = 1;
9231 spec->auto_mic = 1;
9234 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9236 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9238 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9239 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9240 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9241 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9242 /* enable unsolicited event */
9243 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9244 { } /* end */
9247 static void alc883_eee1601_inithook(struct hda_codec *codec)
9249 struct alc_spec *spec = codec->spec;
9251 spec->autocfg.hp_pins[0] = 0x14;
9252 spec->autocfg.speaker_pins[0] = 0x1b;
9253 alc_automute_pin(codec);
9256 static struct hda_verb alc889A_mb31_verbs[] = {
9257 /* Init rear pin (used as headphone output) */
9258 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9260 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9261 /* Init line pin (used as output in 4ch and 6ch mode) */
9262 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9263 /* Init line 2 pin (used as headphone out by default) */
9264 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9265 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9266 { } /* end */
9269 /* Mute speakers according to the headphone jack state */
9270 static void alc889A_mb31_automute(struct hda_codec *codec)
9272 unsigned int present;
9274 /* Mute only in 2ch or 4ch mode */
9275 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9276 == 0x00) {
9277 present = snd_hda_jack_detect(codec, 0x15);
9278 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9279 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9280 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9281 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9285 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9287 if ((res >> 26) == ALC880_HP_EVENT)
9288 alc889A_mb31_automute(codec);
9292 #ifdef CONFIG_SND_HDA_POWER_SAVE
9293 #define alc882_loopbacks alc880_loopbacks
9294 #endif
9296 /* pcm configuration: identical with ALC880 */
9297 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9298 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9299 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9300 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9302 static hda_nid_t alc883_slave_dig_outs[] = {
9303 ALC1200_DIGOUT_NID, 0,
9306 static hda_nid_t alc1200_slave_dig_outs[] = {
9307 ALC883_DIGOUT_NID, 0,
9311 * configuration and preset
9313 static const char *alc882_models[ALC882_MODEL_LAST] = {
9314 [ALC882_3ST_DIG] = "3stack-dig",
9315 [ALC882_6ST_DIG] = "6stack-dig",
9316 [ALC882_ARIMA] = "arima",
9317 [ALC882_W2JC] = "w2jc",
9318 [ALC882_TARGA] = "targa",
9319 [ALC882_ASUS_A7J] = "asus-a7j",
9320 [ALC882_ASUS_A7M] = "asus-a7m",
9321 [ALC885_MACPRO] = "macpro",
9322 [ALC885_MB5] = "mb5",
9323 [ALC885_MACMINI3] = "macmini3",
9324 [ALC885_MBA21] = "mba21",
9325 [ALC885_MBP3] = "mbp3",
9326 [ALC885_IMAC24] = "imac24",
9327 [ALC885_IMAC91] = "imac91",
9328 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9329 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9330 [ALC883_3ST_6ch] = "3stack-6ch",
9331 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9332 [ALC883_TARGA_DIG] = "targa-dig",
9333 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9334 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9335 [ALC883_ACER] = "acer",
9336 [ALC883_ACER_ASPIRE] = "acer-aspire",
9337 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9338 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9339 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9340 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9341 [ALC883_MEDION] = "medion",
9342 [ALC883_MEDION_MD2] = "medion-md2",
9343 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9344 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9345 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9346 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9347 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9348 [ALC888_LENOVO_SKY] = "lenovo-sky",
9349 [ALC883_HAIER_W66] = "haier-w66",
9350 [ALC888_3ST_HP] = "3stack-hp",
9351 [ALC888_6ST_DELL] = "6stack-dell",
9352 [ALC883_MITAC] = "mitac",
9353 [ALC883_CLEVO_M540R] = "clevo-m540r",
9354 [ALC883_CLEVO_M720] = "clevo-m720",
9355 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9356 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9357 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9358 [ALC889A_INTEL] = "intel-alc889a",
9359 [ALC889_INTEL] = "intel-x58",
9360 [ALC1200_ASUS_P5Q] = "asus-p5q",
9361 [ALC889A_MB31] = "mb31",
9362 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9363 [ALC882_AUTO] = "auto",
9366 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9367 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9369 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9370 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9371 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9372 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9373 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9374 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9375 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9376 ALC888_ACER_ASPIRE_4930G),
9377 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9378 ALC888_ACER_ASPIRE_4930G),
9379 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9380 ALC888_ACER_ASPIRE_8930G),
9381 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9382 ALC888_ACER_ASPIRE_8930G),
9383 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9384 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9385 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9386 ALC888_ACER_ASPIRE_6530G),
9387 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9388 ALC888_ACER_ASPIRE_6530G),
9389 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9390 ALC888_ACER_ASPIRE_7730G),
9391 /* default Acer -- disabled as it causes more problems.
9392 * model=auto should work fine now
9394 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9396 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9398 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9399 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9400 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9401 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9402 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9403 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9405 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9406 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9407 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9408 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9409 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9410 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9411 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9412 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9413 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9414 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9415 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9417 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9418 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9419 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9420 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9421 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9422 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9423 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9424 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9425 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9427 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9428 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9429 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9430 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9431 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9432 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9433 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9434 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9435 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9436 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9437 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9438 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9439 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9440 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9441 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9442 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9443 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9444 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9445 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9446 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9447 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9448 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9449 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9450 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9451 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9452 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9453 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9454 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9455 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9456 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9457 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9459 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9460 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9461 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9462 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9463 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9464 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9465 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9466 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9467 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9468 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9469 ALC883_FUJITSU_PI2515),
9470 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9471 ALC888_FUJITSU_XA3530),
9472 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9473 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9474 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9475 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9476 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9477 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9478 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9479 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9481 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9482 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9483 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9484 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9485 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9486 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9487 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9492 /* codec SSID table for Intel Mac */
9493 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9494 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9495 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9496 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9497 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9498 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9499 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9500 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9501 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9502 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9503 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9504 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9505 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9506 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9507 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9508 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9509 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9510 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9511 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9512 * so apparently no perfect solution yet
9514 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9515 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9516 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9517 {} /* terminator */
9520 static struct alc_config_preset alc882_presets[] = {
9521 [ALC882_3ST_DIG] = {
9522 .mixers = { alc882_base_mixer },
9523 .init_verbs = { alc882_base_init_verbs,
9524 alc882_adc1_init_verbs },
9525 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9526 .dac_nids = alc882_dac_nids,
9527 .dig_out_nid = ALC882_DIGOUT_NID,
9528 .dig_in_nid = ALC882_DIGIN_NID,
9529 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9530 .channel_mode = alc882_ch_modes,
9531 .need_dac_fix = 1,
9532 .input_mux = &alc882_capture_source,
9534 [ALC882_6ST_DIG] = {
9535 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9536 .init_verbs = { alc882_base_init_verbs,
9537 alc882_adc1_init_verbs },
9538 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9539 .dac_nids = alc882_dac_nids,
9540 .dig_out_nid = ALC882_DIGOUT_NID,
9541 .dig_in_nid = ALC882_DIGIN_NID,
9542 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9543 .channel_mode = alc882_sixstack_modes,
9544 .input_mux = &alc882_capture_source,
9546 [ALC882_ARIMA] = {
9547 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9548 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9549 alc882_eapd_verbs },
9550 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9551 .dac_nids = alc882_dac_nids,
9552 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9553 .channel_mode = alc882_sixstack_modes,
9554 .input_mux = &alc882_capture_source,
9556 [ALC882_W2JC] = {
9557 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
9558 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9559 alc882_eapd_verbs, alc880_gpio1_init_verbs },
9560 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9561 .dac_nids = alc882_dac_nids,
9562 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9563 .channel_mode = alc880_threestack_modes,
9564 .need_dac_fix = 1,
9565 .input_mux = &alc882_capture_source,
9566 .dig_out_nid = ALC882_DIGOUT_NID,
9568 [ALC885_MBA21] = {
9569 .mixers = { alc885_mba21_mixer },
9570 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9571 .num_dacs = 2,
9572 .dac_nids = alc882_dac_nids,
9573 .channel_mode = alc885_mba21_ch_modes,
9574 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9575 .input_mux = &alc882_capture_source,
9576 .unsol_event = alc_automute_amp_unsol_event,
9577 .setup = alc885_mba21_setup,
9578 .init_hook = alc_automute_amp,
9580 [ALC885_MBP3] = {
9581 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9582 .init_verbs = { alc885_mbp3_init_verbs,
9583 alc880_gpio1_init_verbs },
9584 .num_dacs = 2,
9585 .dac_nids = alc882_dac_nids,
9586 .hp_nid = 0x04,
9587 .channel_mode = alc885_mbp_4ch_modes,
9588 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9589 .input_mux = &alc882_capture_source,
9590 .dig_out_nid = ALC882_DIGOUT_NID,
9591 .dig_in_nid = ALC882_DIGIN_NID,
9592 .unsol_event = alc_automute_amp_unsol_event,
9593 .setup = alc885_mbp3_setup,
9594 .init_hook = alc_automute_amp,
9596 [ALC885_MB5] = {
9597 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9598 .init_verbs = { alc885_mb5_init_verbs,
9599 alc880_gpio1_init_verbs },
9600 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9601 .dac_nids = alc882_dac_nids,
9602 .channel_mode = alc885_mb5_6ch_modes,
9603 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9604 .input_mux = &mb5_capture_source,
9605 .dig_out_nid = ALC882_DIGOUT_NID,
9606 .dig_in_nid = ALC882_DIGIN_NID,
9607 .unsol_event = alc_automute_amp_unsol_event,
9608 .setup = alc885_mb5_setup,
9609 .init_hook = alc_automute_amp,
9611 [ALC885_MACMINI3] = {
9612 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9613 .init_verbs = { alc885_macmini3_init_verbs,
9614 alc880_gpio1_init_verbs },
9615 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9616 .dac_nids = alc882_dac_nids,
9617 .channel_mode = alc885_macmini3_6ch_modes,
9618 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9619 .input_mux = &macmini3_capture_source,
9620 .dig_out_nid = ALC882_DIGOUT_NID,
9621 .dig_in_nid = ALC882_DIGIN_NID,
9622 .unsol_event = alc_automute_amp_unsol_event,
9623 .setup = alc885_macmini3_setup,
9624 .init_hook = alc_automute_amp,
9626 [ALC885_MACPRO] = {
9627 .mixers = { alc882_macpro_mixer },
9628 .init_verbs = { alc882_macpro_init_verbs },
9629 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9630 .dac_nids = alc882_dac_nids,
9631 .dig_out_nid = ALC882_DIGOUT_NID,
9632 .dig_in_nid = ALC882_DIGIN_NID,
9633 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9634 .channel_mode = alc882_ch_modes,
9635 .input_mux = &alc882_capture_source,
9636 .init_hook = alc885_macpro_init_hook,
9638 [ALC885_IMAC24] = {
9639 .mixers = { alc885_imac24_mixer },
9640 .init_verbs = { alc885_imac24_init_verbs },
9641 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9642 .dac_nids = alc882_dac_nids,
9643 .dig_out_nid = ALC882_DIGOUT_NID,
9644 .dig_in_nid = ALC882_DIGIN_NID,
9645 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9646 .channel_mode = alc882_ch_modes,
9647 .input_mux = &alc882_capture_source,
9648 .unsol_event = alc_automute_amp_unsol_event,
9649 .setup = alc885_imac24_setup,
9650 .init_hook = alc885_imac24_init_hook,
9652 [ALC885_IMAC91] = {
9653 .mixers = {alc885_imac91_mixer},
9654 .init_verbs = { alc885_imac91_init_verbs,
9655 alc880_gpio1_init_verbs },
9656 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9657 .dac_nids = alc882_dac_nids,
9658 .channel_mode = alc885_mba21_ch_modes,
9659 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9660 .input_mux = &alc889A_imac91_capture_source,
9661 .dig_out_nid = ALC882_DIGOUT_NID,
9662 .dig_in_nid = ALC882_DIGIN_NID,
9663 .unsol_event = alc_automute_amp_unsol_event,
9664 .setup = alc885_imac91_setup,
9665 .init_hook = alc_automute_amp,
9667 [ALC882_TARGA] = {
9668 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9669 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9670 alc880_gpio3_init_verbs, alc882_targa_verbs},
9671 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9672 .dac_nids = alc882_dac_nids,
9673 .dig_out_nid = ALC882_DIGOUT_NID,
9674 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9675 .adc_nids = alc882_adc_nids,
9676 .capsrc_nids = alc882_capsrc_nids,
9677 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9678 .channel_mode = alc882_3ST_6ch_modes,
9679 .need_dac_fix = 1,
9680 .input_mux = &alc882_capture_source,
9681 .unsol_event = alc882_targa_unsol_event,
9682 .setup = alc882_targa_setup,
9683 .init_hook = alc882_targa_automute,
9685 [ALC882_ASUS_A7J] = {
9686 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9687 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9688 alc882_asus_a7j_verbs},
9689 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9690 .dac_nids = alc882_dac_nids,
9691 .dig_out_nid = ALC882_DIGOUT_NID,
9692 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9693 .adc_nids = alc882_adc_nids,
9694 .capsrc_nids = alc882_capsrc_nids,
9695 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9696 .channel_mode = alc882_3ST_6ch_modes,
9697 .need_dac_fix = 1,
9698 .input_mux = &alc882_capture_source,
9700 [ALC882_ASUS_A7M] = {
9701 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9702 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9703 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9704 alc882_asus_a7m_verbs },
9705 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9706 .dac_nids = alc882_dac_nids,
9707 .dig_out_nid = ALC882_DIGOUT_NID,
9708 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9709 .channel_mode = alc880_threestack_modes,
9710 .need_dac_fix = 1,
9711 .input_mux = &alc882_capture_source,
9713 [ALC883_3ST_2ch_DIG] = {
9714 .mixers = { alc883_3ST_2ch_mixer },
9715 .init_verbs = { alc883_init_verbs },
9716 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9717 .dac_nids = alc883_dac_nids,
9718 .dig_out_nid = ALC883_DIGOUT_NID,
9719 .dig_in_nid = ALC883_DIGIN_NID,
9720 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9721 .channel_mode = alc883_3ST_2ch_modes,
9722 .input_mux = &alc883_capture_source,
9724 [ALC883_3ST_6ch_DIG] = {
9725 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9726 .init_verbs = { alc883_init_verbs },
9727 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9728 .dac_nids = alc883_dac_nids,
9729 .dig_out_nid = ALC883_DIGOUT_NID,
9730 .dig_in_nid = ALC883_DIGIN_NID,
9731 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9732 .channel_mode = alc883_3ST_6ch_modes,
9733 .need_dac_fix = 1,
9734 .input_mux = &alc883_capture_source,
9736 [ALC883_3ST_6ch] = {
9737 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9738 .init_verbs = { alc883_init_verbs },
9739 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9740 .dac_nids = alc883_dac_nids,
9741 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9742 .channel_mode = alc883_3ST_6ch_modes,
9743 .need_dac_fix = 1,
9744 .input_mux = &alc883_capture_source,
9746 [ALC883_3ST_6ch_INTEL] = {
9747 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9748 .init_verbs = { alc883_init_verbs },
9749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9750 .dac_nids = alc883_dac_nids,
9751 .dig_out_nid = ALC883_DIGOUT_NID,
9752 .dig_in_nid = ALC883_DIGIN_NID,
9753 .slave_dig_outs = alc883_slave_dig_outs,
9754 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9755 .channel_mode = alc883_3ST_6ch_intel_modes,
9756 .need_dac_fix = 1,
9757 .input_mux = &alc883_3stack_6ch_intel,
9759 [ALC889A_INTEL] = {
9760 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9761 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9762 alc_hp15_unsol_verbs },
9763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9764 .dac_nids = alc883_dac_nids,
9765 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9766 .adc_nids = alc889_adc_nids,
9767 .dig_out_nid = ALC883_DIGOUT_NID,
9768 .dig_in_nid = ALC883_DIGIN_NID,
9769 .slave_dig_outs = alc883_slave_dig_outs,
9770 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9771 .channel_mode = alc889_8ch_intel_modes,
9772 .capsrc_nids = alc889_capsrc_nids,
9773 .input_mux = &alc889_capture_source,
9774 .setup = alc889_automute_setup,
9775 .init_hook = alc_automute_amp,
9776 .unsol_event = alc_automute_amp_unsol_event,
9777 .need_dac_fix = 1,
9779 [ALC889_INTEL] = {
9780 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9781 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9782 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9783 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9784 .dac_nids = alc883_dac_nids,
9785 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9786 .adc_nids = alc889_adc_nids,
9787 .dig_out_nid = ALC883_DIGOUT_NID,
9788 .dig_in_nid = ALC883_DIGIN_NID,
9789 .slave_dig_outs = alc883_slave_dig_outs,
9790 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9791 .channel_mode = alc889_8ch_intel_modes,
9792 .capsrc_nids = alc889_capsrc_nids,
9793 .input_mux = &alc889_capture_source,
9794 .setup = alc889_automute_setup,
9795 .init_hook = alc889_intel_init_hook,
9796 .unsol_event = alc_automute_amp_unsol_event,
9797 .need_dac_fix = 1,
9799 [ALC883_6ST_DIG] = {
9800 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9801 .init_verbs = { alc883_init_verbs },
9802 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9803 .dac_nids = alc883_dac_nids,
9804 .dig_out_nid = ALC883_DIGOUT_NID,
9805 .dig_in_nid = ALC883_DIGIN_NID,
9806 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9807 .channel_mode = alc883_sixstack_modes,
9808 .input_mux = &alc883_capture_source,
9810 [ALC883_TARGA_DIG] = {
9811 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9812 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9813 alc883_targa_verbs},
9814 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9815 .dac_nids = alc883_dac_nids,
9816 .dig_out_nid = ALC883_DIGOUT_NID,
9817 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9818 .channel_mode = alc883_3ST_6ch_modes,
9819 .need_dac_fix = 1,
9820 .input_mux = &alc883_capture_source,
9821 .unsol_event = alc883_targa_unsol_event,
9822 .setup = alc882_targa_setup,
9823 .init_hook = alc882_targa_automute,
9825 [ALC883_TARGA_2ch_DIG] = {
9826 .mixers = { alc883_targa_2ch_mixer},
9827 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9828 alc883_targa_verbs},
9829 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9830 .dac_nids = alc883_dac_nids,
9831 .adc_nids = alc883_adc_nids_alt,
9832 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9833 .capsrc_nids = alc883_capsrc_nids,
9834 .dig_out_nid = ALC883_DIGOUT_NID,
9835 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9836 .channel_mode = alc883_3ST_2ch_modes,
9837 .input_mux = &alc883_capture_source,
9838 .unsol_event = alc883_targa_unsol_event,
9839 .setup = alc882_targa_setup,
9840 .init_hook = alc882_targa_automute,
9842 [ALC883_TARGA_8ch_DIG] = {
9843 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9844 alc883_chmode_mixer },
9845 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9846 alc883_targa_verbs },
9847 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9848 .dac_nids = alc883_dac_nids,
9849 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9850 .adc_nids = alc883_adc_nids_rev,
9851 .capsrc_nids = alc883_capsrc_nids_rev,
9852 .dig_out_nid = ALC883_DIGOUT_NID,
9853 .dig_in_nid = ALC883_DIGIN_NID,
9854 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9855 .channel_mode = alc883_4ST_8ch_modes,
9856 .need_dac_fix = 1,
9857 .input_mux = &alc883_capture_source,
9858 .unsol_event = alc883_targa_unsol_event,
9859 .setup = alc882_targa_setup,
9860 .init_hook = alc882_targa_automute,
9862 [ALC883_ACER] = {
9863 .mixers = { alc883_base_mixer },
9864 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9865 * and the headphone jack. Turn this on and rely on the
9866 * standard mute methods whenever the user wants to turn
9867 * these outputs off.
9869 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9870 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9871 .dac_nids = alc883_dac_nids,
9872 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9873 .channel_mode = alc883_3ST_2ch_modes,
9874 .input_mux = &alc883_capture_source,
9876 [ALC883_ACER_ASPIRE] = {
9877 .mixers = { alc883_acer_aspire_mixer },
9878 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9879 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9880 .dac_nids = alc883_dac_nids,
9881 .dig_out_nid = ALC883_DIGOUT_NID,
9882 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9883 .channel_mode = alc883_3ST_2ch_modes,
9884 .input_mux = &alc883_capture_source,
9885 .unsol_event = alc_automute_amp_unsol_event,
9886 .setup = alc883_acer_aspire_setup,
9887 .init_hook = alc_automute_amp,
9889 [ALC888_ACER_ASPIRE_4930G] = {
9890 .mixers = { alc888_base_mixer,
9891 alc883_chmode_mixer },
9892 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9893 alc888_acer_aspire_4930g_verbs },
9894 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9895 .dac_nids = alc883_dac_nids,
9896 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9897 .adc_nids = alc883_adc_nids_rev,
9898 .capsrc_nids = alc883_capsrc_nids_rev,
9899 .dig_out_nid = ALC883_DIGOUT_NID,
9900 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9901 .channel_mode = alc883_3ST_6ch_modes,
9902 .need_dac_fix = 1,
9903 .const_channel_count = 6,
9904 .num_mux_defs =
9905 ARRAY_SIZE(alc888_2_capture_sources),
9906 .input_mux = alc888_2_capture_sources,
9907 .unsol_event = alc_automute_amp_unsol_event,
9908 .setup = alc888_acer_aspire_4930g_setup,
9909 .init_hook = alc_automute_amp,
9911 [ALC888_ACER_ASPIRE_6530G] = {
9912 .mixers = { alc888_acer_aspire_6530_mixer },
9913 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9914 alc888_acer_aspire_6530g_verbs },
9915 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9916 .dac_nids = alc883_dac_nids,
9917 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9918 .adc_nids = alc883_adc_nids_rev,
9919 .capsrc_nids = alc883_capsrc_nids_rev,
9920 .dig_out_nid = ALC883_DIGOUT_NID,
9921 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9922 .channel_mode = alc883_3ST_2ch_modes,
9923 .num_mux_defs =
9924 ARRAY_SIZE(alc888_2_capture_sources),
9925 .input_mux = alc888_acer_aspire_6530_sources,
9926 .unsol_event = alc_automute_amp_unsol_event,
9927 .setup = alc888_acer_aspire_6530g_setup,
9928 .init_hook = alc_automute_amp,
9930 [ALC888_ACER_ASPIRE_8930G] = {
9931 .mixers = { alc889_acer_aspire_8930g_mixer,
9932 alc883_chmode_mixer },
9933 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9934 alc889_acer_aspire_8930g_verbs,
9935 alc889_eapd_verbs},
9936 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9937 .dac_nids = alc883_dac_nids,
9938 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9939 .adc_nids = alc889_adc_nids,
9940 .capsrc_nids = alc889_capsrc_nids,
9941 .dig_out_nid = ALC883_DIGOUT_NID,
9942 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9943 .channel_mode = alc883_3ST_6ch_modes,
9944 .need_dac_fix = 1,
9945 .const_channel_count = 6,
9946 .num_mux_defs =
9947 ARRAY_SIZE(alc889_capture_sources),
9948 .input_mux = alc889_capture_sources,
9949 .unsol_event = alc_automute_amp_unsol_event,
9950 .setup = alc889_acer_aspire_8930g_setup,
9951 .init_hook = alc_automute_amp,
9952 #ifdef CONFIG_SND_HDA_POWER_SAVE
9953 .power_hook = alc_power_eapd,
9954 #endif
9956 [ALC888_ACER_ASPIRE_7730G] = {
9957 .mixers = { alc883_3ST_6ch_mixer,
9958 alc883_chmode_mixer },
9959 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9960 alc888_acer_aspire_7730G_verbs },
9961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9962 .dac_nids = alc883_dac_nids,
9963 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9964 .adc_nids = alc883_adc_nids_rev,
9965 .capsrc_nids = alc883_capsrc_nids_rev,
9966 .dig_out_nid = ALC883_DIGOUT_NID,
9967 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9968 .channel_mode = alc883_3ST_6ch_modes,
9969 .need_dac_fix = 1,
9970 .const_channel_count = 6,
9971 .input_mux = &alc883_capture_source,
9972 .unsol_event = alc_automute_amp_unsol_event,
9973 .setup = alc888_acer_aspire_6530g_setup,
9974 .init_hook = alc_automute_amp,
9976 [ALC883_MEDION] = {
9977 .mixers = { alc883_fivestack_mixer,
9978 alc883_chmode_mixer },
9979 .init_verbs = { alc883_init_verbs,
9980 alc883_medion_eapd_verbs },
9981 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9982 .dac_nids = alc883_dac_nids,
9983 .adc_nids = alc883_adc_nids_alt,
9984 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9985 .capsrc_nids = alc883_capsrc_nids,
9986 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9987 .channel_mode = alc883_sixstack_modes,
9988 .input_mux = &alc883_capture_source,
9990 [ALC883_MEDION_MD2] = {
9991 .mixers = { alc883_medion_md2_mixer},
9992 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9993 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9994 .dac_nids = alc883_dac_nids,
9995 .dig_out_nid = ALC883_DIGOUT_NID,
9996 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9997 .channel_mode = alc883_3ST_2ch_modes,
9998 .input_mux = &alc883_capture_source,
9999 .unsol_event = alc_automute_amp_unsol_event,
10000 .setup = alc883_medion_md2_setup,
10001 .init_hook = alc_automute_amp,
10003 [ALC883_MEDION_WIM2160] = {
10004 .mixers = { alc883_medion_wim2160_mixer },
10005 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10006 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10007 .dac_nids = alc883_dac_nids,
10008 .dig_out_nid = ALC883_DIGOUT_NID,
10009 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10010 .adc_nids = alc883_adc_nids,
10011 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10012 .channel_mode = alc883_3ST_2ch_modes,
10013 .input_mux = &alc883_capture_source,
10014 .unsol_event = alc_automute_amp_unsol_event,
10015 .setup = alc883_medion_wim2160_setup,
10016 .init_hook = alc_automute_amp,
10018 [ALC883_LAPTOP_EAPD] = {
10019 .mixers = { alc883_base_mixer },
10020 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10022 .dac_nids = alc883_dac_nids,
10023 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10024 .channel_mode = alc883_3ST_2ch_modes,
10025 .input_mux = &alc883_capture_source,
10027 [ALC883_CLEVO_M540R] = {
10028 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10029 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10030 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10031 .dac_nids = alc883_dac_nids,
10032 .dig_out_nid = ALC883_DIGOUT_NID,
10033 .dig_in_nid = ALC883_DIGIN_NID,
10034 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10035 .channel_mode = alc883_3ST_6ch_clevo_modes,
10036 .need_dac_fix = 1,
10037 .input_mux = &alc883_capture_source,
10038 /* This machine has the hardware HP auto-muting, thus
10039 * we need no software mute via unsol event
10042 [ALC883_CLEVO_M720] = {
10043 .mixers = { alc883_clevo_m720_mixer },
10044 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10045 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10046 .dac_nids = alc883_dac_nids,
10047 .dig_out_nid = ALC883_DIGOUT_NID,
10048 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10049 .channel_mode = alc883_3ST_2ch_modes,
10050 .input_mux = &alc883_capture_source,
10051 .unsol_event = alc883_clevo_m720_unsol_event,
10052 .setup = alc883_clevo_m720_setup,
10053 .init_hook = alc883_clevo_m720_init_hook,
10055 [ALC883_LENOVO_101E_2ch] = {
10056 .mixers = { alc883_lenovo_101e_2ch_mixer},
10057 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10058 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10059 .dac_nids = alc883_dac_nids,
10060 .adc_nids = alc883_adc_nids_alt,
10061 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10062 .capsrc_nids = alc883_capsrc_nids,
10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10064 .channel_mode = alc883_3ST_2ch_modes,
10065 .input_mux = &alc883_lenovo_101e_capture_source,
10066 .unsol_event = alc883_lenovo_101e_unsol_event,
10067 .init_hook = alc883_lenovo_101e_all_automute,
10069 [ALC883_LENOVO_NB0763] = {
10070 .mixers = { alc883_lenovo_nb0763_mixer },
10071 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10072 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10073 .dac_nids = alc883_dac_nids,
10074 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10075 .channel_mode = alc883_3ST_2ch_modes,
10076 .need_dac_fix = 1,
10077 .input_mux = &alc883_lenovo_nb0763_capture_source,
10078 .unsol_event = alc_automute_amp_unsol_event,
10079 .setup = alc883_medion_md2_setup,
10080 .init_hook = alc_automute_amp,
10082 [ALC888_LENOVO_MS7195_DIG] = {
10083 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10084 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10085 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10086 .dac_nids = alc883_dac_nids,
10087 .dig_out_nid = ALC883_DIGOUT_NID,
10088 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10089 .channel_mode = alc883_3ST_6ch_modes,
10090 .need_dac_fix = 1,
10091 .input_mux = &alc883_capture_source,
10092 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10093 .init_hook = alc888_lenovo_ms7195_front_automute,
10095 [ALC883_HAIER_W66] = {
10096 .mixers = { alc883_targa_2ch_mixer},
10097 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10098 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10099 .dac_nids = alc883_dac_nids,
10100 .dig_out_nid = ALC883_DIGOUT_NID,
10101 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10102 .channel_mode = alc883_3ST_2ch_modes,
10103 .input_mux = &alc883_capture_source,
10104 .unsol_event = alc_automute_amp_unsol_event,
10105 .setup = alc883_haier_w66_setup,
10106 .init_hook = alc_automute_amp,
10108 [ALC888_3ST_HP] = {
10109 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10110 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10111 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10112 .dac_nids = alc883_dac_nids,
10113 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10114 .channel_mode = alc888_3st_hp_modes,
10115 .need_dac_fix = 1,
10116 .input_mux = &alc883_capture_source,
10117 .unsol_event = alc_automute_amp_unsol_event,
10118 .setup = alc888_3st_hp_setup,
10119 .init_hook = alc_automute_amp,
10121 [ALC888_6ST_DELL] = {
10122 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10123 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10124 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10125 .dac_nids = alc883_dac_nids,
10126 .dig_out_nid = ALC883_DIGOUT_NID,
10127 .dig_in_nid = ALC883_DIGIN_NID,
10128 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10129 .channel_mode = alc883_sixstack_modes,
10130 .input_mux = &alc883_capture_source,
10131 .unsol_event = alc_automute_amp_unsol_event,
10132 .setup = alc888_6st_dell_setup,
10133 .init_hook = alc_automute_amp,
10135 [ALC883_MITAC] = {
10136 .mixers = { alc883_mitac_mixer },
10137 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10138 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10139 .dac_nids = alc883_dac_nids,
10140 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10141 .channel_mode = alc883_3ST_2ch_modes,
10142 .input_mux = &alc883_capture_source,
10143 .unsol_event = alc_automute_amp_unsol_event,
10144 .setup = alc883_mitac_setup,
10145 .init_hook = alc_automute_amp,
10147 [ALC883_FUJITSU_PI2515] = {
10148 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10149 .init_verbs = { alc883_init_verbs,
10150 alc883_2ch_fujitsu_pi2515_verbs},
10151 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10152 .dac_nids = alc883_dac_nids,
10153 .dig_out_nid = ALC883_DIGOUT_NID,
10154 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10155 .channel_mode = alc883_3ST_2ch_modes,
10156 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10157 .unsol_event = alc_automute_amp_unsol_event,
10158 .setup = alc883_2ch_fujitsu_pi2515_setup,
10159 .init_hook = alc_automute_amp,
10161 [ALC888_FUJITSU_XA3530] = {
10162 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10163 .init_verbs = { alc883_init_verbs,
10164 alc888_fujitsu_xa3530_verbs },
10165 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10166 .dac_nids = alc883_dac_nids,
10167 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10168 .adc_nids = alc883_adc_nids_rev,
10169 .capsrc_nids = alc883_capsrc_nids_rev,
10170 .dig_out_nid = ALC883_DIGOUT_NID,
10171 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10172 .channel_mode = alc888_4ST_8ch_intel_modes,
10173 .num_mux_defs =
10174 ARRAY_SIZE(alc888_2_capture_sources),
10175 .input_mux = alc888_2_capture_sources,
10176 .unsol_event = alc_automute_amp_unsol_event,
10177 .setup = alc888_fujitsu_xa3530_setup,
10178 .init_hook = alc_automute_amp,
10180 [ALC888_LENOVO_SKY] = {
10181 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10182 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10183 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10184 .dac_nids = alc883_dac_nids,
10185 .dig_out_nid = ALC883_DIGOUT_NID,
10186 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10187 .channel_mode = alc883_sixstack_modes,
10188 .need_dac_fix = 1,
10189 .input_mux = &alc883_lenovo_sky_capture_source,
10190 .unsol_event = alc_automute_amp_unsol_event,
10191 .setup = alc888_lenovo_sky_setup,
10192 .init_hook = alc_automute_amp,
10194 [ALC888_ASUS_M90V] = {
10195 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10196 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10197 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10198 .dac_nids = alc883_dac_nids,
10199 .dig_out_nid = ALC883_DIGOUT_NID,
10200 .dig_in_nid = ALC883_DIGIN_NID,
10201 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10202 .channel_mode = alc883_3ST_6ch_modes,
10203 .need_dac_fix = 1,
10204 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10205 .unsol_event = alc_sku_unsol_event,
10206 .setup = alc883_mode2_setup,
10207 .init_hook = alc_inithook,
10209 [ALC888_ASUS_EEE1601] = {
10210 .mixers = { alc883_asus_eee1601_mixer },
10211 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10212 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10213 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10214 .dac_nids = alc883_dac_nids,
10215 .dig_out_nid = ALC883_DIGOUT_NID,
10216 .dig_in_nid = ALC883_DIGIN_NID,
10217 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10218 .channel_mode = alc883_3ST_2ch_modes,
10219 .need_dac_fix = 1,
10220 .input_mux = &alc883_asus_eee1601_capture_source,
10221 .unsol_event = alc_sku_unsol_event,
10222 .init_hook = alc883_eee1601_inithook,
10224 [ALC1200_ASUS_P5Q] = {
10225 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10226 .init_verbs = { alc883_init_verbs },
10227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10228 .dac_nids = alc883_dac_nids,
10229 .dig_out_nid = ALC1200_DIGOUT_NID,
10230 .dig_in_nid = ALC883_DIGIN_NID,
10231 .slave_dig_outs = alc1200_slave_dig_outs,
10232 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10233 .channel_mode = alc883_sixstack_modes,
10234 .input_mux = &alc883_capture_source,
10236 [ALC889A_MB31] = {
10237 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10238 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10239 alc880_gpio1_init_verbs },
10240 .adc_nids = alc883_adc_nids,
10241 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10242 .capsrc_nids = alc883_capsrc_nids,
10243 .dac_nids = alc883_dac_nids,
10244 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10245 .channel_mode = alc889A_mb31_6ch_modes,
10246 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10247 .input_mux = &alc889A_mb31_capture_source,
10248 .dig_out_nid = ALC883_DIGOUT_NID,
10249 .unsol_event = alc889A_mb31_unsol_event,
10250 .init_hook = alc889A_mb31_automute,
10252 [ALC883_SONY_VAIO_TT] = {
10253 .mixers = { alc883_vaiott_mixer },
10254 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
10257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10258 .channel_mode = alc883_3ST_2ch_modes,
10259 .input_mux = &alc883_capture_source,
10260 .unsol_event = alc_automute_amp_unsol_event,
10261 .setup = alc883_vaiott_setup,
10262 .init_hook = alc_automute_amp,
10268 * Pin config fixes
10270 enum {
10271 PINFIX_ABIT_AW9D_MAX
10274 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10275 { 0x15, 0x01080104 }, /* side */
10276 { 0x16, 0x01011012 }, /* rear */
10277 { 0x17, 0x01016011 }, /* clfe */
10281 static const struct alc_fixup alc882_fixups[] = {
10282 [PINFIX_ABIT_AW9D_MAX] = {
10283 .pins = alc882_abit_aw9d_pinfix
10287 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10288 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10293 * BIOS auto configuration
10295 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10296 const struct auto_pin_cfg *cfg)
10298 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10301 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10302 hda_nid_t nid, int pin_type,
10303 hda_nid_t dac)
10305 int idx;
10307 /* set as output */
10308 alc_set_pin_output(codec, nid, pin_type);
10310 if (dac == 0x25)
10311 idx = 4;
10312 else if (dac >= 0x02 && dac <= 0x05)
10313 idx = dac - 2;
10314 else
10315 return;
10316 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10319 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10321 struct alc_spec *spec = codec->spec;
10322 int i;
10324 for (i = 0; i <= HDA_SIDE; i++) {
10325 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10326 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10327 if (nid)
10328 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10329 spec->multiout.dac_nids[i]);
10333 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10335 struct alc_spec *spec = codec->spec;
10336 hda_nid_t pin, dac;
10338 pin = spec->autocfg.hp_pins[0];
10339 if (pin) {
10340 dac = spec->multiout.hp_nid;
10341 if (!dac)
10342 dac = spec->multiout.dac_nids[0]; /* to front */
10343 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10345 pin = spec->autocfg.speaker_pins[0];
10346 if (pin) {
10347 dac = spec->multiout.extra_out_nid[0];
10348 if (!dac)
10349 dac = spec->multiout.dac_nids[0]; /* to front */
10350 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10354 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10356 struct alc_spec *spec = codec->spec;
10357 int i;
10359 for (i = 0; i < AUTO_PIN_LAST; i++) {
10360 hda_nid_t nid = spec->autocfg.input_pins[i];
10361 if (!nid)
10362 continue;
10363 alc_set_input_pin(codec, nid, i);
10364 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10365 snd_hda_codec_write(codec, nid, 0,
10366 AC_VERB_SET_AMP_GAIN_MUTE,
10367 AMP_OUT_MUTE);
10371 static void alc882_auto_init_input_src(struct hda_codec *codec)
10373 struct alc_spec *spec = codec->spec;
10374 int c;
10376 for (c = 0; c < spec->num_adc_nids; c++) {
10377 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10378 hda_nid_t nid = spec->capsrc_nids[c];
10379 unsigned int mux_idx;
10380 const struct hda_input_mux *imux;
10381 int conns, mute, idx, item;
10383 conns = snd_hda_get_connections(codec, nid, conn_list,
10384 ARRAY_SIZE(conn_list));
10385 if (conns < 0)
10386 continue;
10387 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10388 imux = &spec->input_mux[mux_idx];
10389 if (!imux->num_items && mux_idx > 0)
10390 imux = &spec->input_mux[0];
10391 for (idx = 0; idx < conns; idx++) {
10392 /* if the current connection is the selected one,
10393 * unmute it as default - otherwise mute it
10395 mute = AMP_IN_MUTE(idx);
10396 for (item = 0; item < imux->num_items; item++) {
10397 if (imux->items[item].index == idx) {
10398 if (spec->cur_mux[c] == item)
10399 mute = AMP_IN_UNMUTE(idx);
10400 break;
10403 /* check if we have a selector or mixer
10404 * we could check for the widget type instead, but
10405 * just check for Amp-In presence (in case of mixer
10406 * without amp-in there is something wrong, this
10407 * function shouldn't be used or capsrc nid is wrong)
10409 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10410 snd_hda_codec_write(codec, nid, 0,
10411 AC_VERB_SET_AMP_GAIN_MUTE,
10412 mute);
10413 else if (mute != AMP_IN_MUTE(idx))
10414 snd_hda_codec_write(codec, nid, 0,
10415 AC_VERB_SET_CONNECT_SEL,
10416 idx);
10421 /* add mic boosts if needed */
10422 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10424 struct alc_spec *spec = codec->spec;
10425 int err;
10426 hda_nid_t nid;
10428 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10429 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10430 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10431 "Mic Boost",
10432 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10433 if (err < 0)
10434 return err;
10436 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10437 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10438 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10439 "Front Mic Boost",
10440 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10441 if (err < 0)
10442 return err;
10444 return 0;
10447 /* almost identical with ALC880 parser... */
10448 static int alc882_parse_auto_config(struct hda_codec *codec)
10450 struct alc_spec *spec = codec->spec;
10451 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10452 int i, err;
10454 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10455 alc882_ignore);
10456 if (err < 0)
10457 return err;
10458 if (!spec->autocfg.line_outs)
10459 return 0; /* can't find valid BIOS pin config */
10461 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10462 if (err < 0)
10463 return err;
10464 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10465 if (err < 0)
10466 return err;
10467 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10468 "Headphone");
10469 if (err < 0)
10470 return err;
10471 err = alc880_auto_create_extra_out(spec,
10472 spec->autocfg.speaker_pins[0],
10473 "Speaker");
10474 if (err < 0)
10475 return err;
10476 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10477 if (err < 0)
10478 return err;
10480 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10482 /* check multiple SPDIF-out (for recent codecs) */
10483 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10484 hda_nid_t dig_nid;
10485 err = snd_hda_get_connections(codec,
10486 spec->autocfg.dig_out_pins[i],
10487 &dig_nid, 1);
10488 if (err < 0)
10489 continue;
10490 if (!i)
10491 spec->multiout.dig_out_nid = dig_nid;
10492 else {
10493 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
10494 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
10495 break;
10496 spec->slave_dig_outs[i - 1] = dig_nid;
10499 if (spec->autocfg.dig_in_pin)
10500 spec->dig_in_nid = ALC880_DIGIN_NID;
10502 if (spec->kctls.list)
10503 add_mixer(spec, spec->kctls.list);
10505 add_verb(spec, alc883_auto_init_verbs);
10506 /* if ADC 0x07 is available, initialize it, too */
10507 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10508 add_verb(spec, alc882_adc1_init_verbs);
10510 spec->num_mux_defs = 1;
10511 spec->input_mux = &spec->private_imux[0];
10513 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10515 err = alc_auto_add_mic_boost(codec);
10516 if (err < 0)
10517 return err;
10519 return 1; /* config found */
10522 /* additional initialization for auto-configuration model */
10523 static void alc882_auto_init(struct hda_codec *codec)
10525 struct alc_spec *spec = codec->spec;
10526 alc882_auto_init_multi_out(codec);
10527 alc882_auto_init_hp_out(codec);
10528 alc882_auto_init_analog_input(codec);
10529 alc882_auto_init_input_src(codec);
10530 if (spec->unsol_event)
10531 alc_inithook(codec);
10534 static int patch_alc882(struct hda_codec *codec)
10536 struct alc_spec *spec;
10537 int err, board_config;
10539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10540 if (spec == NULL)
10541 return -ENOMEM;
10543 codec->spec = spec;
10545 alc_auto_parse_customize_define(codec);
10547 switch (codec->vendor_id) {
10548 case 0x10ec0882:
10549 case 0x10ec0885:
10550 break;
10551 default:
10552 /* ALC883 and variants */
10553 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10554 break;
10557 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10558 alc882_models,
10559 alc882_cfg_tbl);
10561 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10562 board_config = snd_hda_check_board_codec_sid_config(codec,
10563 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10565 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10566 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10567 codec->chip_name);
10568 board_config = ALC882_AUTO;
10571 if (board_config == ALC882_AUTO)
10572 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
10574 if (board_config == ALC882_AUTO) {
10575 /* automatic parse from the BIOS config */
10576 err = alc882_parse_auto_config(codec);
10577 if (err < 0) {
10578 alc_free(codec);
10579 return err;
10580 } else if (!err) {
10581 printk(KERN_INFO
10582 "hda_codec: Cannot set up configuration "
10583 "from BIOS. Using base mode...\n");
10584 board_config = ALC882_3ST_DIG;
10588 if (has_cdefine_beep(codec)) {
10589 err = snd_hda_attach_beep_device(codec, 0x1);
10590 if (err < 0) {
10591 alc_free(codec);
10592 return err;
10596 if (board_config != ALC882_AUTO)
10597 setup_preset(codec, &alc882_presets[board_config]);
10599 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10600 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10601 /* FIXME: setup DAC5 */
10602 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10603 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10605 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10606 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10608 if (!spec->adc_nids && spec->input_mux) {
10609 int i, j;
10610 spec->num_adc_nids = 0;
10611 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10612 const struct hda_input_mux *imux = spec->input_mux;
10613 hda_nid_t cap;
10614 hda_nid_t items[16];
10615 hda_nid_t nid = alc882_adc_nids[i];
10616 unsigned int wcap = get_wcaps(codec, nid);
10617 /* get type */
10618 wcap = get_wcaps_type(wcap);
10619 if (wcap != AC_WID_AUD_IN)
10620 continue;
10621 spec->private_adc_nids[spec->num_adc_nids] = nid;
10622 err = snd_hda_get_connections(codec, nid, &cap, 1);
10623 if (err < 0)
10624 continue;
10625 err = snd_hda_get_connections(codec, cap, items,
10626 ARRAY_SIZE(items));
10627 if (err < 0)
10628 continue;
10629 for (j = 0; j < imux->num_items; j++)
10630 if (imux->items[j].index >= err)
10631 break;
10632 if (j < imux->num_items)
10633 continue;
10634 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10635 spec->num_adc_nids++;
10637 spec->adc_nids = spec->private_adc_nids;
10638 spec->capsrc_nids = spec->private_capsrc_nids;
10641 set_capture_mixer(codec);
10643 if (has_cdefine_beep(codec))
10644 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10646 if (board_config == ALC882_AUTO)
10647 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10649 spec->vmaster_nid = 0x0c;
10651 codec->patch_ops = alc_patch_ops;
10652 if (board_config == ALC882_AUTO)
10653 spec->init_hook = alc882_auto_init;
10654 #ifdef CONFIG_SND_HDA_POWER_SAVE
10655 if (!spec->loopback.amplist)
10656 spec->loopback.amplist = alc882_loopbacks;
10657 #endif
10659 return 0;
10664 * ALC262 support
10667 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10668 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10670 #define alc262_dac_nids alc260_dac_nids
10671 #define alc262_adc_nids alc882_adc_nids
10672 #define alc262_adc_nids_alt alc882_adc_nids_alt
10673 #define alc262_capsrc_nids alc882_capsrc_nids
10674 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10676 #define alc262_modes alc260_modes
10677 #define alc262_capture_source alc882_capture_source
10679 static hda_nid_t alc262_dmic_adc_nids[1] = {
10680 /* ADC0 */
10681 0x09
10684 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10686 static struct snd_kcontrol_new alc262_base_mixer[] = {
10687 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10688 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10689 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10690 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10691 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10692 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10695 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10696 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10697 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10699 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10701 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10702 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10703 { } /* end */
10706 /* update HP, line and mono-out pins according to the master switch */
10707 static void alc262_hp_master_update(struct hda_codec *codec)
10709 struct alc_spec *spec = codec->spec;
10710 int val = spec->master_sw;
10712 /* HP & line-out */
10713 snd_hda_codec_write_cache(codec, 0x1b, 0,
10714 AC_VERB_SET_PIN_WIDGET_CONTROL,
10715 val ? PIN_HP : 0);
10716 snd_hda_codec_write_cache(codec, 0x15, 0,
10717 AC_VERB_SET_PIN_WIDGET_CONTROL,
10718 val ? PIN_HP : 0);
10719 /* mono (speaker) depending on the HP jack sense */
10720 val = val && !spec->jack_present;
10721 snd_hda_codec_write_cache(codec, 0x16, 0,
10722 AC_VERB_SET_PIN_WIDGET_CONTROL,
10723 val ? PIN_OUT : 0);
10726 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10728 struct alc_spec *spec = codec->spec;
10730 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10731 alc262_hp_master_update(codec);
10734 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10736 if ((res >> 26) != ALC880_HP_EVENT)
10737 return;
10738 alc262_hp_bpc_automute(codec);
10741 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10743 struct alc_spec *spec = codec->spec;
10745 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10746 alc262_hp_master_update(codec);
10749 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10750 unsigned int res)
10752 if ((res >> 26) != ALC880_HP_EVENT)
10753 return;
10754 alc262_hp_wildwest_automute(codec);
10757 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10759 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10760 struct snd_ctl_elem_value *ucontrol)
10762 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10763 struct alc_spec *spec = codec->spec;
10764 int val = !!*ucontrol->value.integer.value;
10766 if (val == spec->master_sw)
10767 return 0;
10768 spec->master_sw = val;
10769 alc262_hp_master_update(codec);
10770 return 1;
10773 #define ALC262_HP_MASTER_SWITCH \
10775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10776 .name = "Master Playback Switch", \
10777 .info = snd_ctl_boolean_mono_info, \
10778 .get = alc262_hp_master_sw_get, \
10779 .put = alc262_hp_master_sw_put, \
10780 }, \
10782 .iface = NID_MAPPING, \
10783 .name = "Master Playback Switch", \
10784 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10788 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10789 ALC262_HP_MASTER_SWITCH,
10790 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10791 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10793 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10794 HDA_OUTPUT),
10795 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10796 HDA_OUTPUT),
10797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10800 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10801 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10802 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10803 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10804 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10805 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10806 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10807 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10808 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10809 { } /* end */
10812 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10813 ALC262_HP_MASTER_SWITCH,
10814 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10815 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10816 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10818 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10819 HDA_OUTPUT),
10820 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10821 HDA_OUTPUT),
10822 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10823 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10824 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10825 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10826 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10827 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10828 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10829 { } /* end */
10832 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10833 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10834 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10835 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10836 { } /* end */
10839 /* mute/unmute internal speaker according to the hp jack and mute state */
10840 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10842 struct alc_spec *spec = codec->spec;
10844 spec->autocfg.hp_pins[0] = 0x15;
10845 spec->autocfg.speaker_pins[0] = 0x14;
10848 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10849 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10850 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10851 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10852 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10855 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10856 { } /* end */
10859 static struct hda_verb alc262_hp_t5735_verbs[] = {
10860 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10861 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10863 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10867 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10868 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10869 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10870 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10871 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10872 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10873 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10874 { } /* end */
10877 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10879 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10880 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10881 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10882 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10883 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10885 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10887 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10891 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10892 .num_items = 1,
10893 .items = {
10894 { "Line", 0x1 },
10898 /* bind hp and internal speaker mute (with plug check) as master switch */
10899 static void alc262_hippo_master_update(struct hda_codec *codec)
10901 struct alc_spec *spec = codec->spec;
10902 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10903 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10904 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10905 unsigned int mute;
10907 /* HP */
10908 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10909 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10910 HDA_AMP_MUTE, mute);
10911 /* mute internal speaker per jack sense */
10912 if (spec->jack_present)
10913 mute = HDA_AMP_MUTE;
10914 if (line_nid)
10915 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10916 HDA_AMP_MUTE, mute);
10917 if (speaker_nid && speaker_nid != line_nid)
10918 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10919 HDA_AMP_MUTE, mute);
10922 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10924 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10925 struct snd_ctl_elem_value *ucontrol)
10927 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10928 struct alc_spec *spec = codec->spec;
10929 int val = !!*ucontrol->value.integer.value;
10931 if (val == spec->master_sw)
10932 return 0;
10933 spec->master_sw = val;
10934 alc262_hippo_master_update(codec);
10935 return 1;
10938 #define ALC262_HIPPO_MASTER_SWITCH \
10940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10941 .name = "Master Playback Switch", \
10942 .info = snd_ctl_boolean_mono_info, \
10943 .get = alc262_hippo_master_sw_get, \
10944 .put = alc262_hippo_master_sw_put, \
10945 }, \
10947 .iface = NID_MAPPING, \
10948 .name = "Master Playback Switch", \
10949 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10950 (SUBDEV_SPEAKER(0) << 16), \
10953 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10954 ALC262_HIPPO_MASTER_SWITCH,
10955 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10956 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10957 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10958 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10959 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10960 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10961 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10962 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10963 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10964 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10965 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10966 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10967 { } /* end */
10970 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10971 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10972 ALC262_HIPPO_MASTER_SWITCH,
10973 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10974 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10979 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10980 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10982 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10983 { } /* end */
10986 /* mute/unmute internal speaker according to the hp jack and mute state */
10987 static void alc262_hippo_automute(struct hda_codec *codec)
10989 struct alc_spec *spec = codec->spec;
10990 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10992 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10993 alc262_hippo_master_update(codec);
10996 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10998 if ((res >> 26) != ALC880_HP_EVENT)
10999 return;
11000 alc262_hippo_automute(codec);
11003 static void alc262_hippo_setup(struct hda_codec *codec)
11005 struct alc_spec *spec = codec->spec;
11007 spec->autocfg.hp_pins[0] = 0x15;
11008 spec->autocfg.speaker_pins[0] = 0x14;
11011 static void alc262_hippo1_setup(struct hda_codec *codec)
11013 struct alc_spec *spec = codec->spec;
11015 spec->autocfg.hp_pins[0] = 0x1b;
11016 spec->autocfg.speaker_pins[0] = 0x14;
11020 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11021 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11022 ALC262_HIPPO_MASTER_SWITCH,
11023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11025 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11026 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11027 { } /* end */
11030 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11031 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11032 ALC262_HIPPO_MASTER_SWITCH,
11033 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11036 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11037 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11038 { } /* end */
11041 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11042 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11043 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11044 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11045 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11050 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11051 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11052 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11053 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11054 { } /* end */
11057 static struct hda_verb alc262_tyan_verbs[] = {
11058 /* Headphone automute */
11059 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11060 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11061 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11063 /* P11 AUX_IN, white 4-pin connector */
11064 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11065 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11066 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11067 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11072 /* unsolicited event for HP jack sensing */
11073 static void alc262_tyan_setup(struct hda_codec *codec)
11075 struct alc_spec *spec = codec->spec;
11077 spec->autocfg.hp_pins[0] = 0x1b;
11078 spec->autocfg.speaker_pins[0] = 0x15;
11082 #define alc262_capture_mixer alc882_capture_mixer
11083 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11086 * generic initialization of ADC, input mixers and output mixers
11088 static struct hda_verb alc262_init_verbs[] = {
11090 * Unmute ADC0-2 and set the default input to mic-in
11092 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11093 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11094 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11095 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11096 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11097 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11099 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11100 * mixer widget
11101 * Note: PASD motherboards uses the Line In 2 as the input for
11102 * front panel mic (mic 2)
11104 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11109 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11112 * Set up output mixers (0x0c - 0x0e)
11114 /* set vol=0 to output mixers */
11115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11116 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11117 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11118 /* set up input amps for analog loopback */
11119 /* Amp Indices: DAC = 0, mixer = 1 */
11120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11121 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11123 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11125 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11127 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11128 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11129 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11130 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11132 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11137 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11138 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11141 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11143 /* FIXME: use matrix-type input source selection */
11144 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11145 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11146 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11147 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11150 /* Input mixer2 */
11151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11152 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11153 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11154 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11155 /* Input mixer3 */
11156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11164 static struct hda_verb alc262_eapd_verbs[] = {
11165 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11166 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11170 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11171 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11172 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11173 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11175 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11180 static struct hda_verb alc262_sony_unsol_verbs[] = {
11181 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11182 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11183 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11185 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11186 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11190 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11195 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11196 { } /* end */
11199 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11200 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11204 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11206 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11207 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11211 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11213 struct alc_spec *spec = codec->spec;
11215 spec->autocfg.hp_pins[0] = 0x15;
11216 spec->autocfg.speaker_pins[0] = 0x14;
11217 spec->ext_mic.pin = 0x18;
11218 spec->ext_mic.mux_idx = 0;
11219 spec->int_mic.pin = 0x12;
11220 spec->int_mic.mux_idx = 9;
11221 spec->auto_mic = 1;
11225 * nec model
11226 * 0x15 = headphone
11227 * 0x16 = internal speaker
11228 * 0x18 = external mic
11231 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11232 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11233 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11237 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11239 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11241 { } /* end */
11244 static struct hda_verb alc262_nec_verbs[] = {
11245 /* Unmute Speaker */
11246 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11248 /* Headphone */
11249 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11250 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11252 /* External mic to headphone */
11253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11254 /* External mic to speaker */
11255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11260 * fujitsu model
11261 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11262 * 0x1b = port replicator headphone out
11265 #define ALC_HP_EVENT 0x37
11267 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11268 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11270 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11275 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11276 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11277 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11281 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11282 /* Front Mic pin: input vref at 50% */
11283 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11284 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11288 static struct hda_input_mux alc262_fujitsu_capture_source = {
11289 .num_items = 3,
11290 .items = {
11291 { "Mic", 0x0 },
11292 { "Int Mic", 0x1 },
11293 { "CD", 0x4 },
11297 static struct hda_input_mux alc262_HP_capture_source = {
11298 .num_items = 5,
11299 .items = {
11300 { "Mic", 0x0 },
11301 { "Front Mic", 0x1 },
11302 { "Line", 0x2 },
11303 { "CD", 0x4 },
11304 { "AUX IN", 0x6 },
11308 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11309 .num_items = 4,
11310 .items = {
11311 { "Mic", 0x0 },
11312 { "Front Mic", 0x2 },
11313 { "Line", 0x1 },
11314 { "CD", 0x4 },
11318 /* mute/unmute internal speaker according to the hp jacks and mute state */
11319 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11321 struct alc_spec *spec = codec->spec;
11322 unsigned int mute;
11324 if (force || !spec->sense_updated) {
11325 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11326 snd_hda_jack_detect(codec, 0x1b);
11327 spec->sense_updated = 1;
11329 /* unmute internal speaker only if both HPs are unplugged and
11330 * master switch is on
11332 if (spec->jack_present)
11333 mute = HDA_AMP_MUTE;
11334 else
11335 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11336 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11337 HDA_AMP_MUTE, mute);
11340 /* unsolicited event for HP jack sensing */
11341 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11342 unsigned int res)
11344 if ((res >> 26) != ALC_HP_EVENT)
11345 return;
11346 alc262_fujitsu_automute(codec, 1);
11349 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11351 alc262_fujitsu_automute(codec, 1);
11354 /* bind volumes of both NID 0x0c and 0x0d */
11355 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11356 .ops = &snd_hda_bind_vol,
11357 .values = {
11358 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11359 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11364 /* mute/unmute internal speaker according to the hp jack and mute state */
11365 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11367 struct alc_spec *spec = codec->spec;
11368 unsigned int mute;
11370 if (force || !spec->sense_updated) {
11371 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11372 spec->sense_updated = 1;
11374 if (spec->jack_present) {
11375 /* mute internal speaker */
11376 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11377 HDA_AMP_MUTE, HDA_AMP_MUTE);
11378 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11379 HDA_AMP_MUTE, HDA_AMP_MUTE);
11380 } else {
11381 /* unmute internal speaker if necessary */
11382 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11383 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11384 HDA_AMP_MUTE, mute);
11385 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11386 HDA_AMP_MUTE, mute);
11390 /* unsolicited event for HP jack sensing */
11391 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11392 unsigned int res)
11394 if ((res >> 26) != ALC_HP_EVENT)
11395 return;
11396 alc262_lenovo_3000_automute(codec, 1);
11399 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11400 int dir, int idx, long *valp)
11402 int i, change = 0;
11404 for (i = 0; i < 2; i++, valp++)
11405 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11406 HDA_AMP_MUTE,
11407 *valp ? 0 : HDA_AMP_MUTE);
11408 return change;
11411 /* bind hp and internal speaker mute (with plug check) */
11412 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11413 struct snd_ctl_elem_value *ucontrol)
11415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11416 long *valp = ucontrol->value.integer.value;
11417 int change;
11419 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11420 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11421 if (change)
11422 alc262_fujitsu_automute(codec, 0);
11423 return change;
11426 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11427 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11429 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11430 .name = "Master Playback Switch",
11431 .subdevice = HDA_SUBDEV_AMP_FLAG,
11432 .info = snd_hda_mixer_amp_switch_info,
11433 .get = snd_hda_mixer_amp_switch_get,
11434 .put = alc262_fujitsu_master_sw_put,
11435 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11438 .iface = NID_MAPPING,
11439 .name = "Master Playback Switch",
11440 .private_value = 0x1b,
11442 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11443 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11444 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11446 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11447 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11449 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11450 { } /* end */
11453 /* bind hp and internal speaker mute (with plug check) */
11454 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11455 struct snd_ctl_elem_value *ucontrol)
11457 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11458 long *valp = ucontrol->value.integer.value;
11459 int change;
11461 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11462 if (change)
11463 alc262_lenovo_3000_automute(codec, 0);
11464 return change;
11467 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11468 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11470 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11471 .name = "Master Playback Switch",
11472 .subdevice = HDA_SUBDEV_AMP_FLAG,
11473 .info = snd_hda_mixer_amp_switch_info,
11474 .get = snd_hda_mixer_amp_switch_get,
11475 .put = alc262_lenovo_3000_master_sw_put,
11476 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11478 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11479 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11480 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11483 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11484 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11485 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11486 { } /* end */
11489 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11490 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11491 ALC262_HIPPO_MASTER_SWITCH,
11492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11494 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11495 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11497 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11498 { } /* end */
11501 /* additional init verbs for Benq laptops */
11502 static struct hda_verb alc262_EAPD_verbs[] = {
11503 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11504 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11508 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11512 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11513 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11517 /* Samsung Q1 Ultra Vista model setup */
11518 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11519 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11520 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11523 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
11524 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
11525 { } /* end */
11528 static struct hda_verb alc262_ultra_verbs[] = {
11529 /* output mixer */
11530 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11533 /* speaker */
11534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11537 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11538 /* HP */
11539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11542 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11543 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11544 /* internal mic */
11545 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11546 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11547 /* ADC, choose mic */
11548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11549 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11557 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11561 /* mute/unmute internal speaker according to the hp jack and mute state */
11562 static void alc262_ultra_automute(struct hda_codec *codec)
11564 struct alc_spec *spec = codec->spec;
11565 unsigned int mute;
11567 mute = 0;
11568 /* auto-mute only when HP is used as HP */
11569 if (!spec->cur_mux[0]) {
11570 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11571 if (spec->jack_present)
11572 mute = HDA_AMP_MUTE;
11574 /* mute/unmute internal speaker */
11575 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11576 HDA_AMP_MUTE, mute);
11577 /* mute/unmute HP */
11578 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11579 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11582 /* unsolicited event for HP jack sensing */
11583 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11584 unsigned int res)
11586 if ((res >> 26) != ALC880_HP_EVENT)
11587 return;
11588 alc262_ultra_automute(codec);
11591 static struct hda_input_mux alc262_ultra_capture_source = {
11592 .num_items = 2,
11593 .items = {
11594 { "Mic", 0x1 },
11595 { "Headphone", 0x7 },
11599 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11600 struct snd_ctl_elem_value *ucontrol)
11602 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11603 struct alc_spec *spec = codec->spec;
11604 int ret;
11606 ret = alc_mux_enum_put(kcontrol, ucontrol);
11607 if (!ret)
11608 return 0;
11609 /* reprogram the HP pin as mic or HP according to the input source */
11610 snd_hda_codec_write_cache(codec, 0x15, 0,
11611 AC_VERB_SET_PIN_WIDGET_CONTROL,
11612 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11613 alc262_ultra_automute(codec); /* mute/unmute HP */
11614 return ret;
11617 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11618 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11619 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11622 .name = "Capture Source",
11623 .info = alc_mux_enum_info,
11624 .get = alc_mux_enum_get,
11625 .put = alc262_ultra_mux_enum_put,
11628 .iface = NID_MAPPING,
11629 .name = "Capture Source",
11630 .private_value = 0x15,
11632 { } /* end */
11635 /* We use two mixers depending on the output pin; 0x16 is a mono output
11636 * and thus it's bound with a different mixer.
11637 * This function returns which mixer amp should be used.
11639 static int alc262_check_volbit(hda_nid_t nid)
11641 if (!nid)
11642 return 0;
11643 else if (nid == 0x16)
11644 return 2;
11645 else
11646 return 1;
11649 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11650 const char *pfx, int *vbits)
11652 unsigned long val;
11653 int vbit;
11655 vbit = alc262_check_volbit(nid);
11656 if (!vbit)
11657 return 0;
11658 if (*vbits & vbit) /* a volume control for this mixer already there */
11659 return 0;
11660 *vbits |= vbit;
11661 if (vbit == 2)
11662 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11663 else
11664 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11665 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
11668 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11669 const char *pfx)
11671 unsigned long val;
11673 if (!nid)
11674 return 0;
11675 if (nid == 0x16)
11676 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11677 else
11678 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11679 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
11682 /* add playback controls from the parsed DAC table */
11683 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11684 const struct auto_pin_cfg *cfg)
11686 const char *pfx;
11687 int vbits;
11688 int err;
11690 spec->multiout.num_dacs = 1; /* only use one dac */
11691 spec->multiout.dac_nids = spec->private_dac_nids;
11692 spec->multiout.dac_nids[0] = 2;
11694 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11695 pfx = "Master";
11696 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11697 pfx = "Speaker";
11698 else
11699 pfx = "Front";
11700 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11701 if (err < 0)
11702 return err;
11703 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11704 if (err < 0)
11705 return err;
11706 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11707 if (err < 0)
11708 return err;
11710 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11711 alc262_check_volbit(cfg->speaker_pins[0]) |
11712 alc262_check_volbit(cfg->hp_pins[0]);
11713 if (vbits == 1 || vbits == 2)
11714 pfx = "Master"; /* only one mixer is used */
11715 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11716 pfx = "Speaker";
11717 else
11718 pfx = "Front";
11719 vbits = 0;
11720 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11721 if (err < 0)
11722 return err;
11723 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11724 &vbits);
11725 if (err < 0)
11726 return err;
11727 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11728 &vbits);
11729 if (err < 0)
11730 return err;
11731 return 0;
11734 #define alc262_auto_create_input_ctls \
11735 alc882_auto_create_input_ctls
11738 * generic initialization of ADC, input mixers and output mixers
11740 static struct hda_verb alc262_volume_init_verbs[] = {
11742 * Unmute ADC0-2 and set the default input to mic-in
11744 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11746 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11748 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11749 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11751 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11752 * mixer widget
11753 * Note: PASD motherboards uses the Line In 2 as the input for
11754 * front panel mic (mic 2)
11756 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11757 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11758 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11759 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11760 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11761 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11764 * Set up output mixers (0x0c - 0x0f)
11766 /* set vol=0 to output mixers */
11767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11768 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11769 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11771 /* set up input amps for analog loopback */
11772 /* Amp Indices: DAC = 0, mixer = 1 */
11773 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11775 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11780 /* FIXME: use matrix-type input source selection */
11781 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11782 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11783 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11784 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11785 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11786 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11787 /* Input mixer2 */
11788 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11789 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11790 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11791 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11792 /* Input mixer3 */
11793 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11795 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11796 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11801 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11803 * Unmute ADC0-2 and set the default input to mic-in
11805 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11807 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11809 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11810 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11812 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11813 * mixer widget
11814 * Note: PASD motherboards uses the Line In 2 as the input for
11815 * front panel mic (mic 2)
11817 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11818 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11819 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11820 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11821 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11822 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11823 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11824 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11827 * Set up output mixers (0x0c - 0x0e)
11829 /* set vol=0 to output mixers */
11830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11831 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11832 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11834 /* set up input amps for analog loopback */
11835 /* Amp Indices: DAC = 0, mixer = 1 */
11836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11838 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11839 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11840 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11843 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11844 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11845 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11850 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11851 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11853 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11855 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11856 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11857 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11860 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11862 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11863 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11864 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11867 /* FIXME: use matrix-type input source selection */
11868 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11869 /* Input mixer1: only unmute Mic */
11870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11873 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11874 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11875 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11876 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11877 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11878 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11879 /* Input mixer2 */
11880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11885 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11888 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11889 /* Input mixer3 */
11890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11891 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11893 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11894 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11895 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11896 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11897 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11898 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11900 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11905 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11907 * Unmute ADC0-2 and set the default input to mic-in
11909 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11911 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11912 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11914 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11916 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11917 * mixer widget
11918 * Note: PASD motherboards uses the Line In 2 as the input for front
11919 * panel mic (mic 2)
11921 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11926 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11931 * Set up output mixers (0x0c - 0x0e)
11933 /* set vol=0 to output mixers */
11934 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11935 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11938 /* set up input amps for analog loopback */
11939 /* Amp Indices: DAC = 0, mixer = 1 */
11940 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11942 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11944 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11945 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11951 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11952 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11953 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11954 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11956 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11959 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11960 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11962 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11963 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11964 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11965 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11966 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11967 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11969 /* FIXME: use matrix-type input source selection */
11970 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11971 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11976 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11977 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11978 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11979 /* Input mixer2 */
11980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11981 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11982 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11983 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11985 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11986 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11987 /* Input mixer3 */
11988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11991 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11992 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11993 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11994 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11996 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12001 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12004 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12005 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12007 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12008 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12009 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12010 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12012 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12013 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12019 #ifdef CONFIG_SND_HDA_POWER_SAVE
12020 #define alc262_loopbacks alc880_loopbacks
12021 #endif
12023 /* pcm configuration: identical with ALC880 */
12024 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12025 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12026 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12027 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12030 * BIOS auto configuration
12032 static int alc262_parse_auto_config(struct hda_codec *codec)
12034 struct alc_spec *spec = codec->spec;
12035 int err;
12036 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12038 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12039 alc262_ignore);
12040 if (err < 0)
12041 return err;
12042 if (!spec->autocfg.line_outs) {
12043 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12044 spec->multiout.max_channels = 2;
12045 spec->no_analog = 1;
12046 goto dig_only;
12048 return 0; /* can't find valid BIOS pin config */
12050 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12051 if (err < 0)
12052 return err;
12053 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12054 if (err < 0)
12055 return err;
12057 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12059 dig_only:
12060 if (spec->autocfg.dig_outs) {
12061 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
12062 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12064 if (spec->autocfg.dig_in_pin)
12065 spec->dig_in_nid = ALC262_DIGIN_NID;
12067 if (spec->kctls.list)
12068 add_mixer(spec, spec->kctls.list);
12070 add_verb(spec, alc262_volume_init_verbs);
12071 spec->num_mux_defs = 1;
12072 spec->input_mux = &spec->private_imux[0];
12074 err = alc_auto_add_mic_boost(codec);
12075 if (err < 0)
12076 return err;
12078 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12080 return 1;
12083 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12084 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12085 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12086 #define alc262_auto_init_input_src alc882_auto_init_input_src
12089 /* init callback for auto-configuration model -- overriding the default init */
12090 static void alc262_auto_init(struct hda_codec *codec)
12092 struct alc_spec *spec = codec->spec;
12093 alc262_auto_init_multi_out(codec);
12094 alc262_auto_init_hp_out(codec);
12095 alc262_auto_init_analog_input(codec);
12096 alc262_auto_init_input_src(codec);
12097 if (spec->unsol_event)
12098 alc_inithook(codec);
12102 * configuration and preset
12104 static const char *alc262_models[ALC262_MODEL_LAST] = {
12105 [ALC262_BASIC] = "basic",
12106 [ALC262_HIPPO] = "hippo",
12107 [ALC262_HIPPO_1] = "hippo_1",
12108 [ALC262_FUJITSU] = "fujitsu",
12109 [ALC262_HP_BPC] = "hp-bpc",
12110 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12111 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12112 [ALC262_HP_RP5700] = "hp-rp5700",
12113 [ALC262_BENQ_ED8] = "benq",
12114 [ALC262_BENQ_T31] = "benq-t31",
12115 [ALC262_SONY_ASSAMD] = "sony-assamd",
12116 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12117 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12118 [ALC262_ULTRA] = "ultra",
12119 [ALC262_LENOVO_3000] = "lenovo-3000",
12120 [ALC262_NEC] = "nec",
12121 [ALC262_TYAN] = "tyan",
12122 [ALC262_AUTO] = "auto",
12125 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12126 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12127 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12128 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12129 ALC262_HP_BPC),
12130 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12131 ALC262_HP_BPC),
12132 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12133 ALC262_HP_BPC),
12134 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12135 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12136 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12137 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12138 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12139 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12140 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12141 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12142 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12143 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12144 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12145 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12146 ALC262_HP_TC_T5735),
12147 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12148 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12149 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12150 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12151 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12152 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12153 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12154 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12155 #if 0 /* disable the quirk since model=auto works better in recent versions */
12156 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12157 ALC262_SONY_ASSAMD),
12158 #endif
12159 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12160 ALC262_TOSHIBA_RX1),
12161 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12162 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12163 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12164 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12165 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12166 ALC262_ULTRA),
12167 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12168 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12169 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12170 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12171 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12175 static struct alc_config_preset alc262_presets[] = {
12176 [ALC262_BASIC] = {
12177 .mixers = { alc262_base_mixer },
12178 .init_verbs = { alc262_init_verbs },
12179 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12180 .dac_nids = alc262_dac_nids,
12181 .hp_nid = 0x03,
12182 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12183 .channel_mode = alc262_modes,
12184 .input_mux = &alc262_capture_source,
12186 [ALC262_HIPPO] = {
12187 .mixers = { alc262_hippo_mixer },
12188 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12189 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12190 .dac_nids = alc262_dac_nids,
12191 .hp_nid = 0x03,
12192 .dig_out_nid = ALC262_DIGOUT_NID,
12193 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12194 .channel_mode = alc262_modes,
12195 .input_mux = &alc262_capture_source,
12196 .unsol_event = alc262_hippo_unsol_event,
12197 .setup = alc262_hippo_setup,
12198 .init_hook = alc262_hippo_automute,
12200 [ALC262_HIPPO_1] = {
12201 .mixers = { alc262_hippo1_mixer },
12202 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12203 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12204 .dac_nids = alc262_dac_nids,
12205 .hp_nid = 0x02,
12206 .dig_out_nid = ALC262_DIGOUT_NID,
12207 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12208 .channel_mode = alc262_modes,
12209 .input_mux = &alc262_capture_source,
12210 .unsol_event = alc262_hippo_unsol_event,
12211 .setup = alc262_hippo1_setup,
12212 .init_hook = alc262_hippo_automute,
12214 [ALC262_FUJITSU] = {
12215 .mixers = { alc262_fujitsu_mixer },
12216 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12217 alc262_fujitsu_unsol_verbs },
12218 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12219 .dac_nids = alc262_dac_nids,
12220 .hp_nid = 0x03,
12221 .dig_out_nid = ALC262_DIGOUT_NID,
12222 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12223 .channel_mode = alc262_modes,
12224 .input_mux = &alc262_fujitsu_capture_source,
12225 .unsol_event = alc262_fujitsu_unsol_event,
12226 .init_hook = alc262_fujitsu_init_hook,
12228 [ALC262_HP_BPC] = {
12229 .mixers = { alc262_HP_BPC_mixer },
12230 .init_verbs = { alc262_HP_BPC_init_verbs },
12231 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12232 .dac_nids = alc262_dac_nids,
12233 .hp_nid = 0x03,
12234 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12235 .channel_mode = alc262_modes,
12236 .input_mux = &alc262_HP_capture_source,
12237 .unsol_event = alc262_hp_bpc_unsol_event,
12238 .init_hook = alc262_hp_bpc_automute,
12240 [ALC262_HP_BPC_D7000_WF] = {
12241 .mixers = { alc262_HP_BPC_WildWest_mixer },
12242 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12243 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12244 .dac_nids = alc262_dac_nids,
12245 .hp_nid = 0x03,
12246 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12247 .channel_mode = alc262_modes,
12248 .input_mux = &alc262_HP_D7000_capture_source,
12249 .unsol_event = alc262_hp_wildwest_unsol_event,
12250 .init_hook = alc262_hp_wildwest_automute,
12252 [ALC262_HP_BPC_D7000_WL] = {
12253 .mixers = { alc262_HP_BPC_WildWest_mixer,
12254 alc262_HP_BPC_WildWest_option_mixer },
12255 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12256 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12257 .dac_nids = alc262_dac_nids,
12258 .hp_nid = 0x03,
12259 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12260 .channel_mode = alc262_modes,
12261 .input_mux = &alc262_HP_D7000_capture_source,
12262 .unsol_event = alc262_hp_wildwest_unsol_event,
12263 .init_hook = alc262_hp_wildwest_automute,
12265 [ALC262_HP_TC_T5735] = {
12266 .mixers = { alc262_hp_t5735_mixer },
12267 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12268 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12269 .dac_nids = alc262_dac_nids,
12270 .hp_nid = 0x03,
12271 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12272 .channel_mode = alc262_modes,
12273 .input_mux = &alc262_capture_source,
12274 .unsol_event = alc_sku_unsol_event,
12275 .setup = alc262_hp_t5735_setup,
12276 .init_hook = alc_inithook,
12278 [ALC262_HP_RP5700] = {
12279 .mixers = { alc262_hp_rp5700_mixer },
12280 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12281 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12282 .dac_nids = alc262_dac_nids,
12283 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12284 .channel_mode = alc262_modes,
12285 .input_mux = &alc262_hp_rp5700_capture_source,
12287 [ALC262_BENQ_ED8] = {
12288 .mixers = { alc262_base_mixer },
12289 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12290 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12291 .dac_nids = alc262_dac_nids,
12292 .hp_nid = 0x03,
12293 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12294 .channel_mode = alc262_modes,
12295 .input_mux = &alc262_capture_source,
12297 [ALC262_SONY_ASSAMD] = {
12298 .mixers = { alc262_sony_mixer },
12299 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12300 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12301 .dac_nids = alc262_dac_nids,
12302 .hp_nid = 0x02,
12303 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12304 .channel_mode = alc262_modes,
12305 .input_mux = &alc262_capture_source,
12306 .unsol_event = alc262_hippo_unsol_event,
12307 .setup = alc262_hippo_setup,
12308 .init_hook = alc262_hippo_automute,
12310 [ALC262_BENQ_T31] = {
12311 .mixers = { alc262_benq_t31_mixer },
12312 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12313 alc_hp15_unsol_verbs },
12314 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12315 .dac_nids = alc262_dac_nids,
12316 .hp_nid = 0x03,
12317 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12318 .channel_mode = alc262_modes,
12319 .input_mux = &alc262_capture_source,
12320 .unsol_event = alc262_hippo_unsol_event,
12321 .setup = alc262_hippo_setup,
12322 .init_hook = alc262_hippo_automute,
12324 [ALC262_ULTRA] = {
12325 .mixers = { alc262_ultra_mixer },
12326 .cap_mixer = alc262_ultra_capture_mixer,
12327 .init_verbs = { alc262_ultra_verbs },
12328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12329 .dac_nids = alc262_dac_nids,
12330 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12331 .channel_mode = alc262_modes,
12332 .input_mux = &alc262_ultra_capture_source,
12333 .adc_nids = alc262_adc_nids, /* ADC0 */
12334 .capsrc_nids = alc262_capsrc_nids,
12335 .num_adc_nids = 1, /* single ADC */
12336 .unsol_event = alc262_ultra_unsol_event,
12337 .init_hook = alc262_ultra_automute,
12339 [ALC262_LENOVO_3000] = {
12340 .mixers = { alc262_lenovo_3000_mixer },
12341 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12342 alc262_lenovo_3000_unsol_verbs,
12343 alc262_lenovo_3000_init_verbs },
12344 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12345 .dac_nids = alc262_dac_nids,
12346 .hp_nid = 0x03,
12347 .dig_out_nid = ALC262_DIGOUT_NID,
12348 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12349 .channel_mode = alc262_modes,
12350 .input_mux = &alc262_fujitsu_capture_source,
12351 .unsol_event = alc262_lenovo_3000_unsol_event,
12353 [ALC262_NEC] = {
12354 .mixers = { alc262_nec_mixer },
12355 .init_verbs = { alc262_nec_verbs },
12356 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12357 .dac_nids = alc262_dac_nids,
12358 .hp_nid = 0x03,
12359 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12360 .channel_mode = alc262_modes,
12361 .input_mux = &alc262_capture_source,
12363 [ALC262_TOSHIBA_S06] = {
12364 .mixers = { alc262_toshiba_s06_mixer },
12365 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12366 alc262_eapd_verbs },
12367 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12368 .capsrc_nids = alc262_dmic_capsrc_nids,
12369 .dac_nids = alc262_dac_nids,
12370 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12371 .num_adc_nids = 1, /* single ADC */
12372 .dig_out_nid = ALC262_DIGOUT_NID,
12373 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12374 .channel_mode = alc262_modes,
12375 .unsol_event = alc_sku_unsol_event,
12376 .setup = alc262_toshiba_s06_setup,
12377 .init_hook = alc_inithook,
12379 [ALC262_TOSHIBA_RX1] = {
12380 .mixers = { alc262_toshiba_rx1_mixer },
12381 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12382 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12383 .dac_nids = alc262_dac_nids,
12384 .hp_nid = 0x03,
12385 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12386 .channel_mode = alc262_modes,
12387 .input_mux = &alc262_capture_source,
12388 .unsol_event = alc262_hippo_unsol_event,
12389 .setup = alc262_hippo_setup,
12390 .init_hook = alc262_hippo_automute,
12392 [ALC262_TYAN] = {
12393 .mixers = { alc262_tyan_mixer },
12394 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12395 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12396 .dac_nids = alc262_dac_nids,
12397 .hp_nid = 0x02,
12398 .dig_out_nid = ALC262_DIGOUT_NID,
12399 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12400 .channel_mode = alc262_modes,
12401 .input_mux = &alc262_capture_source,
12402 .unsol_event = alc_automute_amp_unsol_event,
12403 .setup = alc262_tyan_setup,
12404 .init_hook = alc_automute_amp,
12408 static int patch_alc262(struct hda_codec *codec)
12410 struct alc_spec *spec;
12411 int board_config;
12412 int err;
12414 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12415 if (spec == NULL)
12416 return -ENOMEM;
12418 codec->spec = spec;
12419 #if 0
12420 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12421 * under-run
12424 int tmp;
12425 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12426 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12427 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12428 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12430 #endif
12431 alc_auto_parse_customize_define(codec);
12433 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12435 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12436 alc262_models,
12437 alc262_cfg_tbl);
12439 if (board_config < 0) {
12440 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12441 codec->chip_name);
12442 board_config = ALC262_AUTO;
12445 if (board_config == ALC262_AUTO) {
12446 /* automatic parse from the BIOS config */
12447 err = alc262_parse_auto_config(codec);
12448 if (err < 0) {
12449 alc_free(codec);
12450 return err;
12451 } else if (!err) {
12452 printk(KERN_INFO
12453 "hda_codec: Cannot set up configuration "
12454 "from BIOS. Using base mode...\n");
12455 board_config = ALC262_BASIC;
12459 if (!spec->no_analog && has_cdefine_beep(codec)) {
12460 err = snd_hda_attach_beep_device(codec, 0x1);
12461 if (err < 0) {
12462 alc_free(codec);
12463 return err;
12467 if (board_config != ALC262_AUTO)
12468 setup_preset(codec, &alc262_presets[board_config]);
12470 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12471 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12473 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12474 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12476 if (!spec->adc_nids && spec->input_mux) {
12477 int i;
12478 /* check whether the digital-mic has to be supported */
12479 for (i = 0; i < spec->input_mux->num_items; i++) {
12480 if (spec->input_mux->items[i].index >= 9)
12481 break;
12483 if (i < spec->input_mux->num_items) {
12484 /* use only ADC0 */
12485 spec->adc_nids = alc262_dmic_adc_nids;
12486 spec->num_adc_nids = 1;
12487 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12488 } else {
12489 /* all analog inputs */
12490 /* check whether NID 0x07 is valid */
12491 unsigned int wcap = get_wcaps(codec, 0x07);
12493 /* get type */
12494 wcap = get_wcaps_type(wcap);
12495 if (wcap != AC_WID_AUD_IN) {
12496 spec->adc_nids = alc262_adc_nids_alt;
12497 spec->num_adc_nids =
12498 ARRAY_SIZE(alc262_adc_nids_alt);
12499 spec->capsrc_nids = alc262_capsrc_nids_alt;
12500 } else {
12501 spec->adc_nids = alc262_adc_nids;
12502 spec->num_adc_nids =
12503 ARRAY_SIZE(alc262_adc_nids);
12504 spec->capsrc_nids = alc262_capsrc_nids;
12508 if (!spec->cap_mixer && !spec->no_analog)
12509 set_capture_mixer(codec);
12510 if (!spec->no_analog && has_cdefine_beep(codec))
12511 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12513 spec->vmaster_nid = 0x0c;
12515 codec->patch_ops = alc_patch_ops;
12516 if (board_config == ALC262_AUTO)
12517 spec->init_hook = alc262_auto_init;
12518 #ifdef CONFIG_SND_HDA_POWER_SAVE
12519 if (!spec->loopback.amplist)
12520 spec->loopback.amplist = alc262_loopbacks;
12521 #endif
12523 return 0;
12527 * ALC268 channel source setting (2 channel)
12529 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12530 #define alc268_modes alc260_modes
12532 static hda_nid_t alc268_dac_nids[2] = {
12533 /* front, hp */
12534 0x02, 0x03
12537 static hda_nid_t alc268_adc_nids[2] = {
12538 /* ADC0-1 */
12539 0x08, 0x07
12542 static hda_nid_t alc268_adc_nids_alt[1] = {
12543 /* ADC0 */
12544 0x08
12547 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12549 static struct snd_kcontrol_new alc268_base_mixer[] = {
12550 /* output mixer control */
12551 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12552 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12555 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12556 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12557 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12561 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12562 /* output mixer control */
12563 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12564 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12565 ALC262_HIPPO_MASTER_SWITCH,
12566 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12567 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12568 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12572 /* bind Beep switches of both NID 0x0f and 0x10 */
12573 static struct hda_bind_ctls alc268_bind_beep_sw = {
12574 .ops = &snd_hda_bind_sw,
12575 .values = {
12576 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12577 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12582 static struct snd_kcontrol_new alc268_beep_mixer[] = {
12583 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12584 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12588 static struct hda_verb alc268_eapd_verbs[] = {
12589 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12590 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12594 /* Toshiba specific */
12595 static struct hda_verb alc268_toshiba_verbs[] = {
12596 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12597 { } /* end */
12600 /* Acer specific */
12601 /* bind volumes of both NID 0x02 and 0x03 */
12602 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12603 .ops = &snd_hda_bind_vol,
12604 .values = {
12605 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12606 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12611 /* mute/unmute internal speaker according to the hp jack and mute state */
12612 static void alc268_acer_automute(struct hda_codec *codec, int force)
12614 struct alc_spec *spec = codec->spec;
12615 unsigned int mute;
12617 if (force || !spec->sense_updated) {
12618 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
12619 spec->sense_updated = 1;
12621 if (spec->jack_present)
12622 mute = HDA_AMP_MUTE; /* mute internal speaker */
12623 else /* unmute internal speaker if necessary */
12624 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12625 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12626 HDA_AMP_MUTE, mute);
12630 /* bind hp and internal speaker mute (with plug check) */
12631 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12632 struct snd_ctl_elem_value *ucontrol)
12634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12635 long *valp = ucontrol->value.integer.value;
12636 int change;
12638 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
12639 if (change)
12640 alc268_acer_automute(codec, 0);
12641 return change;
12644 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12645 /* output mixer control */
12646 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12648 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12649 .name = "Master Playback Switch",
12650 .subdevice = HDA_SUBDEV_AMP_FLAG,
12651 .info = snd_hda_mixer_amp_switch_info,
12652 .get = snd_hda_mixer_amp_switch_get,
12653 .put = alc268_acer_master_sw_put,
12654 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12656 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12660 static struct snd_kcontrol_new alc268_acer_mixer[] = {
12661 /* output mixer control */
12662 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12665 .name = "Master Playback Switch",
12666 .subdevice = HDA_SUBDEV_AMP_FLAG,
12667 .info = snd_hda_mixer_amp_switch_info,
12668 .get = snd_hda_mixer_amp_switch_get,
12669 .put = alc268_acer_master_sw_put,
12670 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12673 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12674 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12678 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12679 /* output mixer control */
12680 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12683 .name = "Master Playback Switch",
12684 .subdevice = HDA_SUBDEV_AMP_FLAG,
12685 .info = snd_hda_mixer_amp_switch_info,
12686 .get = snd_hda_mixer_amp_switch_get,
12687 .put = alc268_acer_master_sw_put,
12688 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12690 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12691 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12695 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12696 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12697 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12698 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12699 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12700 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12701 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12705 static struct hda_verb alc268_acer_verbs[] = {
12706 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12707 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12710 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12711 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12712 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12716 /* unsolicited event for HP jack sensing */
12717 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12718 #define alc268_toshiba_setup alc262_hippo_setup
12719 #define alc268_toshiba_automute alc262_hippo_automute
12721 static void alc268_acer_unsol_event(struct hda_codec *codec,
12722 unsigned int res)
12724 if ((res >> 26) != ALC880_HP_EVENT)
12725 return;
12726 alc268_acer_automute(codec, 1);
12729 static void alc268_acer_init_hook(struct hda_codec *codec)
12731 alc268_acer_automute(codec, 1);
12734 /* toggle speaker-output according to the hp-jack state */
12735 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12737 unsigned int present;
12738 unsigned char bits;
12740 present = snd_hda_jack_detect(codec, 0x15);
12741 bits = present ? HDA_AMP_MUTE : 0;
12742 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12743 HDA_AMP_MUTE, bits);
12744 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12745 HDA_AMP_MUTE, bits);
12748 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12749 unsigned int res)
12751 switch (res >> 26) {
12752 case ALC880_HP_EVENT:
12753 alc268_aspire_one_speaker_automute(codec);
12754 break;
12755 case ALC880_MIC_EVENT:
12756 alc_mic_automute(codec);
12757 break;
12761 static void alc268_acer_lc_setup(struct hda_codec *codec)
12763 struct alc_spec *spec = codec->spec;
12764 spec->ext_mic.pin = 0x18;
12765 spec->ext_mic.mux_idx = 0;
12766 spec->int_mic.pin = 0x12;
12767 spec->int_mic.mux_idx = 6;
12768 spec->auto_mic = 1;
12771 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12773 alc268_aspire_one_speaker_automute(codec);
12774 alc_mic_automute(codec);
12777 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12778 /* output mixer control */
12779 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12780 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12781 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12783 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12784 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12788 static struct hda_verb alc268_dell_verbs[] = {
12789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12792 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12796 /* mute/unmute internal speaker according to the hp jack and mute state */
12797 static void alc268_dell_setup(struct hda_codec *codec)
12799 struct alc_spec *spec = codec->spec;
12801 spec->autocfg.hp_pins[0] = 0x15;
12802 spec->autocfg.speaker_pins[0] = 0x14;
12803 spec->ext_mic.pin = 0x18;
12804 spec->ext_mic.mux_idx = 0;
12805 spec->int_mic.pin = 0x19;
12806 spec->int_mic.mux_idx = 1;
12807 spec->auto_mic = 1;
12810 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12812 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12813 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12814 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12815 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12816 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12817 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12818 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12822 static struct hda_verb alc267_quanta_il1_verbs[] = {
12823 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12828 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12830 struct alc_spec *spec = codec->spec;
12831 spec->autocfg.hp_pins[0] = 0x15;
12832 spec->autocfg.speaker_pins[0] = 0x14;
12833 spec->ext_mic.pin = 0x18;
12834 spec->ext_mic.mux_idx = 0;
12835 spec->int_mic.pin = 0x19;
12836 spec->int_mic.mux_idx = 1;
12837 spec->auto_mic = 1;
12841 * generic initialization of ADC, input mixers and output mixers
12843 static struct hda_verb alc268_base_init_verbs[] = {
12844 /* Unmute DAC0-1 and set vol = 0 */
12845 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12846 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12849 * Set up output mixers (0x0c - 0x0e)
12851 /* set vol=0 to output mixers */
12852 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12853 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12855 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12856 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12860 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12861 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12862 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12863 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12864 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12865 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12868 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12869 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12870 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12871 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12873 /* set PCBEEP vol = 0, mute connections */
12874 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12875 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12876 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12878 /* Unmute Selector 23h,24h and set the default input to mic-in */
12880 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12882 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12883 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12889 * generic initialization of ADC, input mixers and output mixers
12891 static struct hda_verb alc268_volume_init_verbs[] = {
12892 /* set output DAC */
12893 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12894 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12898 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12899 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12900 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12902 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12903 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12904 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12907 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12909 /* set PCBEEP vol = 0, mute connections */
12910 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12912 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12917 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12918 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12919 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12920 { } /* end */
12923 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12924 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12925 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12926 _DEFINE_CAPSRC(1),
12927 { } /* end */
12930 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12931 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12932 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12933 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12934 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12935 _DEFINE_CAPSRC(2),
12936 { } /* end */
12939 static struct hda_input_mux alc268_capture_source = {
12940 .num_items = 4,
12941 .items = {
12942 { "Mic", 0x0 },
12943 { "Front Mic", 0x1 },
12944 { "Line", 0x2 },
12945 { "CD", 0x3 },
12949 static struct hda_input_mux alc268_acer_capture_source = {
12950 .num_items = 3,
12951 .items = {
12952 { "Mic", 0x0 },
12953 { "Internal Mic", 0x1 },
12954 { "Line", 0x2 },
12958 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12959 .num_items = 3,
12960 .items = {
12961 { "Mic", 0x0 },
12962 { "Internal Mic", 0x6 },
12963 { "Line", 0x2 },
12967 #ifdef CONFIG_SND_DEBUG
12968 static struct snd_kcontrol_new alc268_test_mixer[] = {
12969 /* Volume widgets */
12970 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12971 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12972 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12973 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12974 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12975 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12976 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12977 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12978 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12979 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12980 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12981 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12982 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12983 /* The below appears problematic on some hardwares */
12984 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12985 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12986 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12987 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12988 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12990 /* Modes for retasking pin widgets */
12991 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12992 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12993 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12994 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12996 /* Controls for GPIO pins, assuming they are configured as outputs */
12997 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12998 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12999 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13000 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13002 /* Switches to allow the digital SPDIF output pin to be enabled.
13003 * The ALC268 does not have an SPDIF input.
13005 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13007 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13008 * this output to turn on an external amplifier.
13010 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13011 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13013 { } /* end */
13015 #endif
13017 /* create input playback/capture controls for the given pin */
13018 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13019 const char *ctlname, int idx)
13021 hda_nid_t dac;
13022 int err;
13024 switch (nid) {
13025 case 0x14:
13026 case 0x16:
13027 dac = 0x02;
13028 break;
13029 case 0x15:
13030 case 0x1a: /* ALC259/269 only */
13031 case 0x1b: /* ALC259/269 only */
13032 case 0x21: /* ALC269vb has this pin, too */
13033 dac = 0x03;
13034 break;
13035 default:
13036 return 0;
13038 if (spec->multiout.dac_nids[0] != dac &&
13039 spec->multiout.dac_nids[1] != dac) {
13040 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13041 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13042 HDA_OUTPUT));
13043 if (err < 0)
13044 return err;
13045 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13048 if (nid != 0x16)
13049 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13050 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13051 else /* mono */
13052 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13053 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13054 if (err < 0)
13055 return err;
13056 return 0;
13059 /* add playback controls from the parsed DAC table */
13060 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13061 const struct auto_pin_cfg *cfg)
13063 hda_nid_t nid;
13064 int err;
13066 spec->multiout.dac_nids = spec->private_dac_nids;
13068 nid = cfg->line_out_pins[0];
13069 if (nid) {
13070 const char *name;
13071 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13072 name = "Speaker";
13073 else
13074 name = "Front";
13075 err = alc268_new_analog_output(spec, nid, name, 0);
13076 if (err < 0)
13077 return err;
13080 nid = cfg->speaker_pins[0];
13081 if (nid == 0x1d) {
13082 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13083 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13084 if (err < 0)
13085 return err;
13086 } else {
13087 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13088 if (err < 0)
13089 return err;
13091 nid = cfg->hp_pins[0];
13092 if (nid) {
13093 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13094 if (err < 0)
13095 return err;
13098 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13099 if (nid == 0x16) {
13100 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13101 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13102 if (err < 0)
13103 return err;
13105 return 0;
13108 /* create playback/capture controls for input pins */
13109 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13110 const struct auto_pin_cfg *cfg)
13112 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13115 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13116 hda_nid_t nid, int pin_type)
13118 int idx;
13120 alc_set_pin_output(codec, nid, pin_type);
13121 if (nid == 0x14 || nid == 0x16)
13122 idx = 0;
13123 else
13124 idx = 1;
13125 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13128 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13130 struct alc_spec *spec = codec->spec;
13131 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13132 if (nid) {
13133 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13134 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13138 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13140 struct alc_spec *spec = codec->spec;
13141 hda_nid_t pin;
13143 pin = spec->autocfg.hp_pins[0];
13144 if (pin)
13145 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13146 pin = spec->autocfg.speaker_pins[0];
13147 if (pin)
13148 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13151 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13153 struct alc_spec *spec = codec->spec;
13154 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13155 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13156 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13157 unsigned int dac_vol1, dac_vol2;
13159 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13160 snd_hda_codec_write(codec, speaker_nid, 0,
13161 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13162 /* mute mixer inputs from 0x1d */
13163 snd_hda_codec_write(codec, 0x0f, 0,
13164 AC_VERB_SET_AMP_GAIN_MUTE,
13165 AMP_IN_UNMUTE(1));
13166 snd_hda_codec_write(codec, 0x10, 0,
13167 AC_VERB_SET_AMP_GAIN_MUTE,
13168 AMP_IN_UNMUTE(1));
13169 } else {
13170 /* unmute mixer inputs from 0x1d */
13171 snd_hda_codec_write(codec, 0x0f, 0,
13172 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13173 snd_hda_codec_write(codec, 0x10, 0,
13174 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13177 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13178 if (line_nid == 0x14)
13179 dac_vol2 = AMP_OUT_ZERO;
13180 else if (line_nid == 0x15)
13181 dac_vol1 = AMP_OUT_ZERO;
13182 if (hp_nid == 0x14)
13183 dac_vol2 = AMP_OUT_ZERO;
13184 else if (hp_nid == 0x15)
13185 dac_vol1 = AMP_OUT_ZERO;
13186 if (line_nid != 0x16 || hp_nid != 0x16 ||
13187 spec->autocfg.line_out_pins[1] != 0x16 ||
13188 spec->autocfg.line_out_pins[2] != 0x16)
13189 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13191 snd_hda_codec_write(codec, 0x02, 0,
13192 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13193 snd_hda_codec_write(codec, 0x03, 0,
13194 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13197 /* pcm configuration: identical with ALC880 */
13198 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13199 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13200 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13201 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13204 * BIOS auto configuration
13206 static int alc268_parse_auto_config(struct hda_codec *codec)
13208 struct alc_spec *spec = codec->spec;
13209 int err;
13210 static hda_nid_t alc268_ignore[] = { 0 };
13212 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13213 alc268_ignore);
13214 if (err < 0)
13215 return err;
13216 if (!spec->autocfg.line_outs) {
13217 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13218 spec->multiout.max_channels = 2;
13219 spec->no_analog = 1;
13220 goto dig_only;
13222 return 0; /* can't find valid BIOS pin config */
13224 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13225 if (err < 0)
13226 return err;
13227 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13228 if (err < 0)
13229 return err;
13231 spec->multiout.max_channels = 2;
13233 dig_only:
13234 /* digital only support output */
13235 if (spec->autocfg.dig_outs) {
13236 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
13237 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13239 if (spec->kctls.list)
13240 add_mixer(spec, spec->kctls.list);
13242 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13243 add_mixer(spec, alc268_beep_mixer);
13245 add_verb(spec, alc268_volume_init_verbs);
13246 spec->num_mux_defs = 2;
13247 spec->input_mux = &spec->private_imux[0];
13249 err = alc_auto_add_mic_boost(codec);
13250 if (err < 0)
13251 return err;
13253 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13255 return 1;
13258 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13260 /* init callback for auto-configuration model -- overriding the default init */
13261 static void alc268_auto_init(struct hda_codec *codec)
13263 struct alc_spec *spec = codec->spec;
13264 alc268_auto_init_multi_out(codec);
13265 alc268_auto_init_hp_out(codec);
13266 alc268_auto_init_mono_speaker_out(codec);
13267 alc268_auto_init_analog_input(codec);
13268 if (spec->unsol_event)
13269 alc_inithook(codec);
13273 * configuration and preset
13275 static const char *alc268_models[ALC268_MODEL_LAST] = {
13276 [ALC267_QUANTA_IL1] = "quanta-il1",
13277 [ALC268_3ST] = "3stack",
13278 [ALC268_TOSHIBA] = "toshiba",
13279 [ALC268_ACER] = "acer",
13280 [ALC268_ACER_DMIC] = "acer-dmic",
13281 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13282 [ALC268_DELL] = "dell",
13283 [ALC268_ZEPTO] = "zepto",
13284 #ifdef CONFIG_SND_DEBUG
13285 [ALC268_TEST] = "test",
13286 #endif
13287 [ALC268_AUTO] = "auto",
13290 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13291 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13292 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13293 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13294 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13295 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13296 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13297 ALC268_ACER_ASPIRE_ONE),
13298 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13299 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13300 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13301 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13302 /* almost compatible with toshiba but with optional digital outs;
13303 * auto-probing seems working fine
13305 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13306 ALC268_AUTO),
13307 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13308 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13309 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13310 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13311 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13315 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13316 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13317 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13318 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13319 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13320 ALC268_TOSHIBA),
13324 static struct alc_config_preset alc268_presets[] = {
13325 [ALC267_QUANTA_IL1] = {
13326 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13327 alc268_capture_nosrc_mixer },
13328 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13329 alc267_quanta_il1_verbs },
13330 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13331 .dac_nids = alc268_dac_nids,
13332 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13333 .adc_nids = alc268_adc_nids_alt,
13334 .hp_nid = 0x03,
13335 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13336 .channel_mode = alc268_modes,
13337 .unsol_event = alc_sku_unsol_event,
13338 .setup = alc267_quanta_il1_setup,
13339 .init_hook = alc_inithook,
13341 [ALC268_3ST] = {
13342 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13343 alc268_beep_mixer },
13344 .init_verbs = { alc268_base_init_verbs },
13345 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13346 .dac_nids = alc268_dac_nids,
13347 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13348 .adc_nids = alc268_adc_nids_alt,
13349 .capsrc_nids = alc268_capsrc_nids,
13350 .hp_nid = 0x03,
13351 .dig_out_nid = ALC268_DIGOUT_NID,
13352 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13353 .channel_mode = alc268_modes,
13354 .input_mux = &alc268_capture_source,
13356 [ALC268_TOSHIBA] = {
13357 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13358 alc268_beep_mixer },
13359 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13360 alc268_toshiba_verbs },
13361 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13362 .dac_nids = alc268_dac_nids,
13363 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13364 .adc_nids = alc268_adc_nids_alt,
13365 .capsrc_nids = alc268_capsrc_nids,
13366 .hp_nid = 0x03,
13367 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13368 .channel_mode = alc268_modes,
13369 .input_mux = &alc268_capture_source,
13370 .unsol_event = alc268_toshiba_unsol_event,
13371 .setup = alc268_toshiba_setup,
13372 .init_hook = alc268_toshiba_automute,
13374 [ALC268_ACER] = {
13375 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13376 alc268_beep_mixer },
13377 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13378 alc268_acer_verbs },
13379 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13380 .dac_nids = alc268_dac_nids,
13381 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13382 .adc_nids = alc268_adc_nids_alt,
13383 .capsrc_nids = alc268_capsrc_nids,
13384 .hp_nid = 0x02,
13385 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13386 .channel_mode = alc268_modes,
13387 .input_mux = &alc268_acer_capture_source,
13388 .unsol_event = alc268_acer_unsol_event,
13389 .init_hook = alc268_acer_init_hook,
13391 [ALC268_ACER_DMIC] = {
13392 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13393 alc268_beep_mixer },
13394 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13395 alc268_acer_verbs },
13396 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13397 .dac_nids = alc268_dac_nids,
13398 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13399 .adc_nids = alc268_adc_nids_alt,
13400 .capsrc_nids = alc268_capsrc_nids,
13401 .hp_nid = 0x02,
13402 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13403 .channel_mode = alc268_modes,
13404 .input_mux = &alc268_acer_dmic_capture_source,
13405 .unsol_event = alc268_acer_unsol_event,
13406 .init_hook = alc268_acer_init_hook,
13408 [ALC268_ACER_ASPIRE_ONE] = {
13409 .mixers = { alc268_acer_aspire_one_mixer,
13410 alc268_beep_mixer,
13411 alc268_capture_nosrc_mixer },
13412 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13413 alc268_acer_aspire_one_verbs },
13414 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13415 .dac_nids = alc268_dac_nids,
13416 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13417 .adc_nids = alc268_adc_nids_alt,
13418 .capsrc_nids = alc268_capsrc_nids,
13419 .hp_nid = 0x03,
13420 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13421 .channel_mode = alc268_modes,
13422 .unsol_event = alc268_acer_lc_unsol_event,
13423 .setup = alc268_acer_lc_setup,
13424 .init_hook = alc268_acer_lc_init_hook,
13426 [ALC268_DELL] = {
13427 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13428 alc268_capture_nosrc_mixer },
13429 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13430 alc268_dell_verbs },
13431 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13432 .dac_nids = alc268_dac_nids,
13433 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13434 .adc_nids = alc268_adc_nids_alt,
13435 .capsrc_nids = alc268_capsrc_nids,
13436 .hp_nid = 0x02,
13437 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13438 .channel_mode = alc268_modes,
13439 .unsol_event = alc_sku_unsol_event,
13440 .setup = alc268_dell_setup,
13441 .init_hook = alc_inithook,
13443 [ALC268_ZEPTO] = {
13444 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13445 alc268_beep_mixer },
13446 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13447 alc268_toshiba_verbs },
13448 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13449 .dac_nids = alc268_dac_nids,
13450 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13451 .adc_nids = alc268_adc_nids_alt,
13452 .capsrc_nids = alc268_capsrc_nids,
13453 .hp_nid = 0x03,
13454 .dig_out_nid = ALC268_DIGOUT_NID,
13455 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13456 .channel_mode = alc268_modes,
13457 .input_mux = &alc268_capture_source,
13458 .setup = alc268_toshiba_setup,
13459 .init_hook = alc268_toshiba_automute,
13461 #ifdef CONFIG_SND_DEBUG
13462 [ALC268_TEST] = {
13463 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13464 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13465 alc268_volume_init_verbs },
13466 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13467 .dac_nids = alc268_dac_nids,
13468 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13469 .adc_nids = alc268_adc_nids_alt,
13470 .capsrc_nids = alc268_capsrc_nids,
13471 .hp_nid = 0x03,
13472 .dig_out_nid = ALC268_DIGOUT_NID,
13473 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13474 .channel_mode = alc268_modes,
13475 .input_mux = &alc268_capture_source,
13477 #endif
13480 static int patch_alc268(struct hda_codec *codec)
13482 struct alc_spec *spec;
13483 int board_config;
13484 int i, has_beep, err;
13486 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13487 if (spec == NULL)
13488 return -ENOMEM;
13490 codec->spec = spec;
13492 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13493 alc268_models,
13494 alc268_cfg_tbl);
13496 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13497 board_config = snd_hda_check_board_codec_sid_config(codec,
13498 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13500 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13501 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13502 codec->chip_name);
13503 board_config = ALC268_AUTO;
13506 if (board_config == ALC268_AUTO) {
13507 /* automatic parse from the BIOS config */
13508 err = alc268_parse_auto_config(codec);
13509 if (err < 0) {
13510 alc_free(codec);
13511 return err;
13512 } else if (!err) {
13513 printk(KERN_INFO
13514 "hda_codec: Cannot set up configuration "
13515 "from BIOS. Using base mode...\n");
13516 board_config = ALC268_3ST;
13520 if (board_config != ALC268_AUTO)
13521 setup_preset(codec, &alc268_presets[board_config]);
13523 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13524 spec->stream_analog_capture = &alc268_pcm_analog_capture;
13525 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
13527 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13529 has_beep = 0;
13530 for (i = 0; i < spec->num_mixers; i++) {
13531 if (spec->mixers[i] == alc268_beep_mixer) {
13532 has_beep = 1;
13533 break;
13537 if (has_beep) {
13538 err = snd_hda_attach_beep_device(codec, 0x1);
13539 if (err < 0) {
13540 alc_free(codec);
13541 return err;
13543 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13544 /* override the amp caps for beep generator */
13545 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13546 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13547 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13548 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13549 (0 << AC_AMPCAP_MUTE_SHIFT));
13552 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13553 /* check whether NID 0x07 is valid */
13554 unsigned int wcap = get_wcaps(codec, 0x07);
13555 int i;
13557 spec->capsrc_nids = alc268_capsrc_nids;
13558 /* get type */
13559 wcap = get_wcaps_type(wcap);
13560 if (spec->auto_mic ||
13561 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
13562 spec->adc_nids = alc268_adc_nids_alt;
13563 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
13564 if (spec->auto_mic)
13565 fixup_automic_adc(codec);
13566 if (spec->auto_mic || spec->input_mux->num_items == 1)
13567 add_mixer(spec, alc268_capture_nosrc_mixer);
13568 else
13569 add_mixer(spec, alc268_capture_alt_mixer);
13570 } else {
13571 spec->adc_nids = alc268_adc_nids;
13572 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13573 add_mixer(spec, alc268_capture_mixer);
13575 /* set default input source */
13576 for (i = 0; i < spec->num_adc_nids; i++)
13577 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13578 0, AC_VERB_SET_CONNECT_SEL,
13579 i < spec->num_mux_defs ?
13580 spec->input_mux[i].items[0].index :
13581 spec->input_mux->items[0].index);
13584 spec->vmaster_nid = 0x02;
13586 codec->patch_ops = alc_patch_ops;
13587 if (board_config == ALC268_AUTO)
13588 spec->init_hook = alc268_auto_init;
13590 return 0;
13594 * ALC269 channel source setting (2 channel)
13596 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13598 #define alc269_dac_nids alc260_dac_nids
13600 static hda_nid_t alc269_adc_nids[1] = {
13601 /* ADC1 */
13602 0x08,
13605 static hda_nid_t alc269_capsrc_nids[1] = {
13606 0x23,
13609 static hda_nid_t alc269vb_adc_nids[1] = {
13610 /* ADC1 */
13611 0x09,
13614 static hda_nid_t alc269vb_capsrc_nids[1] = {
13615 0x22,
13618 static hda_nid_t alc269_adc_candidates[] = {
13619 0x08, 0x09, 0x07,
13622 #define alc269_modes alc260_modes
13623 #define alc269_capture_source alc880_lg_lw_capture_source
13625 static struct snd_kcontrol_new alc269_base_mixer[] = {
13626 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13627 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13632 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13635 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13637 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13638 { } /* end */
13641 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13642 /* output mixer control */
13643 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13645 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13646 .name = "Master Playback Switch",
13647 .subdevice = HDA_SUBDEV_AMP_FLAG,
13648 .info = snd_hda_mixer_amp_switch_info,
13649 .get = snd_hda_mixer_amp_switch_get,
13650 .put = alc268_acer_master_sw_put,
13651 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13653 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13654 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13655 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13656 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13657 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13658 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13662 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13663 /* output mixer control */
13664 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13667 .name = "Master Playback Switch",
13668 .subdevice = HDA_SUBDEV_AMP_FLAG,
13669 .info = snd_hda_mixer_amp_switch_info,
13670 .get = snd_hda_mixer_amp_switch_get,
13671 .put = alc268_acer_master_sw_put,
13672 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13677 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13678 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13679 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13680 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13681 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13682 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
13686 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13687 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13688 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13690 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13691 { } /* end */
13694 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13695 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13696 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13698 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13699 { } /* end */
13702 /* capture mixer elements */
13703 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13704 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13705 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13706 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13707 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13708 { } /* end */
13711 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13712 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13713 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13715 { } /* end */
13718 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13719 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13720 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13721 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13722 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13723 { } /* end */
13726 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13727 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13728 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13729 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13730 { } /* end */
13733 /* FSC amilo */
13734 #define alc269_fujitsu_mixer alc269_laptop_mixer
13736 static struct hda_verb alc269_quanta_fl1_verbs[] = {
13737 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13738 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13739 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13740 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13741 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13742 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13746 static struct hda_verb alc269_lifebook_verbs[] = {
13747 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13748 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13749 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13751 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13754 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13755 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13756 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13760 /* toggle speaker-output according to the hp-jack state */
13761 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13763 unsigned int present;
13764 unsigned char bits;
13766 present = snd_hda_jack_detect(codec, 0x15);
13767 bits = present ? HDA_AMP_MUTE : 0;
13768 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13769 HDA_AMP_MUTE, bits);
13770 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13771 HDA_AMP_MUTE, bits);
13773 snd_hda_codec_write(codec, 0x20, 0,
13774 AC_VERB_SET_COEF_INDEX, 0x0c);
13775 snd_hda_codec_write(codec, 0x20, 0,
13776 AC_VERB_SET_PROC_COEF, 0x680);
13778 snd_hda_codec_write(codec, 0x20, 0,
13779 AC_VERB_SET_COEF_INDEX, 0x0c);
13780 snd_hda_codec_write(codec, 0x20, 0,
13781 AC_VERB_SET_PROC_COEF, 0x480);
13784 /* toggle speaker-output according to the hp-jacks state */
13785 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13787 unsigned int present;
13788 unsigned char bits;
13790 /* Check laptop headphone socket */
13791 present = snd_hda_jack_detect(codec, 0x15);
13793 /* Check port replicator headphone socket */
13794 present |= snd_hda_jack_detect(codec, 0x1a);
13796 bits = present ? HDA_AMP_MUTE : 0;
13797 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13798 HDA_AMP_MUTE, bits);
13799 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13800 HDA_AMP_MUTE, bits);
13802 snd_hda_codec_write(codec, 0x20, 0,
13803 AC_VERB_SET_COEF_INDEX, 0x0c);
13804 snd_hda_codec_write(codec, 0x20, 0,
13805 AC_VERB_SET_PROC_COEF, 0x680);
13807 snd_hda_codec_write(codec, 0x20, 0,
13808 AC_VERB_SET_COEF_INDEX, 0x0c);
13809 snd_hda_codec_write(codec, 0x20, 0,
13810 AC_VERB_SET_PROC_COEF, 0x480);
13813 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13815 unsigned int present_laptop;
13816 unsigned int present_dock;
13818 present_laptop = snd_hda_jack_detect(codec, 0x18);
13819 present_dock = snd_hda_jack_detect(codec, 0x1b);
13821 /* Laptop mic port overrides dock mic port, design decision */
13822 if (present_dock)
13823 snd_hda_codec_write(codec, 0x23, 0,
13824 AC_VERB_SET_CONNECT_SEL, 0x3);
13825 if (present_laptop)
13826 snd_hda_codec_write(codec, 0x23, 0,
13827 AC_VERB_SET_CONNECT_SEL, 0x0);
13828 if (!present_dock && !present_laptop)
13829 snd_hda_codec_write(codec, 0x23, 0,
13830 AC_VERB_SET_CONNECT_SEL, 0x1);
13833 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13834 unsigned int res)
13836 switch (res >> 26) {
13837 case ALC880_HP_EVENT:
13838 alc269_quanta_fl1_speaker_automute(codec);
13839 break;
13840 case ALC880_MIC_EVENT:
13841 alc_mic_automute(codec);
13842 break;
13846 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13847 unsigned int res)
13849 if ((res >> 26) == ALC880_HP_EVENT)
13850 alc269_lifebook_speaker_automute(codec);
13851 if ((res >> 26) == ALC880_MIC_EVENT)
13852 alc269_lifebook_mic_autoswitch(codec);
13855 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13857 struct alc_spec *spec = codec->spec;
13858 spec->autocfg.hp_pins[0] = 0x15;
13859 spec->autocfg.speaker_pins[0] = 0x14;
13860 spec->ext_mic.pin = 0x18;
13861 spec->ext_mic.mux_idx = 0;
13862 spec->int_mic.pin = 0x19;
13863 spec->int_mic.mux_idx = 1;
13864 spec->auto_mic = 1;
13867 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13869 alc269_quanta_fl1_speaker_automute(codec);
13870 alc_mic_automute(codec);
13873 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13875 alc269_lifebook_speaker_automute(codec);
13876 alc269_lifebook_mic_autoswitch(codec);
13879 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13880 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13881 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13882 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13883 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13884 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13885 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13886 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13890 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13892 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13893 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13894 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13895 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13896 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13900 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13901 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13902 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13903 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13904 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13905 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13906 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13907 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13911 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13912 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13913 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13914 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13915 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13916 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13917 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13918 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13922 /* toggle speaker-output according to the hp-jack state */
13923 static void alc269_speaker_automute(struct hda_codec *codec)
13925 struct alc_spec *spec = codec->spec;
13926 unsigned int nid = spec->autocfg.hp_pins[0];
13927 unsigned int present;
13928 unsigned char bits;
13930 present = snd_hda_jack_detect(codec, nid);
13931 bits = present ? HDA_AMP_MUTE : 0;
13932 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13933 HDA_AMP_MUTE, bits);
13934 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13935 HDA_AMP_MUTE, bits);
13938 /* unsolicited event for HP jack sensing */
13939 static void alc269_laptop_unsol_event(struct hda_codec *codec,
13940 unsigned int res)
13942 switch (res >> 26) {
13943 case ALC880_HP_EVENT:
13944 alc269_speaker_automute(codec);
13945 break;
13946 case ALC880_MIC_EVENT:
13947 alc_mic_automute(codec);
13948 break;
13952 static void alc269_laptop_amic_setup(struct hda_codec *codec)
13954 struct alc_spec *spec = codec->spec;
13955 spec->autocfg.hp_pins[0] = 0x15;
13956 spec->autocfg.speaker_pins[0] = 0x14;
13957 spec->ext_mic.pin = 0x18;
13958 spec->ext_mic.mux_idx = 0;
13959 spec->int_mic.pin = 0x19;
13960 spec->int_mic.mux_idx = 1;
13961 spec->auto_mic = 1;
13964 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13966 struct alc_spec *spec = codec->spec;
13967 spec->autocfg.hp_pins[0] = 0x15;
13968 spec->autocfg.speaker_pins[0] = 0x14;
13969 spec->ext_mic.pin = 0x18;
13970 spec->ext_mic.mux_idx = 0;
13971 spec->int_mic.pin = 0x12;
13972 spec->int_mic.mux_idx = 5;
13973 spec->auto_mic = 1;
13976 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
13978 struct alc_spec *spec = codec->spec;
13979 spec->autocfg.hp_pins[0] = 0x21;
13980 spec->autocfg.speaker_pins[0] = 0x14;
13981 spec->ext_mic.pin = 0x18;
13982 spec->ext_mic.mux_idx = 0;
13983 spec->int_mic.pin = 0x19;
13984 spec->int_mic.mux_idx = 1;
13985 spec->auto_mic = 1;
13988 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13990 struct alc_spec *spec = codec->spec;
13991 spec->autocfg.hp_pins[0] = 0x21;
13992 spec->autocfg.speaker_pins[0] = 0x14;
13993 spec->ext_mic.pin = 0x18;
13994 spec->ext_mic.mux_idx = 0;
13995 spec->int_mic.pin = 0x12;
13996 spec->int_mic.mux_idx = 6;
13997 spec->auto_mic = 1;
14000 static void alc269_laptop_inithook(struct hda_codec *codec)
14002 alc269_speaker_automute(codec);
14003 alc_mic_automute(codec);
14007 * generic initialization of ADC, input mixers and output mixers
14009 static struct hda_verb alc269_init_verbs[] = {
14011 * Unmute ADC0 and set the default input to mic-in
14013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14016 * Set up output mixers (0x02 - 0x03)
14018 /* set vol=0 to output mixers */
14019 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14020 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14022 /* set up input amps for analog loopback */
14023 /* Amp Indices: DAC = 0, mixer = 1 */
14024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14032 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14033 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14034 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14036 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14037 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14039 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14042 /* FIXME: use Mux-type input source selection */
14043 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14044 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14045 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14047 /* set EAPD */
14048 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14052 static struct hda_verb alc269vb_init_verbs[] = {
14054 * Unmute ADC0 and set the default input to mic-in
14056 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14059 * Set up output mixers (0x02 - 0x03)
14061 /* set vol=0 to output mixers */
14062 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14063 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14065 /* set up input amps for analog loopback */
14066 /* Amp Indices: DAC = 0, mixer = 1 */
14067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14068 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14069 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14071 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14072 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14074 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14075 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14076 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14078 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14079 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14082 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14083 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14085 /* FIXME: use Mux-type input source selection */
14086 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14087 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14088 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14090 /* set EAPD */
14091 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14095 #define alc269_auto_create_multi_out_ctls \
14096 alc268_auto_create_multi_out_ctls
14097 #define alc269_auto_create_input_ctls \
14098 alc268_auto_create_input_ctls
14100 #ifdef CONFIG_SND_HDA_POWER_SAVE
14101 #define alc269_loopbacks alc880_loopbacks
14102 #endif
14104 /* pcm configuration: identical with ALC880 */
14105 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14106 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14107 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14108 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14110 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14111 .substreams = 1,
14112 .channels_min = 2,
14113 .channels_max = 8,
14114 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14115 /* NID is set in alc_build_pcms */
14116 .ops = {
14117 .open = alc880_playback_pcm_open,
14118 .prepare = alc880_playback_pcm_prepare,
14119 .cleanup = alc880_playback_pcm_cleanup
14123 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14124 .substreams = 1,
14125 .channels_min = 2,
14126 .channels_max = 2,
14127 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14128 /* NID is set in alc_build_pcms */
14131 #ifdef CONFIG_SND_HDA_POWER_SAVE
14132 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14134 switch (codec->subsystem_id) {
14135 case 0x103c1586:
14136 return 1;
14138 return 0;
14141 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14143 /* update mute-LED according to the speaker mute state */
14144 if (nid == 0x01 || nid == 0x14) {
14145 int pinval;
14146 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14147 HDA_AMP_MUTE)
14148 pinval = 0x24;
14149 else
14150 pinval = 0x20;
14151 /* mic2 vref pin is used for mute LED control */
14152 snd_hda_codec_update_cache(codec, 0x19, 0,
14153 AC_VERB_SET_PIN_WIDGET_CONTROL,
14154 pinval);
14156 return alc_check_power_status(codec, nid);
14158 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14161 * BIOS auto configuration
14163 static int alc269_parse_auto_config(struct hda_codec *codec)
14165 struct alc_spec *spec = codec->spec;
14166 int err;
14167 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14169 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14170 alc269_ignore);
14171 if (err < 0)
14172 return err;
14174 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14175 if (err < 0)
14176 return err;
14177 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14178 if (err < 0)
14179 return err;
14181 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14183 if (spec->autocfg.dig_outs)
14184 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14186 if (spec->kctls.list)
14187 add_mixer(spec, spec->kctls.list);
14189 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14190 add_verb(spec, alc269vb_init_verbs);
14191 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14192 } else {
14193 add_verb(spec, alc269_init_verbs);
14194 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14197 spec->num_mux_defs = 1;
14198 spec->input_mux = &spec->private_imux[0];
14199 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14200 sizeof(alc269_adc_candidates));
14202 /* set default input source */
14203 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
14204 0, AC_VERB_SET_CONNECT_SEL,
14205 spec->input_mux->items[0].index);
14207 err = alc_auto_add_mic_boost(codec);
14208 if (err < 0)
14209 return err;
14211 if (!spec->cap_mixer && !spec->no_analog)
14212 set_capture_mixer(codec);
14214 return 1;
14217 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14218 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14219 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14222 /* init callback for auto-configuration model -- overriding the default init */
14223 static void alc269_auto_init(struct hda_codec *codec)
14225 struct alc_spec *spec = codec->spec;
14226 alc269_auto_init_multi_out(codec);
14227 alc269_auto_init_hp_out(codec);
14228 alc269_auto_init_analog_input(codec);
14229 if (spec->unsol_event)
14230 alc_inithook(codec);
14233 enum {
14234 ALC269_FIXUP_SONY_VAIO,
14235 ALC269_FIXUP_DELL_M101Z,
14238 static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14243 static const struct alc_fixup alc269_fixups[] = {
14244 [ALC269_FIXUP_SONY_VAIO] = {
14245 .verbs = alc269_sony_vaio_fixup_verbs
14247 [ALC269_FIXUP_DELL_M101Z] = {
14248 .verbs = (const struct hda_verb[]) {
14249 /* Enables internal speaker */
14250 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14251 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14257 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14258 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14259 SND_PCI_QUIRK(0x104d, 0x9077, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14260 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14266 * configuration and preset
14268 static const char *alc269_models[ALC269_MODEL_LAST] = {
14269 [ALC269_BASIC] = "basic",
14270 [ALC269_QUANTA_FL1] = "quanta",
14271 [ALC269_AMIC] = "laptop-amic",
14272 [ALC269_DMIC] = "laptop-dmic",
14273 [ALC269_FUJITSU] = "fujitsu",
14274 [ALC269_LIFEBOOK] = "lifebook",
14275 [ALC269_AUTO] = "auto",
14278 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14279 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14280 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14281 ALC269_AMIC),
14282 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14283 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14284 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14285 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14286 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14287 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14288 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14289 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14290 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14291 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14292 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14293 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14294 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14295 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14296 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14297 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14298 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14299 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14300 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14301 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14302 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14303 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14304 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14305 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14306 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14307 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14308 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14309 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14310 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14311 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14312 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14313 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14314 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14315 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14316 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14317 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14318 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14319 ALC269_DMIC),
14320 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14321 ALC269_DMIC),
14322 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14323 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14324 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14325 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14326 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14327 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14328 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14329 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14330 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14331 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14335 static struct alc_config_preset alc269_presets[] = {
14336 [ALC269_BASIC] = {
14337 .mixers = { alc269_base_mixer },
14338 .init_verbs = { alc269_init_verbs },
14339 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14340 .dac_nids = alc269_dac_nids,
14341 .hp_nid = 0x03,
14342 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14343 .channel_mode = alc269_modes,
14344 .input_mux = &alc269_capture_source,
14346 [ALC269_QUANTA_FL1] = {
14347 .mixers = { alc269_quanta_fl1_mixer },
14348 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14349 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14350 .dac_nids = alc269_dac_nids,
14351 .hp_nid = 0x03,
14352 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14353 .channel_mode = alc269_modes,
14354 .input_mux = &alc269_capture_source,
14355 .unsol_event = alc269_quanta_fl1_unsol_event,
14356 .setup = alc269_quanta_fl1_setup,
14357 .init_hook = alc269_quanta_fl1_init_hook,
14359 [ALC269_AMIC] = {
14360 .mixers = { alc269_laptop_mixer },
14361 .cap_mixer = alc269_laptop_analog_capture_mixer,
14362 .init_verbs = { alc269_init_verbs,
14363 alc269_laptop_amic_init_verbs },
14364 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14365 .dac_nids = alc269_dac_nids,
14366 .hp_nid = 0x03,
14367 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14368 .channel_mode = alc269_modes,
14369 .unsol_event = alc269_laptop_unsol_event,
14370 .setup = alc269_laptop_amic_setup,
14371 .init_hook = alc269_laptop_inithook,
14373 [ALC269_DMIC] = {
14374 .mixers = { alc269_laptop_mixer },
14375 .cap_mixer = alc269_laptop_digital_capture_mixer,
14376 .init_verbs = { alc269_init_verbs,
14377 alc269_laptop_dmic_init_verbs },
14378 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14379 .dac_nids = alc269_dac_nids,
14380 .hp_nid = 0x03,
14381 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14382 .channel_mode = alc269_modes,
14383 .unsol_event = alc269_laptop_unsol_event,
14384 .setup = alc269_laptop_dmic_setup,
14385 .init_hook = alc269_laptop_inithook,
14387 [ALC269VB_AMIC] = {
14388 .mixers = { alc269vb_laptop_mixer },
14389 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14390 .init_verbs = { alc269vb_init_verbs,
14391 alc269vb_laptop_amic_init_verbs },
14392 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14393 .dac_nids = alc269_dac_nids,
14394 .hp_nid = 0x03,
14395 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14396 .channel_mode = alc269_modes,
14397 .unsol_event = alc269_laptop_unsol_event,
14398 .setup = alc269vb_laptop_amic_setup,
14399 .init_hook = alc269_laptop_inithook,
14401 [ALC269VB_DMIC] = {
14402 .mixers = { alc269vb_laptop_mixer },
14403 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14404 .init_verbs = { alc269vb_init_verbs,
14405 alc269vb_laptop_dmic_init_verbs },
14406 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14407 .dac_nids = alc269_dac_nids,
14408 .hp_nid = 0x03,
14409 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14410 .channel_mode = alc269_modes,
14411 .unsol_event = alc269_laptop_unsol_event,
14412 .setup = alc269vb_laptop_dmic_setup,
14413 .init_hook = alc269_laptop_inithook,
14415 [ALC269_FUJITSU] = {
14416 .mixers = { alc269_fujitsu_mixer },
14417 .cap_mixer = alc269_laptop_digital_capture_mixer,
14418 .init_verbs = { alc269_init_verbs,
14419 alc269_laptop_dmic_init_verbs },
14420 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14421 .dac_nids = alc269_dac_nids,
14422 .hp_nid = 0x03,
14423 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14424 .channel_mode = alc269_modes,
14425 .unsol_event = alc269_laptop_unsol_event,
14426 .setup = alc269_laptop_dmic_setup,
14427 .init_hook = alc269_laptop_inithook,
14429 [ALC269_LIFEBOOK] = {
14430 .mixers = { alc269_lifebook_mixer },
14431 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14432 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14433 .dac_nids = alc269_dac_nids,
14434 .hp_nid = 0x03,
14435 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14436 .channel_mode = alc269_modes,
14437 .input_mux = &alc269_capture_source,
14438 .unsol_event = alc269_lifebook_unsol_event,
14439 .init_hook = alc269_lifebook_init_hook,
14443 static int patch_alc269(struct hda_codec *codec)
14445 struct alc_spec *spec;
14446 int board_config;
14447 int err;
14448 int is_alc269vb = 0;
14450 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14451 if (spec == NULL)
14452 return -ENOMEM;
14454 codec->spec = spec;
14456 alc_auto_parse_customize_define(codec);
14458 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14459 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14460 spec->cdefine.platform_type == 1)
14461 alc_codec_rename(codec, "ALC271X");
14462 else
14463 alc_codec_rename(codec, "ALC259");
14464 is_alc269vb = 1;
14465 } else
14466 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14468 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14469 alc269_models,
14470 alc269_cfg_tbl);
14472 if (board_config < 0) {
14473 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14474 codec->chip_name);
14475 board_config = ALC269_AUTO;
14478 if (board_config == ALC269_AUTO)
14479 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14481 if (board_config == ALC269_AUTO) {
14482 /* automatic parse from the BIOS config */
14483 err = alc269_parse_auto_config(codec);
14484 if (err < 0) {
14485 alc_free(codec);
14486 return err;
14487 } else if (!err) {
14488 printk(KERN_INFO
14489 "hda_codec: Cannot set up configuration "
14490 "from BIOS. Using base mode...\n");
14491 board_config = ALC269_BASIC;
14495 if (has_cdefine_beep(codec)) {
14496 err = snd_hda_attach_beep_device(codec, 0x1);
14497 if (err < 0) {
14498 alc_free(codec);
14499 return err;
14503 if (board_config != ALC269_AUTO)
14504 setup_preset(codec, &alc269_presets[board_config]);
14506 if (board_config == ALC269_QUANTA_FL1) {
14507 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14508 * fix the sample rate of analog I/O to 44.1kHz
14510 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14511 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14512 } else {
14513 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14514 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14516 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14517 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14519 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14520 if (!is_alc269vb) {
14521 spec->adc_nids = alc269_adc_nids;
14522 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14523 spec->capsrc_nids = alc269_capsrc_nids;
14524 } else {
14525 spec->adc_nids = alc269vb_adc_nids;
14526 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14527 spec->capsrc_nids = alc269vb_capsrc_nids;
14531 if (!spec->cap_mixer)
14532 set_capture_mixer(codec);
14533 if (has_cdefine_beep(codec))
14534 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14536 if (board_config == ALC269_AUTO)
14537 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14539 spec->vmaster_nid = 0x02;
14541 codec->patch_ops = alc_patch_ops;
14542 if (board_config == ALC269_AUTO)
14543 spec->init_hook = alc269_auto_init;
14544 #ifdef CONFIG_SND_HDA_POWER_SAVE
14545 if (!spec->loopback.amplist)
14546 spec->loopback.amplist = alc269_loopbacks;
14547 if (alc269_mic2_for_mute_led(codec))
14548 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14549 #endif
14551 return 0;
14555 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14559 * set the path ways for 2 channel output
14560 * need to set the codec line out and mic 1 pin widgets to inputs
14562 static struct hda_verb alc861_threestack_ch2_init[] = {
14563 /* set pin widget 1Ah (line in) for input */
14564 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14565 /* set pin widget 18h (mic1/2) for input, for mic also enable
14566 * the vref
14568 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14571 #if 0
14572 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14573 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14574 #endif
14575 { } /* end */
14578 * 6ch mode
14579 * need to set the codec line out and mic 1 pin widgets to outputs
14581 static struct hda_verb alc861_threestack_ch6_init[] = {
14582 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14583 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14584 /* set pin widget 18h (mic1) for output (CLFE)*/
14585 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14587 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14588 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14590 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14591 #if 0
14592 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14593 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14594 #endif
14595 { } /* end */
14598 static struct hda_channel_mode alc861_threestack_modes[2] = {
14599 { 2, alc861_threestack_ch2_init },
14600 { 6, alc861_threestack_ch6_init },
14602 /* Set mic1 as input and unmute the mixer */
14603 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14604 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14605 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14606 { } /* end */
14608 /* Set mic1 as output and mute mixer */
14609 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14610 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14611 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14612 { } /* end */
14615 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14616 { 2, alc861_uniwill_m31_ch2_init },
14617 { 4, alc861_uniwill_m31_ch4_init },
14620 /* Set mic1 and line-in as input and unmute the mixer */
14621 static struct hda_verb alc861_asus_ch2_init[] = {
14622 /* set pin widget 1Ah (line in) for input */
14623 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14624 /* set pin widget 18h (mic1/2) for input, for mic also enable
14625 * the vref
14627 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14629 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14630 #if 0
14631 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14632 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14633 #endif
14634 { } /* end */
14636 /* Set mic1 nad line-in as output and mute mixer */
14637 static struct hda_verb alc861_asus_ch6_init[] = {
14638 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14639 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14640 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14641 /* set pin widget 18h (mic1) for output (CLFE)*/
14642 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14643 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14644 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14645 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14647 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14648 #if 0
14649 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14650 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14651 #endif
14652 { } /* end */
14655 static struct hda_channel_mode alc861_asus_modes[2] = {
14656 { 2, alc861_asus_ch2_init },
14657 { 6, alc861_asus_ch6_init },
14660 /* patch-ALC861 */
14662 static struct snd_kcontrol_new alc861_base_mixer[] = {
14663 /* output mixer control */
14664 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14665 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14666 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14667 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14668 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14670 /*Input mixer control */
14671 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14672 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14673 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14674 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14675 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14676 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14678 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14680 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14682 { } /* end */
14685 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14686 /* output mixer control */
14687 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14688 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14689 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14690 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14691 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14693 /* Input mixer control */
14694 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14695 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14696 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14697 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14698 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14699 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14701 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14702 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14707 .name = "Channel Mode",
14708 .info = alc_ch_mode_info,
14709 .get = alc_ch_mode_get,
14710 .put = alc_ch_mode_put,
14711 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14713 { } /* end */
14716 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14717 /* output mixer control */
14718 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14720 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14722 { } /* end */
14725 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14726 /* output mixer control */
14727 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14728 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14729 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14730 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14731 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14733 /* Input mixer control */
14734 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14735 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14736 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14737 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14738 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14739 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14740 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14741 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14742 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14747 .name = "Channel Mode",
14748 .info = alc_ch_mode_info,
14749 .get = alc_ch_mode_get,
14750 .put = alc_ch_mode_put,
14751 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14753 { } /* end */
14756 static struct snd_kcontrol_new alc861_asus_mixer[] = {
14757 /* output mixer control */
14758 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14759 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14760 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14761 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14762 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14764 /* Input mixer control */
14765 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14766 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14767 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14768 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14769 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14770 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14772 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14773 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14774 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14778 .name = "Channel Mode",
14779 .info = alc_ch_mode_info,
14780 .get = alc_ch_mode_get,
14781 .put = alc_ch_mode_put,
14782 .private_value = ARRAY_SIZE(alc861_asus_modes),
14787 /* additional mixer */
14788 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
14789 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14790 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14795 * generic initialization of ADC, input mixers and output mixers
14797 static struct hda_verb alc861_base_init_verbs[] = {
14799 * Unmute ADC0 and set the default input to mic-in
14801 /* port-A for surround (rear panel) */
14802 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14803 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14804 /* port-B for mic-in (rear panel) with vref */
14805 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14806 /* port-C for line-in (rear panel) */
14807 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14808 /* port-D for Front */
14809 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14810 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14811 /* port-E for HP out (front panel) */
14812 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14813 /* route front PCM to HP */
14814 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14815 /* port-F for mic-in (front panel) with vref */
14816 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14817 /* port-G for CLFE (rear panel) */
14818 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14819 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14820 /* port-H for side (rear panel) */
14821 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14822 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14823 /* CD-in */
14824 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14825 /* route front mic to ADC1*/
14826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14829 /* Unmute DAC0~3 & spdif out*/
14830 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14831 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14832 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14833 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14834 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14836 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14837 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14838 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14839 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14840 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14842 /* Unmute Stereo Mixer 15 */
14843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14845 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14848 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14849 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14850 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14851 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14853 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14854 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14855 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14856 /* hp used DAC 3 (Front) */
14857 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14863 static struct hda_verb alc861_threestack_init_verbs[] = {
14865 * Unmute ADC0 and set the default input to mic-in
14867 /* port-A for surround (rear panel) */
14868 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14869 /* port-B for mic-in (rear panel) with vref */
14870 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14871 /* port-C for line-in (rear panel) */
14872 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14873 /* port-D for Front */
14874 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14875 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14876 /* port-E for HP out (front panel) */
14877 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14878 /* route front PCM to HP */
14879 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14880 /* port-F for mic-in (front panel) with vref */
14881 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14882 /* port-G for CLFE (rear panel) */
14883 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14884 /* port-H for side (rear panel) */
14885 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14886 /* CD-in */
14887 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14888 /* route front mic to ADC1*/
14889 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14890 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14891 /* Unmute DAC0~3 & spdif out*/
14892 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14893 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14894 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14895 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14898 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14899 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14900 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14901 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14902 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14904 /* Unmute Stereo Mixer 15 */
14905 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14906 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14907 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14910 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14912 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14913 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14914 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14916 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14918 /* hp used DAC 3 (Front) */
14919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14924 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14926 * Unmute ADC0 and set the default input to mic-in
14928 /* port-A for surround (rear panel) */
14929 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14930 /* port-B for mic-in (rear panel) with vref */
14931 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14932 /* port-C for line-in (rear panel) */
14933 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14934 /* port-D for Front */
14935 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14936 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14937 /* port-E for HP out (front panel) */
14938 /* this has to be set to VREF80 */
14939 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14940 /* route front PCM to HP */
14941 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14942 /* port-F for mic-in (front panel) with vref */
14943 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14944 /* port-G for CLFE (rear panel) */
14945 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14946 /* port-H for side (rear panel) */
14947 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14948 /* CD-in */
14949 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14950 /* route front mic to ADC1*/
14951 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14952 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14953 /* Unmute DAC0~3 & spdif out*/
14954 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14955 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14956 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14957 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14958 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14960 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14961 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14962 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14963 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14964 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14966 /* Unmute Stereo Mixer 15 */
14967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14969 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14972 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14973 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14974 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14975 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14976 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14977 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14978 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14979 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14980 /* hp used DAC 3 (Front) */
14981 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14982 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14986 static struct hda_verb alc861_asus_init_verbs[] = {
14988 * Unmute ADC0 and set the default input to mic-in
14990 /* port-A for surround (rear panel)
14991 * according to codec#0 this is the HP jack
14993 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14994 /* route front PCM to HP */
14995 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14996 /* port-B for mic-in (rear panel) with vref */
14997 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14998 /* port-C for line-in (rear panel) */
14999 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15000 /* port-D for Front */
15001 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15002 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15003 /* port-E for HP out (front panel) */
15004 /* this has to be set to VREF80 */
15005 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15006 /* route front PCM to HP */
15007 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15008 /* port-F for mic-in (front panel) with vref */
15009 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15010 /* port-G for CLFE (rear panel) */
15011 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15012 /* port-H for side (rear panel) */
15013 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15014 /* CD-in */
15015 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15016 /* route front mic to ADC1*/
15017 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15019 /* Unmute DAC0~3 & spdif out*/
15020 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15021 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15022 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15023 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15024 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15025 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15026 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15027 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15028 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15029 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15031 /* Unmute Stereo Mixer 15 */
15032 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15033 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15037 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15038 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15039 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15040 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15041 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15042 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15043 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15044 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15045 /* hp used DAC 3 (Front) */
15046 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15047 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15051 /* additional init verbs for ASUS laptops */
15052 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15053 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15054 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15059 * generic initialization of ADC, input mixers and output mixers
15061 static struct hda_verb alc861_auto_init_verbs[] = {
15063 * Unmute ADC0 and set the default input to mic-in
15065 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15066 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15068 /* Unmute DAC0~3 & spdif out*/
15069 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15070 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15071 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15072 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15075 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15076 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15077 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15078 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15079 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15081 /* Unmute Stereo Mixer 15 */
15082 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15083 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15087 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15088 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15089 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15090 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15091 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15093 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15098 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15100 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15102 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15103 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15105 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15110 static struct hda_verb alc861_toshiba_init_verbs[] = {
15111 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15116 /* toggle speaker-output according to the hp-jack state */
15117 static void alc861_toshiba_automute(struct hda_codec *codec)
15119 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15121 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15122 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15123 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15124 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15127 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15128 unsigned int res)
15130 if ((res >> 26) == ALC880_HP_EVENT)
15131 alc861_toshiba_automute(codec);
15134 /* pcm configuration: identical with ALC880 */
15135 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15136 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15137 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15138 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15141 #define ALC861_DIGOUT_NID 0x07
15143 static struct hda_channel_mode alc861_8ch_modes[1] = {
15144 { 8, NULL }
15147 static hda_nid_t alc861_dac_nids[4] = {
15148 /* front, surround, clfe, side */
15149 0x03, 0x06, 0x05, 0x04
15152 static hda_nid_t alc660_dac_nids[3] = {
15153 /* front, clfe, surround */
15154 0x03, 0x05, 0x06
15157 static hda_nid_t alc861_adc_nids[1] = {
15158 /* ADC0-2 */
15159 0x08,
15162 static struct hda_input_mux alc861_capture_source = {
15163 .num_items = 5,
15164 .items = {
15165 { "Mic", 0x0 },
15166 { "Front Mic", 0x3 },
15167 { "Line", 0x1 },
15168 { "CD", 0x4 },
15169 { "Mixer", 0x5 },
15173 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15175 struct alc_spec *spec = codec->spec;
15176 hda_nid_t mix, srcs[5];
15177 int i, j, num;
15179 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15180 return 0;
15181 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15182 if (num < 0)
15183 return 0;
15184 for (i = 0; i < num; i++) {
15185 unsigned int type;
15186 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15187 if (type != AC_WID_AUD_OUT)
15188 continue;
15189 for (j = 0; j < spec->multiout.num_dacs; j++)
15190 if (spec->multiout.dac_nids[j] == srcs[i])
15191 break;
15192 if (j >= spec->multiout.num_dacs)
15193 return srcs[i];
15195 return 0;
15198 /* fill in the dac_nids table from the parsed pin configuration */
15199 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15200 const struct auto_pin_cfg *cfg)
15202 struct alc_spec *spec = codec->spec;
15203 int i;
15204 hda_nid_t nid, dac;
15206 spec->multiout.dac_nids = spec->private_dac_nids;
15207 for (i = 0; i < cfg->line_outs; i++) {
15208 nid = cfg->line_out_pins[i];
15209 dac = alc861_look_for_dac(codec, nid);
15210 if (!dac)
15211 continue;
15212 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15214 return 0;
15217 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15218 hda_nid_t nid, unsigned int chs)
15220 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
15221 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15224 /* add playback controls from the parsed DAC table */
15225 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15226 const struct auto_pin_cfg *cfg)
15228 struct alc_spec *spec = codec->spec;
15229 static const char *chname[4] = {
15230 "Front", "Surround", NULL /*CLFE*/, "Side"
15232 hda_nid_t nid;
15233 int i, err;
15235 if (cfg->line_outs == 1) {
15236 const char *pfx = NULL;
15237 if (!cfg->hp_outs)
15238 pfx = "Master";
15239 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15240 pfx = "Speaker";
15241 if (pfx) {
15242 nid = spec->multiout.dac_nids[0];
15243 return alc861_create_out_sw(codec, pfx, nid, 3);
15247 for (i = 0; i < cfg->line_outs; i++) {
15248 nid = spec->multiout.dac_nids[i];
15249 if (!nid)
15250 continue;
15251 if (i == 2) {
15252 /* Center/LFE */
15253 err = alc861_create_out_sw(codec, "Center", nid, 1);
15254 if (err < 0)
15255 return err;
15256 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15257 if (err < 0)
15258 return err;
15259 } else {
15260 err = alc861_create_out_sw(codec, chname[i], nid, 3);
15261 if (err < 0)
15262 return err;
15265 return 0;
15268 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15270 struct alc_spec *spec = codec->spec;
15271 int err;
15272 hda_nid_t nid;
15274 if (!pin)
15275 return 0;
15277 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15278 nid = alc861_look_for_dac(codec, pin);
15279 if (nid) {
15280 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15281 if (err < 0)
15282 return err;
15283 spec->multiout.hp_nid = nid;
15286 return 0;
15289 /* create playback/capture controls for input pins */
15290 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15291 const struct auto_pin_cfg *cfg)
15293 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15296 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15297 hda_nid_t nid,
15298 int pin_type, hda_nid_t dac)
15300 hda_nid_t mix, srcs[5];
15301 int i, num;
15303 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15304 pin_type);
15305 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15306 AMP_OUT_UNMUTE);
15307 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15308 return;
15309 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15310 if (num < 0)
15311 return;
15312 for (i = 0; i < num; i++) {
15313 unsigned int mute;
15314 if (srcs[i] == dac || srcs[i] == 0x15)
15315 mute = AMP_IN_UNMUTE(i);
15316 else
15317 mute = AMP_IN_MUTE(i);
15318 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15319 mute);
15323 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15325 struct alc_spec *spec = codec->spec;
15326 int i;
15328 for (i = 0; i < spec->autocfg.line_outs; i++) {
15329 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15330 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15331 if (nid)
15332 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15333 spec->multiout.dac_nids[i]);
15337 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15339 struct alc_spec *spec = codec->spec;
15341 if (spec->autocfg.hp_outs)
15342 alc861_auto_set_output_and_unmute(codec,
15343 spec->autocfg.hp_pins[0],
15344 PIN_HP,
15345 spec->multiout.hp_nid);
15346 if (spec->autocfg.speaker_outs)
15347 alc861_auto_set_output_and_unmute(codec,
15348 spec->autocfg.speaker_pins[0],
15349 PIN_OUT,
15350 spec->multiout.dac_nids[0]);
15353 static void alc861_auto_init_analog_input(struct hda_codec *codec)
15355 struct alc_spec *spec = codec->spec;
15356 int i;
15358 for (i = 0; i < AUTO_PIN_LAST; i++) {
15359 hda_nid_t nid = spec->autocfg.input_pins[i];
15360 if (nid >= 0x0c && nid <= 0x11)
15361 alc_set_input_pin(codec, nid, i);
15365 /* parse the BIOS configuration and set up the alc_spec */
15366 /* return 1 if successful, 0 if the proper config is not found,
15367 * or a negative error code
15369 static int alc861_parse_auto_config(struct hda_codec *codec)
15371 struct alc_spec *spec = codec->spec;
15372 int err;
15373 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15375 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15376 alc861_ignore);
15377 if (err < 0)
15378 return err;
15379 if (!spec->autocfg.line_outs)
15380 return 0; /* can't find valid BIOS pin config */
15382 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
15383 if (err < 0)
15384 return err;
15385 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15386 if (err < 0)
15387 return err;
15388 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15389 if (err < 0)
15390 return err;
15391 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
15392 if (err < 0)
15393 return err;
15395 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15397 if (spec->autocfg.dig_outs)
15398 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15400 if (spec->kctls.list)
15401 add_mixer(spec, spec->kctls.list);
15403 add_verb(spec, alc861_auto_init_verbs);
15405 spec->num_mux_defs = 1;
15406 spec->input_mux = &spec->private_imux[0];
15408 spec->adc_nids = alc861_adc_nids;
15409 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
15410 set_capture_mixer(codec);
15412 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15414 return 1;
15417 /* additional initialization for auto-configuration model */
15418 static void alc861_auto_init(struct hda_codec *codec)
15420 struct alc_spec *spec = codec->spec;
15421 alc861_auto_init_multi_out(codec);
15422 alc861_auto_init_hp_out(codec);
15423 alc861_auto_init_analog_input(codec);
15424 if (spec->unsol_event)
15425 alc_inithook(codec);
15428 #ifdef CONFIG_SND_HDA_POWER_SAVE
15429 static struct hda_amp_list alc861_loopbacks[] = {
15430 { 0x15, HDA_INPUT, 0 },
15431 { 0x15, HDA_INPUT, 1 },
15432 { 0x15, HDA_INPUT, 2 },
15433 { 0x15, HDA_INPUT, 3 },
15434 { } /* end */
15436 #endif
15440 * configuration and preset
15442 static const char *alc861_models[ALC861_MODEL_LAST] = {
15443 [ALC861_3ST] = "3stack",
15444 [ALC660_3ST] = "3stack-660",
15445 [ALC861_3ST_DIG] = "3stack-dig",
15446 [ALC861_6ST_DIG] = "6stack-dig",
15447 [ALC861_UNIWILL_M31] = "uniwill-m31",
15448 [ALC861_TOSHIBA] = "toshiba",
15449 [ALC861_ASUS] = "asus",
15450 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15451 [ALC861_AUTO] = "auto",
15454 static struct snd_pci_quirk alc861_cfg_tbl[] = {
15455 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15456 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15457 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15458 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15459 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15460 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15461 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15462 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15463 * Any other models that need this preset?
15465 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15466 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15467 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15468 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15469 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15470 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15471 /* FIXME: the below seems conflict */
15472 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15473 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15474 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15478 static struct alc_config_preset alc861_presets[] = {
15479 [ALC861_3ST] = {
15480 .mixers = { alc861_3ST_mixer },
15481 .init_verbs = { alc861_threestack_init_verbs },
15482 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15483 .dac_nids = alc861_dac_nids,
15484 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15485 .channel_mode = alc861_threestack_modes,
15486 .need_dac_fix = 1,
15487 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15488 .adc_nids = alc861_adc_nids,
15489 .input_mux = &alc861_capture_source,
15491 [ALC861_3ST_DIG] = {
15492 .mixers = { alc861_base_mixer },
15493 .init_verbs = { alc861_threestack_init_verbs },
15494 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15495 .dac_nids = alc861_dac_nids,
15496 .dig_out_nid = ALC861_DIGOUT_NID,
15497 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15498 .channel_mode = alc861_threestack_modes,
15499 .need_dac_fix = 1,
15500 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15501 .adc_nids = alc861_adc_nids,
15502 .input_mux = &alc861_capture_source,
15504 [ALC861_6ST_DIG] = {
15505 .mixers = { alc861_base_mixer },
15506 .init_verbs = { alc861_base_init_verbs },
15507 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15508 .dac_nids = alc861_dac_nids,
15509 .dig_out_nid = ALC861_DIGOUT_NID,
15510 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15511 .channel_mode = alc861_8ch_modes,
15512 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15513 .adc_nids = alc861_adc_nids,
15514 .input_mux = &alc861_capture_source,
15516 [ALC660_3ST] = {
15517 .mixers = { alc861_3ST_mixer },
15518 .init_verbs = { alc861_threestack_init_verbs },
15519 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15520 .dac_nids = alc660_dac_nids,
15521 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15522 .channel_mode = alc861_threestack_modes,
15523 .need_dac_fix = 1,
15524 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15525 .adc_nids = alc861_adc_nids,
15526 .input_mux = &alc861_capture_source,
15528 [ALC861_UNIWILL_M31] = {
15529 .mixers = { alc861_uniwill_m31_mixer },
15530 .init_verbs = { alc861_uniwill_m31_init_verbs },
15531 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15532 .dac_nids = alc861_dac_nids,
15533 .dig_out_nid = ALC861_DIGOUT_NID,
15534 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15535 .channel_mode = alc861_uniwill_m31_modes,
15536 .need_dac_fix = 1,
15537 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15538 .adc_nids = alc861_adc_nids,
15539 .input_mux = &alc861_capture_source,
15541 [ALC861_TOSHIBA] = {
15542 .mixers = { alc861_toshiba_mixer },
15543 .init_verbs = { alc861_base_init_verbs,
15544 alc861_toshiba_init_verbs },
15545 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15546 .dac_nids = alc861_dac_nids,
15547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15548 .channel_mode = alc883_3ST_2ch_modes,
15549 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15550 .adc_nids = alc861_adc_nids,
15551 .input_mux = &alc861_capture_source,
15552 .unsol_event = alc861_toshiba_unsol_event,
15553 .init_hook = alc861_toshiba_automute,
15555 [ALC861_ASUS] = {
15556 .mixers = { alc861_asus_mixer },
15557 .init_verbs = { alc861_asus_init_verbs },
15558 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15559 .dac_nids = alc861_dac_nids,
15560 .dig_out_nid = ALC861_DIGOUT_NID,
15561 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15562 .channel_mode = alc861_asus_modes,
15563 .need_dac_fix = 1,
15564 .hp_nid = 0x06,
15565 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15566 .adc_nids = alc861_adc_nids,
15567 .input_mux = &alc861_capture_source,
15569 [ALC861_ASUS_LAPTOP] = {
15570 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15571 .init_verbs = { alc861_asus_init_verbs,
15572 alc861_asus_laptop_init_verbs },
15573 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15574 .dac_nids = alc861_dac_nids,
15575 .dig_out_nid = ALC861_DIGOUT_NID,
15576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15577 .channel_mode = alc883_3ST_2ch_modes,
15578 .need_dac_fix = 1,
15579 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15580 .adc_nids = alc861_adc_nids,
15581 .input_mux = &alc861_capture_source,
15585 /* Pin config fixes */
15586 enum {
15587 PINFIX_FSC_AMILO_PI1505,
15590 static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15591 { 0x0b, 0x0221101f }, /* HP */
15592 { 0x0f, 0x90170310 }, /* speaker */
15596 static const struct alc_fixup alc861_fixups[] = {
15597 [PINFIX_FSC_AMILO_PI1505] = {
15598 .pins = alc861_fsc_amilo_pi1505_pinfix
15602 static struct snd_pci_quirk alc861_fixup_tbl[] = {
15603 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15607 static int patch_alc861(struct hda_codec *codec)
15609 struct alc_spec *spec;
15610 int board_config;
15611 int err;
15613 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15614 if (spec == NULL)
15615 return -ENOMEM;
15617 codec->spec = spec;
15619 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15620 alc861_models,
15621 alc861_cfg_tbl);
15623 if (board_config < 0) {
15624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15625 codec->chip_name);
15626 board_config = ALC861_AUTO;
15629 if (board_config == ALC861_AUTO)
15630 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
15632 if (board_config == ALC861_AUTO) {
15633 /* automatic parse from the BIOS config */
15634 err = alc861_parse_auto_config(codec);
15635 if (err < 0) {
15636 alc_free(codec);
15637 return err;
15638 } else if (!err) {
15639 printk(KERN_INFO
15640 "hda_codec: Cannot set up configuration "
15641 "from BIOS. Using base mode...\n");
15642 board_config = ALC861_3ST_DIG;
15646 err = snd_hda_attach_beep_device(codec, 0x23);
15647 if (err < 0) {
15648 alc_free(codec);
15649 return err;
15652 if (board_config != ALC861_AUTO)
15653 setup_preset(codec, &alc861_presets[board_config]);
15655 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15656 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15658 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15659 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15661 if (!spec->cap_mixer)
15662 set_capture_mixer(codec);
15663 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15665 spec->vmaster_nid = 0x03;
15667 if (board_config == ALC861_AUTO)
15668 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15670 codec->patch_ops = alc_patch_ops;
15671 if (board_config == ALC861_AUTO) {
15672 spec->init_hook = alc861_auto_init;
15673 #ifdef CONFIG_SND_HDA_POWER_SAVE
15674 spec->power_hook = alc_power_eapd;
15675 #endif
15677 #ifdef CONFIG_SND_HDA_POWER_SAVE
15678 if (!spec->loopback.amplist)
15679 spec->loopback.amplist = alc861_loopbacks;
15680 #endif
15682 return 0;
15686 * ALC861-VD support
15688 * Based on ALC882
15690 * In addition, an independent DAC
15692 #define ALC861VD_DIGOUT_NID 0x06
15694 static hda_nid_t alc861vd_dac_nids[4] = {
15695 /* front, surr, clfe, side surr */
15696 0x02, 0x03, 0x04, 0x05
15699 /* dac_nids for ALC660vd are in a different order - according to
15700 * Realtek's driver.
15701 * This should probably result in a different mixer for 6stack models
15702 * of ALC660vd codecs, but for now there is only 3stack mixer
15703 * - and it is the same as in 861vd.
15704 * adc_nids in ALC660vd are (is) the same as in 861vd
15706 static hda_nid_t alc660vd_dac_nids[3] = {
15707 /* front, rear, clfe, rear_surr */
15708 0x02, 0x04, 0x03
15711 static hda_nid_t alc861vd_adc_nids[1] = {
15712 /* ADC0 */
15713 0x09,
15716 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15718 /* input MUX */
15719 /* FIXME: should be a matrix-type input source selection */
15720 static struct hda_input_mux alc861vd_capture_source = {
15721 .num_items = 4,
15722 .items = {
15723 { "Mic", 0x0 },
15724 { "Front Mic", 0x1 },
15725 { "Line", 0x2 },
15726 { "CD", 0x4 },
15730 static struct hda_input_mux alc861vd_dallas_capture_source = {
15731 .num_items = 2,
15732 .items = {
15733 { "Ext Mic", 0x0 },
15734 { "Int Mic", 0x1 },
15738 static struct hda_input_mux alc861vd_hp_capture_source = {
15739 .num_items = 2,
15740 .items = {
15741 { "Front Mic", 0x0 },
15742 { "ATAPI Mic", 0x1 },
15747 * 2ch mode
15749 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15750 { 2, NULL }
15754 * 6ch mode
15756 static struct hda_verb alc861vd_6stack_ch6_init[] = {
15757 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15758 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15759 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15760 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15761 { } /* end */
15765 * 8ch mode
15767 static struct hda_verb alc861vd_6stack_ch8_init[] = {
15768 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15769 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15770 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15771 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15772 { } /* end */
15775 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15776 { 6, alc861vd_6stack_ch6_init },
15777 { 8, alc861vd_6stack_ch8_init },
15780 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15783 .name = "Channel Mode",
15784 .info = alc_ch_mode_info,
15785 .get = alc_ch_mode_get,
15786 .put = alc_ch_mode_put,
15788 { } /* end */
15791 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15792 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15794 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15795 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15796 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15798 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15799 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15801 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15802 HDA_OUTPUT),
15803 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15804 HDA_OUTPUT),
15805 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15806 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15808 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15809 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15813 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15817 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15818 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15819 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15821 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15822 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15827 { } /* end */
15830 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15831 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15832 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15836 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15840 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15841 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15842 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15844 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15845 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15847 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15848 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15850 { } /* end */
15853 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15854 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15855 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15856 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15860 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15864 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15865 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15866 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15871 { } /* end */
15874 /* Pin assignment: Speaker=0x14, HP = 0x15,
15875 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
15877 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
15878 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15879 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
15880 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15881 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15882 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15883 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15884 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15885 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15886 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15887 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15888 { } /* end */
15891 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
15892 * Front Mic=0x18, ATAPI Mic = 0x19,
15894 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15895 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15896 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15897 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15898 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15899 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15901 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15902 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15904 { } /* end */
15908 * generic initialization of ADC, input mixers and output mixers
15910 static struct hda_verb alc861vd_volume_init_verbs[] = {
15912 * Unmute ADC0 and set the default input to mic-in
15914 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15915 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15917 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15918 * the analog-loopback mixer widget
15920 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15924 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15925 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15927 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
15928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15934 * Set up output mixers (0x02 - 0x05)
15936 /* set vol=0 to output mixers */
15937 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15938 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15939 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15940 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15942 /* set up input amps for analog loopback */
15943 /* Amp Indices: DAC = 0, mixer = 1 */
15944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15945 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15947 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15948 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15949 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15950 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15951 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15957 * 3-stack pin configuration:
15958 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15960 static struct hda_verb alc861vd_3stack_init_verbs[] = {
15962 * Set pin mode and muting
15964 /* set front pin widgets 0x14 for output */
15965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15967 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15969 /* Mic (rear) pin: input vref at 80% */
15970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15971 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15972 /* Front Mic pin: input vref at 80% */
15973 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15974 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15975 /* Line In pin: input */
15976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15978 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15979 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15980 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15981 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15982 /* CD pin widget for input */
15983 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15989 * 6-stack pin configuration:
15991 static struct hda_verb alc861vd_6stack_init_verbs[] = {
15993 * Set pin mode and muting
15995 /* set front pin widgets 0x14 for output */
15996 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15997 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15998 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16000 /* Rear Pin: output 1 (0x0d) */
16001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16004 /* CLFE Pin: output 2 (0x0e) */
16005 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16006 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16007 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16008 /* Side Pin: output 3 (0x0f) */
16009 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16010 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16011 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16013 /* Mic (rear) pin: input vref at 80% */
16014 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16015 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16016 /* Front Mic pin: input vref at 80% */
16017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16018 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16019 /* Line In pin: input */
16020 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16021 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16022 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16023 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16024 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16025 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16026 /* CD pin widget for input */
16027 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16032 static struct hda_verb alc861vd_eapd_verbs[] = {
16033 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16037 static struct hda_verb alc660vd_eapd_verbs[] = {
16038 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16039 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16043 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16044 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16045 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16046 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16047 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16048 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16052 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16054 unsigned int present;
16055 unsigned char bits;
16057 present = snd_hda_jack_detect(codec, 0x18);
16058 bits = present ? HDA_AMP_MUTE : 0;
16060 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16061 HDA_AMP_MUTE, bits);
16064 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16066 struct alc_spec *spec = codec->spec;
16067 spec->autocfg.hp_pins[0] = 0x1b;
16068 spec->autocfg.speaker_pins[0] = 0x14;
16071 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16073 alc_automute_amp(codec);
16074 alc861vd_lenovo_mic_automute(codec);
16077 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16078 unsigned int res)
16080 switch (res >> 26) {
16081 case ALC880_MIC_EVENT:
16082 alc861vd_lenovo_mic_automute(codec);
16083 break;
16084 default:
16085 alc_automute_amp_unsol_event(codec, res);
16086 break;
16090 static struct hda_verb alc861vd_dallas_verbs[] = {
16091 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16092 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16093 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16094 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16096 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16098 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16099 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16100 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16102 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16103 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16108 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16109 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16110 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16111 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16112 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16114 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16115 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16117 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16121 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16129 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16130 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16132 { } /* end */
16135 /* toggle speaker-output according to the hp-jack state */
16136 static void alc861vd_dallas_setup(struct hda_codec *codec)
16138 struct alc_spec *spec = codec->spec;
16140 spec->autocfg.hp_pins[0] = 0x15;
16141 spec->autocfg.speaker_pins[0] = 0x14;
16144 #ifdef CONFIG_SND_HDA_POWER_SAVE
16145 #define alc861vd_loopbacks alc880_loopbacks
16146 #endif
16148 /* pcm configuration: identical with ALC880 */
16149 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16150 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16151 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16152 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16155 * configuration and preset
16157 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16158 [ALC660VD_3ST] = "3stack-660",
16159 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16160 [ALC660VD_ASUS_V1S] = "asus-v1s",
16161 [ALC861VD_3ST] = "3stack",
16162 [ALC861VD_3ST_DIG] = "3stack-digout",
16163 [ALC861VD_6ST_DIG] = "6stack-digout",
16164 [ALC861VD_LENOVO] = "lenovo",
16165 [ALC861VD_DALLAS] = "dallas",
16166 [ALC861VD_HP] = "hp",
16167 [ALC861VD_AUTO] = "auto",
16170 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16171 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16172 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16173 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16174 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16175 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16176 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16177 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16178 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16179 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16180 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16181 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16182 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16183 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16184 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16185 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16189 static struct alc_config_preset alc861vd_presets[] = {
16190 [ALC660VD_3ST] = {
16191 .mixers = { alc861vd_3st_mixer },
16192 .init_verbs = { alc861vd_volume_init_verbs,
16193 alc861vd_3stack_init_verbs },
16194 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16195 .dac_nids = alc660vd_dac_nids,
16196 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16197 .channel_mode = alc861vd_3stack_2ch_modes,
16198 .input_mux = &alc861vd_capture_source,
16200 [ALC660VD_3ST_DIG] = {
16201 .mixers = { alc861vd_3st_mixer },
16202 .init_verbs = { alc861vd_volume_init_verbs,
16203 alc861vd_3stack_init_verbs },
16204 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16205 .dac_nids = alc660vd_dac_nids,
16206 .dig_out_nid = ALC861VD_DIGOUT_NID,
16207 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16208 .channel_mode = alc861vd_3stack_2ch_modes,
16209 .input_mux = &alc861vd_capture_source,
16211 [ALC861VD_3ST] = {
16212 .mixers = { alc861vd_3st_mixer },
16213 .init_verbs = { alc861vd_volume_init_verbs,
16214 alc861vd_3stack_init_verbs },
16215 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16216 .dac_nids = alc861vd_dac_nids,
16217 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16218 .channel_mode = alc861vd_3stack_2ch_modes,
16219 .input_mux = &alc861vd_capture_source,
16221 [ALC861VD_3ST_DIG] = {
16222 .mixers = { alc861vd_3st_mixer },
16223 .init_verbs = { alc861vd_volume_init_verbs,
16224 alc861vd_3stack_init_verbs },
16225 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16226 .dac_nids = alc861vd_dac_nids,
16227 .dig_out_nid = ALC861VD_DIGOUT_NID,
16228 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16229 .channel_mode = alc861vd_3stack_2ch_modes,
16230 .input_mux = &alc861vd_capture_source,
16232 [ALC861VD_6ST_DIG] = {
16233 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16234 .init_verbs = { alc861vd_volume_init_verbs,
16235 alc861vd_6stack_init_verbs },
16236 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16237 .dac_nids = alc861vd_dac_nids,
16238 .dig_out_nid = ALC861VD_DIGOUT_NID,
16239 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16240 .channel_mode = alc861vd_6stack_modes,
16241 .input_mux = &alc861vd_capture_source,
16243 [ALC861VD_LENOVO] = {
16244 .mixers = { alc861vd_lenovo_mixer },
16245 .init_verbs = { alc861vd_volume_init_verbs,
16246 alc861vd_3stack_init_verbs,
16247 alc861vd_eapd_verbs,
16248 alc861vd_lenovo_unsol_verbs },
16249 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16250 .dac_nids = alc660vd_dac_nids,
16251 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16252 .channel_mode = alc861vd_3stack_2ch_modes,
16253 .input_mux = &alc861vd_capture_source,
16254 .unsol_event = alc861vd_lenovo_unsol_event,
16255 .setup = alc861vd_lenovo_setup,
16256 .init_hook = alc861vd_lenovo_init_hook,
16258 [ALC861VD_DALLAS] = {
16259 .mixers = { alc861vd_dallas_mixer },
16260 .init_verbs = { alc861vd_dallas_verbs },
16261 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16262 .dac_nids = alc861vd_dac_nids,
16263 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16264 .channel_mode = alc861vd_3stack_2ch_modes,
16265 .input_mux = &alc861vd_dallas_capture_source,
16266 .unsol_event = alc_automute_amp_unsol_event,
16267 .setup = alc861vd_dallas_setup,
16268 .init_hook = alc_automute_amp,
16270 [ALC861VD_HP] = {
16271 .mixers = { alc861vd_hp_mixer },
16272 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16273 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16274 .dac_nids = alc861vd_dac_nids,
16275 .dig_out_nid = ALC861VD_DIGOUT_NID,
16276 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16277 .channel_mode = alc861vd_3stack_2ch_modes,
16278 .input_mux = &alc861vd_hp_capture_source,
16279 .unsol_event = alc_automute_amp_unsol_event,
16280 .setup = alc861vd_dallas_setup,
16281 .init_hook = alc_automute_amp,
16283 [ALC660VD_ASUS_V1S] = {
16284 .mixers = { alc861vd_lenovo_mixer },
16285 .init_verbs = { alc861vd_volume_init_verbs,
16286 alc861vd_3stack_init_verbs,
16287 alc861vd_eapd_verbs,
16288 alc861vd_lenovo_unsol_verbs },
16289 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16290 .dac_nids = alc660vd_dac_nids,
16291 .dig_out_nid = ALC861VD_DIGOUT_NID,
16292 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16293 .channel_mode = alc861vd_3stack_2ch_modes,
16294 .input_mux = &alc861vd_capture_source,
16295 .unsol_event = alc861vd_lenovo_unsol_event,
16296 .setup = alc861vd_lenovo_setup,
16297 .init_hook = alc861vd_lenovo_init_hook,
16302 * BIOS auto configuration
16304 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16305 const struct auto_pin_cfg *cfg)
16307 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
16311 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16312 hda_nid_t nid, int pin_type, int dac_idx)
16314 alc_set_pin_output(codec, nid, pin_type);
16317 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16319 struct alc_spec *spec = codec->spec;
16320 int i;
16322 for (i = 0; i <= HDA_SIDE; i++) {
16323 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16324 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16325 if (nid)
16326 alc861vd_auto_set_output_and_unmute(codec, nid,
16327 pin_type, i);
16332 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16334 struct alc_spec *spec = codec->spec;
16335 hda_nid_t pin;
16337 pin = spec->autocfg.hp_pins[0];
16338 if (pin) /* connect to front and use dac 0 */
16339 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16340 pin = spec->autocfg.speaker_pins[0];
16341 if (pin)
16342 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16345 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16347 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16349 struct alc_spec *spec = codec->spec;
16350 int i;
16352 for (i = 0; i < AUTO_PIN_LAST; i++) {
16353 hda_nid_t nid = spec->autocfg.input_pins[i];
16354 if (alc_is_input_pin(codec, nid)) {
16355 alc_set_input_pin(codec, nid, i);
16356 if (nid != ALC861VD_PIN_CD_NID &&
16357 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16358 snd_hda_codec_write(codec, nid, 0,
16359 AC_VERB_SET_AMP_GAIN_MUTE,
16360 AMP_OUT_MUTE);
16365 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16367 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16368 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16370 /* add playback controls from the parsed DAC table */
16371 /* Based on ALC880 version. But ALC861VD has separate,
16372 * different NIDs for mute/unmute switch and volume control */
16373 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16374 const struct auto_pin_cfg *cfg)
16376 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16377 hda_nid_t nid_v, nid_s;
16378 int i, err;
16380 for (i = 0; i < cfg->line_outs; i++) {
16381 if (!spec->multiout.dac_nids[i])
16382 continue;
16383 nid_v = alc861vd_idx_to_mixer_vol(
16384 alc880_dac_to_idx(
16385 spec->multiout.dac_nids[i]));
16386 nid_s = alc861vd_idx_to_mixer_switch(
16387 alc880_dac_to_idx(
16388 spec->multiout.dac_nids[i]));
16390 if (i == 2) {
16391 /* Center/LFE */
16392 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16393 "Center",
16394 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16395 HDA_OUTPUT));
16396 if (err < 0)
16397 return err;
16398 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16399 "LFE",
16400 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16401 HDA_OUTPUT));
16402 if (err < 0)
16403 return err;
16404 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16405 "Center",
16406 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16407 HDA_INPUT));
16408 if (err < 0)
16409 return err;
16410 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16411 "LFE",
16412 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16413 HDA_INPUT));
16414 if (err < 0)
16415 return err;
16416 } else {
16417 const char *pfx;
16418 if (cfg->line_outs == 1 &&
16419 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16420 if (!cfg->hp_pins)
16421 pfx = "Speaker";
16422 else
16423 pfx = "PCM";
16424 } else
16425 pfx = chname[i];
16426 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16427 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16428 HDA_OUTPUT));
16429 if (err < 0)
16430 return err;
16431 if (cfg->line_outs == 1 &&
16432 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16433 pfx = "Speaker";
16434 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16435 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16436 HDA_INPUT));
16437 if (err < 0)
16438 return err;
16441 return 0;
16444 /* add playback controls for speaker and HP outputs */
16445 /* Based on ALC880 version. But ALC861VD has separate,
16446 * different NIDs for mute/unmute switch and volume control */
16447 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16448 hda_nid_t pin, const char *pfx)
16450 hda_nid_t nid_v, nid_s;
16451 int err;
16453 if (!pin)
16454 return 0;
16456 if (alc880_is_fixed_pin(pin)) {
16457 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16458 /* specify the DAC as the extra output */
16459 if (!spec->multiout.hp_nid)
16460 spec->multiout.hp_nid = nid_v;
16461 else
16462 spec->multiout.extra_out_nid[0] = nid_v;
16463 /* control HP volume/switch on the output mixer amp */
16464 nid_v = alc861vd_idx_to_mixer_vol(
16465 alc880_fixed_pin_idx(pin));
16466 nid_s = alc861vd_idx_to_mixer_switch(
16467 alc880_fixed_pin_idx(pin));
16469 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16470 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16471 if (err < 0)
16472 return err;
16473 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16474 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16475 if (err < 0)
16476 return err;
16477 } else if (alc880_is_multi_pin(pin)) {
16478 /* set manual connection */
16479 /* we have only a switch on HP-out PIN */
16480 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
16481 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16482 if (err < 0)
16483 return err;
16485 return 0;
16488 /* parse the BIOS configuration and set up the alc_spec
16489 * return 1 if successful, 0 if the proper config is not found,
16490 * or a negative error code
16491 * Based on ALC880 version - had to change it to override
16492 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16493 static int alc861vd_parse_auto_config(struct hda_codec *codec)
16495 struct alc_spec *spec = codec->spec;
16496 int err;
16497 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16499 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16500 alc861vd_ignore);
16501 if (err < 0)
16502 return err;
16503 if (!spec->autocfg.line_outs)
16504 return 0; /* can't find valid BIOS pin config */
16506 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16507 if (err < 0)
16508 return err;
16509 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16510 if (err < 0)
16511 return err;
16512 err = alc861vd_auto_create_extra_out(spec,
16513 spec->autocfg.speaker_pins[0],
16514 "Speaker");
16515 if (err < 0)
16516 return err;
16517 err = alc861vd_auto_create_extra_out(spec,
16518 spec->autocfg.hp_pins[0],
16519 "Headphone");
16520 if (err < 0)
16521 return err;
16522 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
16523 if (err < 0)
16524 return err;
16526 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16528 if (spec->autocfg.dig_outs)
16529 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16531 if (spec->kctls.list)
16532 add_mixer(spec, spec->kctls.list);
16534 add_verb(spec, alc861vd_volume_init_verbs);
16536 spec->num_mux_defs = 1;
16537 spec->input_mux = &spec->private_imux[0];
16539 err = alc_auto_add_mic_boost(codec);
16540 if (err < 0)
16541 return err;
16543 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16545 return 1;
16548 /* additional initialization for auto-configuration model */
16549 static void alc861vd_auto_init(struct hda_codec *codec)
16551 struct alc_spec *spec = codec->spec;
16552 alc861vd_auto_init_multi_out(codec);
16553 alc861vd_auto_init_hp_out(codec);
16554 alc861vd_auto_init_analog_input(codec);
16555 alc861vd_auto_init_input_src(codec);
16556 if (spec->unsol_event)
16557 alc_inithook(codec);
16560 enum {
16561 ALC660VD_FIX_ASUS_GPIO1
16564 /* reset GPIO1 */
16565 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16566 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16567 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16568 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16572 static const struct alc_fixup alc861vd_fixups[] = {
16573 [ALC660VD_FIX_ASUS_GPIO1] = {
16574 .verbs = alc660vd_fix_asus_gpio1_verbs,
16578 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16579 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16583 static int patch_alc861vd(struct hda_codec *codec)
16585 struct alc_spec *spec;
16586 int err, board_config;
16588 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16589 if (spec == NULL)
16590 return -ENOMEM;
16592 codec->spec = spec;
16594 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16595 alc861vd_models,
16596 alc861vd_cfg_tbl);
16598 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
16599 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16600 codec->chip_name);
16601 board_config = ALC861VD_AUTO;
16604 if (board_config == ALC861VD_AUTO)
16605 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
16607 if (board_config == ALC861VD_AUTO) {
16608 /* automatic parse from the BIOS config */
16609 err = alc861vd_parse_auto_config(codec);
16610 if (err < 0) {
16611 alc_free(codec);
16612 return err;
16613 } else if (!err) {
16614 printk(KERN_INFO
16615 "hda_codec: Cannot set up configuration "
16616 "from BIOS. Using base mode...\n");
16617 board_config = ALC861VD_3ST;
16621 err = snd_hda_attach_beep_device(codec, 0x23);
16622 if (err < 0) {
16623 alc_free(codec);
16624 return err;
16627 if (board_config != ALC861VD_AUTO)
16628 setup_preset(codec, &alc861vd_presets[board_config]);
16630 if (codec->vendor_id == 0x10ec0660) {
16631 /* always turn on EAPD */
16632 add_verb(spec, alc660vd_eapd_verbs);
16635 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16636 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16638 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16639 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16641 if (!spec->adc_nids) {
16642 spec->adc_nids = alc861vd_adc_nids;
16643 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16645 if (!spec->capsrc_nids)
16646 spec->capsrc_nids = alc861vd_capsrc_nids;
16648 set_capture_mixer(codec);
16649 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16651 spec->vmaster_nid = 0x02;
16653 if (board_config == ALC861VD_AUTO)
16654 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16656 codec->patch_ops = alc_patch_ops;
16658 if (board_config == ALC861VD_AUTO)
16659 spec->init_hook = alc861vd_auto_init;
16660 #ifdef CONFIG_SND_HDA_POWER_SAVE
16661 if (!spec->loopback.amplist)
16662 spec->loopback.amplist = alc861vd_loopbacks;
16663 #endif
16665 return 0;
16669 * ALC662 support
16671 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16672 * configuration. Each pin widget can choose any input DACs and a mixer.
16673 * Each ADC is connected from a mixer of all inputs. This makes possible
16674 * 6-channel independent captures.
16676 * In addition, an independent DAC for the multi-playback (not used in this
16677 * driver yet).
16679 #define ALC662_DIGOUT_NID 0x06
16680 #define ALC662_DIGIN_NID 0x0a
16682 static hda_nid_t alc662_dac_nids[4] = {
16683 /* front, rear, clfe, rear_surr */
16684 0x02, 0x03, 0x04
16687 static hda_nid_t alc272_dac_nids[2] = {
16688 0x02, 0x03
16691 static hda_nid_t alc662_adc_nids[2] = {
16692 /* ADC1-2 */
16693 0x09, 0x08
16696 static hda_nid_t alc272_adc_nids[1] = {
16697 /* ADC1-2 */
16698 0x08,
16701 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16702 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16705 /* input MUX */
16706 /* FIXME: should be a matrix-type input source selection */
16707 static struct hda_input_mux alc662_capture_source = {
16708 .num_items = 4,
16709 .items = {
16710 { "Mic", 0x0 },
16711 { "Front Mic", 0x1 },
16712 { "Line", 0x2 },
16713 { "CD", 0x4 },
16717 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16718 .num_items = 2,
16719 .items = {
16720 { "Mic", 0x1 },
16721 { "Line", 0x2 },
16725 static struct hda_input_mux alc663_capture_source = {
16726 .num_items = 3,
16727 .items = {
16728 { "Mic", 0x0 },
16729 { "Front Mic", 0x1 },
16730 { "Line", 0x2 },
16734 #if 0 /* set to 1 for testing other input sources below */
16735 static struct hda_input_mux alc272_nc10_capture_source = {
16736 .num_items = 16,
16737 .items = {
16738 { "Autoselect Mic", 0x0 },
16739 { "Internal Mic", 0x1 },
16740 { "In-0x02", 0x2 },
16741 { "In-0x03", 0x3 },
16742 { "In-0x04", 0x4 },
16743 { "In-0x05", 0x5 },
16744 { "In-0x06", 0x6 },
16745 { "In-0x07", 0x7 },
16746 { "In-0x08", 0x8 },
16747 { "In-0x09", 0x9 },
16748 { "In-0x0a", 0x0a },
16749 { "In-0x0b", 0x0b },
16750 { "In-0x0c", 0x0c },
16751 { "In-0x0d", 0x0d },
16752 { "In-0x0e", 0x0e },
16753 { "In-0x0f", 0x0f },
16756 #endif
16759 * 2ch mode
16761 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16762 { 2, NULL }
16766 * 2ch mode
16768 static struct hda_verb alc662_3ST_ch2_init[] = {
16769 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16770 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16771 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16772 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16773 { } /* end */
16777 * 6ch mode
16779 static struct hda_verb alc662_3ST_ch6_init[] = {
16780 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16781 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16782 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16783 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16784 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16785 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16786 { } /* end */
16789 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16790 { 2, alc662_3ST_ch2_init },
16791 { 6, alc662_3ST_ch6_init },
16795 * 2ch mode
16797 static struct hda_verb alc662_sixstack_ch6_init[] = {
16798 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16799 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16800 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16801 { } /* end */
16805 * 6ch mode
16807 static struct hda_verb alc662_sixstack_ch8_init[] = {
16808 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16809 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16810 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16811 { } /* end */
16814 static struct hda_channel_mode alc662_5stack_modes[2] = {
16815 { 2, alc662_sixstack_ch6_init },
16816 { 6, alc662_sixstack_ch8_init },
16819 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16820 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16823 static struct snd_kcontrol_new alc662_base_mixer[] = {
16824 /* output mixer control */
16825 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16826 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16827 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16828 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16829 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16830 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16831 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16832 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16835 /*Input mixer control */
16836 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16837 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16838 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16839 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16840 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16841 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16842 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16843 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16844 { } /* end */
16847 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16848 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16849 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16850 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16851 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16852 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16853 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16854 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16857 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16859 { } /* end */
16862 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16863 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16864 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16865 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16866 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16867 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16868 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16869 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16870 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16871 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16872 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16873 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16874 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16875 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16878 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16879 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16880 { } /* end */
16883 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16884 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16885 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
16886 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16887 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
16888 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16889 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16890 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16891 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16892 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16893 { } /* end */
16896 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
16897 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16898 ALC262_HIPPO_MASTER_SWITCH,
16900 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16901 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16902 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16904 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16905 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16906 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16907 { } /* end */
16910 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
16911 ALC262_HIPPO_MASTER_SWITCH,
16912 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16913 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16916 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16917 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16918 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16921 { } /* end */
16924 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16925 .ops = &snd_hda_bind_vol,
16926 .values = {
16927 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16928 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16933 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16934 .ops = &snd_hda_bind_sw,
16935 .values = {
16936 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16937 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16942 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
16943 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16944 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16945 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16946 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16947 { } /* end */
16950 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16951 .ops = &snd_hda_bind_sw,
16952 .values = {
16953 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16954 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16955 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16960 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16961 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16962 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16965 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16966 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16968 { } /* end */
16971 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16972 .ops = &snd_hda_bind_sw,
16973 .values = {
16974 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16975 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16976 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16981 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16982 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16983 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16986 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16987 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16988 { } /* end */
16991 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
16992 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16993 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16994 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16997 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16998 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16999 { } /* end */
17002 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17003 .ops = &snd_hda_bind_vol,
17004 .values = {
17005 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17006 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17011 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17012 .ops = &snd_hda_bind_sw,
17013 .values = {
17014 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17015 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17020 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17021 HDA_BIND_VOL("Master Playback Volume",
17022 &alc663_asus_two_bind_master_vol),
17023 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17024 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17026 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17028 { } /* end */
17031 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17032 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17033 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17034 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17038 { } /* end */
17041 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17042 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17043 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17044 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17045 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17050 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17051 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17052 { } /* end */
17055 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17056 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17057 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17058 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17060 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17061 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17062 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17063 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17064 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17065 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17066 { } /* end */
17069 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17070 .ops = &snd_hda_bind_sw,
17071 .values = {
17072 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17073 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17074 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17075 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17076 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17081 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17082 .ops = &snd_hda_bind_sw,
17083 .values = {
17084 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17085 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17090 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17091 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17092 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17093 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17094 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17095 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17096 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17097 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17100 { } /* end */
17103 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17104 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17105 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17106 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17107 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17108 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17109 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17111 { } /* end */
17115 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17118 .name = "Channel Mode",
17119 .info = alc_ch_mode_info,
17120 .get = alc_ch_mode_get,
17121 .put = alc_ch_mode_put,
17123 { } /* end */
17126 static struct hda_verb alc662_init_verbs[] = {
17127 /* ADC: mute amp left and right */
17128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17129 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17132 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17133 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17134 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17135 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17136 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17138 /* Front Pin: output 0 (0x0c) */
17139 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17140 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17142 /* Rear Pin: output 1 (0x0d) */
17143 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17144 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17146 /* CLFE Pin: output 2 (0x0e) */
17147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17148 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17150 /* Mic (rear) pin: input vref at 80% */
17151 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17153 /* Front Mic pin: input vref at 80% */
17154 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17155 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17156 /* Line In pin: input */
17157 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17158 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17159 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17160 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17161 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17163 /* CD pin widget for input */
17164 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17166 /* FIXME: use matrix-type input source selection */
17167 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17168 /* Input mixer */
17169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17170 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17172 /* always trun on EAPD */
17173 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17174 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17179 static struct hda_verb alc663_init_verbs[] = {
17180 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17181 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17182 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17183 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17184 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17185 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17189 static struct hda_verb alc272_init_verbs[] = {
17190 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17191 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17192 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17194 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17195 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17196 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17197 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17201 static struct hda_verb alc662_sue_init_verbs[] = {
17202 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17203 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17207 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17208 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17209 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17213 /* Set Unsolicited Event*/
17214 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17216 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17220 static struct hda_verb alc663_m51va_init_verbs[] = {
17221 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17222 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17223 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17224 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17225 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17226 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17228 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17229 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17233 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17234 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17235 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17236 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17237 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17238 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17239 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17240 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17244 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17245 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17248 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17249 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17251 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17252 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17256 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17262 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17267 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17268 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17269 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17270 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17271 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17273 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17274 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17277 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17278 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17283 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17284 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17286 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17287 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17290 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17294 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17295 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17299 static struct hda_verb alc663_g71v_init_verbs[] = {
17300 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17301 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17302 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17304 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17305 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17306 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17308 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17309 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17310 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17314 static struct hda_verb alc663_g50v_init_verbs[] = {
17315 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17316 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17317 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17319 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17320 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17324 static struct hda_verb alc662_ecs_init_verbs[] = {
17325 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17327 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17328 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17332 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17334 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17337 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17338 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17339 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17343 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17347 static struct hda_verb alc272_dell_init_verbs[] = {
17348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17349 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17350 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17351 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17352 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17353 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17354 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17355 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17357 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17358 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17362 static struct hda_verb alc663_mode7_init_verbs[] = {
17363 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17364 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17365 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17366 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17370 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17371 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17372 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17375 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17377 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17381 static struct hda_verb alc663_mode8_init_verbs[] = {
17382 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17387 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17388 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17389 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17390 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17391 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17392 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17393 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17394 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17395 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17396 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17397 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17401 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17402 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17403 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17404 { } /* end */
17407 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17408 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17409 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17410 { } /* end */
17413 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17415 unsigned int present;
17416 unsigned char bits;
17418 present = snd_hda_jack_detect(codec, 0x14);
17419 bits = present ? HDA_AMP_MUTE : 0;
17421 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17422 HDA_AMP_MUTE, bits);
17425 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17427 unsigned int present;
17428 unsigned char bits;
17430 present = snd_hda_jack_detect(codec, 0x1b);
17431 bits = present ? HDA_AMP_MUTE : 0;
17433 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17434 HDA_AMP_MUTE, bits);
17435 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17436 HDA_AMP_MUTE, bits);
17439 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17440 unsigned int res)
17442 if ((res >> 26) == ALC880_HP_EVENT)
17443 alc662_lenovo_101e_all_automute(codec);
17444 if ((res >> 26) == ALC880_FRONT_EVENT)
17445 alc662_lenovo_101e_ispeaker_automute(codec);
17448 /* unsolicited event for HP jack sensing */
17449 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17450 unsigned int res)
17452 if ((res >> 26) == ALC880_MIC_EVENT)
17453 alc_mic_automute(codec);
17454 else
17455 alc262_hippo_unsol_event(codec, res);
17458 static void alc662_eeepc_setup(struct hda_codec *codec)
17460 struct alc_spec *spec = codec->spec;
17462 alc262_hippo1_setup(codec);
17463 spec->ext_mic.pin = 0x18;
17464 spec->ext_mic.mux_idx = 0;
17465 spec->int_mic.pin = 0x19;
17466 spec->int_mic.mux_idx = 1;
17467 spec->auto_mic = 1;
17470 static void alc662_eeepc_inithook(struct hda_codec *codec)
17472 alc262_hippo_automute(codec);
17473 alc_mic_automute(codec);
17476 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17478 struct alc_spec *spec = codec->spec;
17480 spec->autocfg.hp_pins[0] = 0x14;
17481 spec->autocfg.speaker_pins[0] = 0x1b;
17484 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17486 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17488 unsigned int present;
17489 unsigned char bits;
17491 present = snd_hda_jack_detect(codec, 0x21);
17492 bits = present ? HDA_AMP_MUTE : 0;
17493 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17494 HDA_AMP_MUTE, bits);
17495 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17496 HDA_AMP_MUTE, bits);
17499 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17501 unsigned int present;
17502 unsigned char bits;
17504 present = snd_hda_jack_detect(codec, 0x21);
17505 bits = present ? HDA_AMP_MUTE : 0;
17506 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17507 HDA_AMP_MUTE, bits);
17508 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17509 HDA_AMP_MUTE, bits);
17510 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17511 HDA_AMP_MUTE, bits);
17512 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17513 HDA_AMP_MUTE, bits);
17516 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17518 unsigned int present;
17519 unsigned char bits;
17521 present = snd_hda_jack_detect(codec, 0x15);
17522 bits = present ? HDA_AMP_MUTE : 0;
17523 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17524 HDA_AMP_MUTE, bits);
17525 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17526 HDA_AMP_MUTE, bits);
17527 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17528 HDA_AMP_MUTE, bits);
17529 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17530 HDA_AMP_MUTE, bits);
17533 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17535 unsigned int present;
17536 unsigned char bits;
17538 present = snd_hda_jack_detect(codec, 0x1b);
17539 bits = present ? 0 : PIN_OUT;
17540 snd_hda_codec_write(codec, 0x14, 0,
17541 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17544 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17546 unsigned int present1, present2;
17548 present1 = snd_hda_jack_detect(codec, 0x21);
17549 present2 = snd_hda_jack_detect(codec, 0x15);
17551 if (present1 || present2) {
17552 snd_hda_codec_write_cache(codec, 0x14, 0,
17553 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17554 } else {
17555 snd_hda_codec_write_cache(codec, 0x14, 0,
17556 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17560 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17562 unsigned int present1, present2;
17564 present1 = snd_hda_jack_detect(codec, 0x1b);
17565 present2 = snd_hda_jack_detect(codec, 0x15);
17567 if (present1 || present2) {
17568 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17569 HDA_AMP_MUTE, HDA_AMP_MUTE);
17570 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17571 HDA_AMP_MUTE, HDA_AMP_MUTE);
17572 } else {
17573 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17574 HDA_AMP_MUTE, 0);
17575 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17576 HDA_AMP_MUTE, 0);
17580 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17582 unsigned int present1, present2;
17584 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17585 AC_VERB_GET_PIN_SENSE, 0)
17586 & AC_PINSENSE_PRESENCE;
17587 present2 = snd_hda_codec_read(codec, 0x21, 0,
17588 AC_VERB_GET_PIN_SENSE, 0)
17589 & AC_PINSENSE_PRESENCE;
17591 if (present1 || present2) {
17592 snd_hda_codec_write_cache(codec, 0x14, 0,
17593 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17594 snd_hda_codec_write_cache(codec, 0x17, 0,
17595 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17596 } else {
17597 snd_hda_codec_write_cache(codec, 0x14, 0,
17598 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17599 snd_hda_codec_write_cache(codec, 0x17, 0,
17600 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17604 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17606 unsigned int present1, present2;
17608 present1 = snd_hda_codec_read(codec, 0x21, 0,
17609 AC_VERB_GET_PIN_SENSE, 0)
17610 & AC_PINSENSE_PRESENCE;
17611 present2 = snd_hda_codec_read(codec, 0x15, 0,
17612 AC_VERB_GET_PIN_SENSE, 0)
17613 & AC_PINSENSE_PRESENCE;
17615 if (present1 || present2) {
17616 snd_hda_codec_write_cache(codec, 0x14, 0,
17617 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17618 snd_hda_codec_write_cache(codec, 0x17, 0,
17619 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17620 } else {
17621 snd_hda_codec_write_cache(codec, 0x14, 0,
17622 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17623 snd_hda_codec_write_cache(codec, 0x17, 0,
17624 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17628 static void alc663_m51va_unsol_event(struct hda_codec *codec,
17629 unsigned int res)
17631 switch (res >> 26) {
17632 case ALC880_HP_EVENT:
17633 alc663_m51va_speaker_automute(codec);
17634 break;
17635 case ALC880_MIC_EVENT:
17636 alc_mic_automute(codec);
17637 break;
17641 static void alc663_m51va_setup(struct hda_codec *codec)
17643 struct alc_spec *spec = codec->spec;
17644 spec->ext_mic.pin = 0x18;
17645 spec->ext_mic.mux_idx = 0;
17646 spec->int_mic.pin = 0x12;
17647 spec->int_mic.mux_idx = 9;
17648 spec->auto_mic = 1;
17651 static void alc663_m51va_inithook(struct hda_codec *codec)
17653 alc663_m51va_speaker_automute(codec);
17654 alc_mic_automute(codec);
17657 /* ***************** Mode1 ******************************/
17658 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
17660 static void alc663_mode1_setup(struct hda_codec *codec)
17662 struct alc_spec *spec = codec->spec;
17663 spec->ext_mic.pin = 0x18;
17664 spec->ext_mic.mux_idx = 0;
17665 spec->int_mic.pin = 0x19;
17666 spec->int_mic.mux_idx = 1;
17667 spec->auto_mic = 1;
17670 #define alc663_mode1_inithook alc663_m51va_inithook
17672 /* ***************** Mode2 ******************************/
17673 static void alc662_mode2_unsol_event(struct hda_codec *codec,
17674 unsigned int res)
17676 switch (res >> 26) {
17677 case ALC880_HP_EVENT:
17678 alc662_f5z_speaker_automute(codec);
17679 break;
17680 case ALC880_MIC_EVENT:
17681 alc_mic_automute(codec);
17682 break;
17686 #define alc662_mode2_setup alc663_mode1_setup
17688 static void alc662_mode2_inithook(struct hda_codec *codec)
17690 alc662_f5z_speaker_automute(codec);
17691 alc_mic_automute(codec);
17693 /* ***************** Mode3 ******************************/
17694 static void alc663_mode3_unsol_event(struct hda_codec *codec,
17695 unsigned int res)
17697 switch (res >> 26) {
17698 case ALC880_HP_EVENT:
17699 alc663_two_hp_m1_speaker_automute(codec);
17700 break;
17701 case ALC880_MIC_EVENT:
17702 alc_mic_automute(codec);
17703 break;
17707 #define alc663_mode3_setup alc663_mode1_setup
17709 static void alc663_mode3_inithook(struct hda_codec *codec)
17711 alc663_two_hp_m1_speaker_automute(codec);
17712 alc_mic_automute(codec);
17714 /* ***************** Mode4 ******************************/
17715 static void alc663_mode4_unsol_event(struct hda_codec *codec,
17716 unsigned int res)
17718 switch (res >> 26) {
17719 case ALC880_HP_EVENT:
17720 alc663_21jd_two_speaker_automute(codec);
17721 break;
17722 case ALC880_MIC_EVENT:
17723 alc_mic_automute(codec);
17724 break;
17728 #define alc663_mode4_setup alc663_mode1_setup
17730 static void alc663_mode4_inithook(struct hda_codec *codec)
17732 alc663_21jd_two_speaker_automute(codec);
17733 alc_mic_automute(codec);
17735 /* ***************** Mode5 ******************************/
17736 static void alc663_mode5_unsol_event(struct hda_codec *codec,
17737 unsigned int res)
17739 switch (res >> 26) {
17740 case ALC880_HP_EVENT:
17741 alc663_15jd_two_speaker_automute(codec);
17742 break;
17743 case ALC880_MIC_EVENT:
17744 alc_mic_automute(codec);
17745 break;
17749 #define alc663_mode5_setup alc663_mode1_setup
17751 static void alc663_mode5_inithook(struct hda_codec *codec)
17753 alc663_15jd_two_speaker_automute(codec);
17754 alc_mic_automute(codec);
17756 /* ***************** Mode6 ******************************/
17757 static void alc663_mode6_unsol_event(struct hda_codec *codec,
17758 unsigned int res)
17760 switch (res >> 26) {
17761 case ALC880_HP_EVENT:
17762 alc663_two_hp_m2_speaker_automute(codec);
17763 break;
17764 case ALC880_MIC_EVENT:
17765 alc_mic_automute(codec);
17766 break;
17770 #define alc663_mode6_setup alc663_mode1_setup
17772 static void alc663_mode6_inithook(struct hda_codec *codec)
17774 alc663_two_hp_m2_speaker_automute(codec);
17775 alc_mic_automute(codec);
17778 /* ***************** Mode7 ******************************/
17779 static void alc663_mode7_unsol_event(struct hda_codec *codec,
17780 unsigned int res)
17782 switch (res >> 26) {
17783 case ALC880_HP_EVENT:
17784 alc663_two_hp_m7_speaker_automute(codec);
17785 break;
17786 case ALC880_MIC_EVENT:
17787 alc_mic_automute(codec);
17788 break;
17792 #define alc663_mode7_setup alc663_mode1_setup
17794 static void alc663_mode7_inithook(struct hda_codec *codec)
17796 alc663_two_hp_m7_speaker_automute(codec);
17797 alc_mic_automute(codec);
17800 /* ***************** Mode8 ******************************/
17801 static void alc663_mode8_unsol_event(struct hda_codec *codec,
17802 unsigned int res)
17804 switch (res >> 26) {
17805 case ALC880_HP_EVENT:
17806 alc663_two_hp_m8_speaker_automute(codec);
17807 break;
17808 case ALC880_MIC_EVENT:
17809 alc_mic_automute(codec);
17810 break;
17814 #define alc663_mode8_setup alc663_m51va_setup
17816 static void alc663_mode8_inithook(struct hda_codec *codec)
17818 alc663_two_hp_m8_speaker_automute(codec);
17819 alc_mic_automute(codec);
17822 static void alc663_g71v_hp_automute(struct hda_codec *codec)
17824 unsigned int present;
17825 unsigned char bits;
17827 present = snd_hda_jack_detect(codec, 0x21);
17828 bits = present ? HDA_AMP_MUTE : 0;
17829 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17830 HDA_AMP_MUTE, bits);
17831 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17832 HDA_AMP_MUTE, bits);
17835 static void alc663_g71v_front_automute(struct hda_codec *codec)
17837 unsigned int present;
17838 unsigned char bits;
17840 present = snd_hda_jack_detect(codec, 0x15);
17841 bits = present ? HDA_AMP_MUTE : 0;
17842 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17843 HDA_AMP_MUTE, bits);
17846 static void alc663_g71v_unsol_event(struct hda_codec *codec,
17847 unsigned int res)
17849 switch (res >> 26) {
17850 case ALC880_HP_EVENT:
17851 alc663_g71v_hp_automute(codec);
17852 break;
17853 case ALC880_FRONT_EVENT:
17854 alc663_g71v_front_automute(codec);
17855 break;
17856 case ALC880_MIC_EVENT:
17857 alc_mic_automute(codec);
17858 break;
17862 #define alc663_g71v_setup alc663_m51va_setup
17864 static void alc663_g71v_inithook(struct hda_codec *codec)
17866 alc663_g71v_front_automute(codec);
17867 alc663_g71v_hp_automute(codec);
17868 alc_mic_automute(codec);
17871 static void alc663_g50v_unsol_event(struct hda_codec *codec,
17872 unsigned int res)
17874 switch (res >> 26) {
17875 case ALC880_HP_EVENT:
17876 alc663_m51va_speaker_automute(codec);
17877 break;
17878 case ALC880_MIC_EVENT:
17879 alc_mic_automute(codec);
17880 break;
17884 #define alc663_g50v_setup alc663_m51va_setup
17886 static void alc663_g50v_inithook(struct hda_codec *codec)
17888 alc663_m51va_speaker_automute(codec);
17889 alc_mic_automute(codec);
17892 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17893 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17894 ALC262_HIPPO_MASTER_SWITCH,
17896 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17897 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17900 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17901 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17902 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17903 { } /* end */
17906 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17907 /* Master Playback automatically created from Speaker and Headphone */
17908 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17910 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17913 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17914 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17915 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17917 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17918 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17919 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17920 { } /* end */
17923 #ifdef CONFIG_SND_HDA_POWER_SAVE
17924 #define alc662_loopbacks alc880_loopbacks
17925 #endif
17928 /* pcm configuration: identical with ALC880 */
17929 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
17930 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
17931 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
17932 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
17935 * configuration and preset
17937 static const char *alc662_models[ALC662_MODEL_LAST] = {
17938 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17939 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17940 [ALC662_3ST_6ch] = "3stack-6ch",
17941 [ALC662_5ST_DIG] = "6stack-dig",
17942 [ALC662_LENOVO_101E] = "lenovo-101e",
17943 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17944 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17945 [ALC662_ECS] = "ecs",
17946 [ALC663_ASUS_M51VA] = "m51va",
17947 [ALC663_ASUS_G71V] = "g71v",
17948 [ALC663_ASUS_H13] = "h13",
17949 [ALC663_ASUS_G50V] = "g50v",
17950 [ALC663_ASUS_MODE1] = "asus-mode1",
17951 [ALC662_ASUS_MODE2] = "asus-mode2",
17952 [ALC663_ASUS_MODE3] = "asus-mode3",
17953 [ALC663_ASUS_MODE4] = "asus-mode4",
17954 [ALC663_ASUS_MODE5] = "asus-mode5",
17955 [ALC663_ASUS_MODE6] = "asus-mode6",
17956 [ALC663_ASUS_MODE7] = "asus-mode7",
17957 [ALC663_ASUS_MODE8] = "asus-mode8",
17958 [ALC272_DELL] = "dell",
17959 [ALC272_DELL_ZM1] = "dell-zm1",
17960 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17961 [ALC662_AUTO] = "auto",
17964 static struct snd_pci_quirk alc662_cfg_tbl[] = {
17965 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17966 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17967 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17968 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17969 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17970 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17971 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17972 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17973 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17974 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17975 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17976 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17977 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17978 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17979 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17980 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17981 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17982 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17983 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17984 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17985 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17986 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17987 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17988 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17989 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17990 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17991 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17992 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17993 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17994 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17995 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17996 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17997 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17998 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17999 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18000 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18001 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18002 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18003 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18004 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18005 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18006 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18007 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18008 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18009 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18010 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18011 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18012 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18013 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18014 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18015 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18016 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18017 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18018 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18019 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18020 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18021 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18022 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18023 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18024 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18025 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18026 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18027 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18028 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18029 ALC662_3ST_6ch_DIG),
18030 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18031 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18032 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18033 ALC662_3ST_6ch_DIG),
18034 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18035 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18036 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18037 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18038 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18039 ALC662_3ST_6ch_DIG),
18040 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18041 ALC663_ASUS_H13),
18045 static struct alc_config_preset alc662_presets[] = {
18046 [ALC662_3ST_2ch_DIG] = {
18047 .mixers = { alc662_3ST_2ch_mixer },
18048 .init_verbs = { alc662_init_verbs },
18049 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18050 .dac_nids = alc662_dac_nids,
18051 .dig_out_nid = ALC662_DIGOUT_NID,
18052 .dig_in_nid = ALC662_DIGIN_NID,
18053 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18054 .channel_mode = alc662_3ST_2ch_modes,
18055 .input_mux = &alc662_capture_source,
18057 [ALC662_3ST_6ch_DIG] = {
18058 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18059 .init_verbs = { alc662_init_verbs },
18060 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18061 .dac_nids = alc662_dac_nids,
18062 .dig_out_nid = ALC662_DIGOUT_NID,
18063 .dig_in_nid = ALC662_DIGIN_NID,
18064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18065 .channel_mode = alc662_3ST_6ch_modes,
18066 .need_dac_fix = 1,
18067 .input_mux = &alc662_capture_source,
18069 [ALC662_3ST_6ch] = {
18070 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18071 .init_verbs = { alc662_init_verbs },
18072 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18073 .dac_nids = alc662_dac_nids,
18074 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18075 .channel_mode = alc662_3ST_6ch_modes,
18076 .need_dac_fix = 1,
18077 .input_mux = &alc662_capture_source,
18079 [ALC662_5ST_DIG] = {
18080 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18081 .init_verbs = { alc662_init_verbs },
18082 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18083 .dac_nids = alc662_dac_nids,
18084 .dig_out_nid = ALC662_DIGOUT_NID,
18085 .dig_in_nid = ALC662_DIGIN_NID,
18086 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18087 .channel_mode = alc662_5stack_modes,
18088 .input_mux = &alc662_capture_source,
18090 [ALC662_LENOVO_101E] = {
18091 .mixers = { alc662_lenovo_101e_mixer },
18092 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18093 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18094 .dac_nids = alc662_dac_nids,
18095 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18096 .channel_mode = alc662_3ST_2ch_modes,
18097 .input_mux = &alc662_lenovo_101e_capture_source,
18098 .unsol_event = alc662_lenovo_101e_unsol_event,
18099 .init_hook = alc662_lenovo_101e_all_automute,
18101 [ALC662_ASUS_EEEPC_P701] = {
18102 .mixers = { alc662_eeepc_p701_mixer },
18103 .init_verbs = { alc662_init_verbs,
18104 alc662_eeepc_sue_init_verbs },
18105 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18106 .dac_nids = alc662_dac_nids,
18107 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18108 .channel_mode = alc662_3ST_2ch_modes,
18109 .unsol_event = alc662_eeepc_unsol_event,
18110 .setup = alc662_eeepc_setup,
18111 .init_hook = alc662_eeepc_inithook,
18113 [ALC662_ASUS_EEEPC_EP20] = {
18114 .mixers = { alc662_eeepc_ep20_mixer,
18115 alc662_chmode_mixer },
18116 .init_verbs = { alc662_init_verbs,
18117 alc662_eeepc_ep20_sue_init_verbs },
18118 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18119 .dac_nids = alc662_dac_nids,
18120 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18121 .channel_mode = alc662_3ST_6ch_modes,
18122 .input_mux = &alc662_lenovo_101e_capture_source,
18123 .unsol_event = alc662_eeepc_unsol_event,
18124 .setup = alc662_eeepc_ep20_setup,
18125 .init_hook = alc662_eeepc_ep20_inithook,
18127 [ALC662_ECS] = {
18128 .mixers = { alc662_ecs_mixer },
18129 .init_verbs = { alc662_init_verbs,
18130 alc662_ecs_init_verbs },
18131 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18132 .dac_nids = alc662_dac_nids,
18133 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18134 .channel_mode = alc662_3ST_2ch_modes,
18135 .unsol_event = alc662_eeepc_unsol_event,
18136 .setup = alc662_eeepc_setup,
18137 .init_hook = alc662_eeepc_inithook,
18139 [ALC663_ASUS_M51VA] = {
18140 .mixers = { alc663_m51va_mixer },
18141 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18142 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18143 .dac_nids = alc662_dac_nids,
18144 .dig_out_nid = ALC662_DIGOUT_NID,
18145 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18146 .channel_mode = alc662_3ST_2ch_modes,
18147 .unsol_event = alc663_m51va_unsol_event,
18148 .setup = alc663_m51va_setup,
18149 .init_hook = alc663_m51va_inithook,
18151 [ALC663_ASUS_G71V] = {
18152 .mixers = { alc663_g71v_mixer },
18153 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18154 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18155 .dac_nids = alc662_dac_nids,
18156 .dig_out_nid = ALC662_DIGOUT_NID,
18157 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18158 .channel_mode = alc662_3ST_2ch_modes,
18159 .unsol_event = alc663_g71v_unsol_event,
18160 .setup = alc663_g71v_setup,
18161 .init_hook = alc663_g71v_inithook,
18163 [ALC663_ASUS_H13] = {
18164 .mixers = { alc663_m51va_mixer },
18165 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18166 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18167 .dac_nids = alc662_dac_nids,
18168 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18169 .channel_mode = alc662_3ST_2ch_modes,
18170 .unsol_event = alc663_m51va_unsol_event,
18171 .init_hook = alc663_m51va_inithook,
18173 [ALC663_ASUS_G50V] = {
18174 .mixers = { alc663_g50v_mixer },
18175 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18176 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18177 .dac_nids = alc662_dac_nids,
18178 .dig_out_nid = ALC662_DIGOUT_NID,
18179 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18180 .channel_mode = alc662_3ST_6ch_modes,
18181 .input_mux = &alc663_capture_source,
18182 .unsol_event = alc663_g50v_unsol_event,
18183 .setup = alc663_g50v_setup,
18184 .init_hook = alc663_g50v_inithook,
18186 [ALC663_ASUS_MODE1] = {
18187 .mixers = { alc663_m51va_mixer },
18188 .cap_mixer = alc662_auto_capture_mixer,
18189 .init_verbs = { alc662_init_verbs,
18190 alc663_21jd_amic_init_verbs },
18191 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18192 .hp_nid = 0x03,
18193 .dac_nids = alc662_dac_nids,
18194 .dig_out_nid = ALC662_DIGOUT_NID,
18195 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18196 .channel_mode = alc662_3ST_2ch_modes,
18197 .unsol_event = alc663_mode1_unsol_event,
18198 .setup = alc663_mode1_setup,
18199 .init_hook = alc663_mode1_inithook,
18201 [ALC662_ASUS_MODE2] = {
18202 .mixers = { alc662_1bjd_mixer },
18203 .cap_mixer = alc662_auto_capture_mixer,
18204 .init_verbs = { alc662_init_verbs,
18205 alc662_1bjd_amic_init_verbs },
18206 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18207 .dac_nids = alc662_dac_nids,
18208 .dig_out_nid = ALC662_DIGOUT_NID,
18209 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18210 .channel_mode = alc662_3ST_2ch_modes,
18211 .unsol_event = alc662_mode2_unsol_event,
18212 .setup = alc662_mode2_setup,
18213 .init_hook = alc662_mode2_inithook,
18215 [ALC663_ASUS_MODE3] = {
18216 .mixers = { alc663_two_hp_m1_mixer },
18217 .cap_mixer = alc662_auto_capture_mixer,
18218 .init_verbs = { alc662_init_verbs,
18219 alc663_two_hp_amic_m1_init_verbs },
18220 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18221 .hp_nid = 0x03,
18222 .dac_nids = alc662_dac_nids,
18223 .dig_out_nid = ALC662_DIGOUT_NID,
18224 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18225 .channel_mode = alc662_3ST_2ch_modes,
18226 .unsol_event = alc663_mode3_unsol_event,
18227 .setup = alc663_mode3_setup,
18228 .init_hook = alc663_mode3_inithook,
18230 [ALC663_ASUS_MODE4] = {
18231 .mixers = { alc663_asus_21jd_clfe_mixer },
18232 .cap_mixer = alc662_auto_capture_mixer,
18233 .init_verbs = { alc662_init_verbs,
18234 alc663_21jd_amic_init_verbs},
18235 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18236 .hp_nid = 0x03,
18237 .dac_nids = alc662_dac_nids,
18238 .dig_out_nid = ALC662_DIGOUT_NID,
18239 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18240 .channel_mode = alc662_3ST_2ch_modes,
18241 .unsol_event = alc663_mode4_unsol_event,
18242 .setup = alc663_mode4_setup,
18243 .init_hook = alc663_mode4_inithook,
18245 [ALC663_ASUS_MODE5] = {
18246 .mixers = { alc663_asus_15jd_clfe_mixer },
18247 .cap_mixer = alc662_auto_capture_mixer,
18248 .init_verbs = { alc662_init_verbs,
18249 alc663_15jd_amic_init_verbs },
18250 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18251 .hp_nid = 0x03,
18252 .dac_nids = alc662_dac_nids,
18253 .dig_out_nid = ALC662_DIGOUT_NID,
18254 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18255 .channel_mode = alc662_3ST_2ch_modes,
18256 .unsol_event = alc663_mode5_unsol_event,
18257 .setup = alc663_mode5_setup,
18258 .init_hook = alc663_mode5_inithook,
18260 [ALC663_ASUS_MODE6] = {
18261 .mixers = { alc663_two_hp_m2_mixer },
18262 .cap_mixer = alc662_auto_capture_mixer,
18263 .init_verbs = { alc662_init_verbs,
18264 alc663_two_hp_amic_m2_init_verbs },
18265 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18266 .hp_nid = 0x03,
18267 .dac_nids = alc662_dac_nids,
18268 .dig_out_nid = ALC662_DIGOUT_NID,
18269 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18270 .channel_mode = alc662_3ST_2ch_modes,
18271 .unsol_event = alc663_mode6_unsol_event,
18272 .setup = alc663_mode6_setup,
18273 .init_hook = alc663_mode6_inithook,
18275 [ALC663_ASUS_MODE7] = {
18276 .mixers = { alc663_mode7_mixer },
18277 .cap_mixer = alc662_auto_capture_mixer,
18278 .init_verbs = { alc662_init_verbs,
18279 alc663_mode7_init_verbs },
18280 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18281 .hp_nid = 0x03,
18282 .dac_nids = alc662_dac_nids,
18283 .dig_out_nid = ALC662_DIGOUT_NID,
18284 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18285 .channel_mode = alc662_3ST_2ch_modes,
18286 .unsol_event = alc663_mode7_unsol_event,
18287 .setup = alc663_mode7_setup,
18288 .init_hook = alc663_mode7_inithook,
18290 [ALC663_ASUS_MODE8] = {
18291 .mixers = { alc663_mode8_mixer },
18292 .cap_mixer = alc662_auto_capture_mixer,
18293 .init_verbs = { alc662_init_verbs,
18294 alc663_mode8_init_verbs },
18295 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18296 .hp_nid = 0x03,
18297 .dac_nids = alc662_dac_nids,
18298 .dig_out_nid = ALC662_DIGOUT_NID,
18299 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18300 .channel_mode = alc662_3ST_2ch_modes,
18301 .unsol_event = alc663_mode8_unsol_event,
18302 .setup = alc663_mode8_setup,
18303 .init_hook = alc663_mode8_inithook,
18305 [ALC272_DELL] = {
18306 .mixers = { alc663_m51va_mixer },
18307 .cap_mixer = alc272_auto_capture_mixer,
18308 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18309 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18310 .dac_nids = alc662_dac_nids,
18311 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18312 .adc_nids = alc272_adc_nids,
18313 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18314 .capsrc_nids = alc272_capsrc_nids,
18315 .channel_mode = alc662_3ST_2ch_modes,
18316 .unsol_event = alc663_m51va_unsol_event,
18317 .setup = alc663_m51va_setup,
18318 .init_hook = alc663_m51va_inithook,
18320 [ALC272_DELL_ZM1] = {
18321 .mixers = { alc663_m51va_mixer },
18322 .cap_mixer = alc662_auto_capture_mixer,
18323 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18324 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18325 .dac_nids = alc662_dac_nids,
18326 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18327 .adc_nids = alc662_adc_nids,
18328 .num_adc_nids = 1,
18329 .capsrc_nids = alc662_capsrc_nids,
18330 .channel_mode = alc662_3ST_2ch_modes,
18331 .unsol_event = alc663_m51va_unsol_event,
18332 .setup = alc663_m51va_setup,
18333 .init_hook = alc663_m51va_inithook,
18335 [ALC272_SAMSUNG_NC10] = {
18336 .mixers = { alc272_nc10_mixer },
18337 .init_verbs = { alc662_init_verbs,
18338 alc663_21jd_amic_init_verbs },
18339 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18340 .dac_nids = alc272_dac_nids,
18341 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18342 .channel_mode = alc662_3ST_2ch_modes,
18343 /*.input_mux = &alc272_nc10_capture_source,*/
18344 .unsol_event = alc663_mode4_unsol_event,
18345 .setup = alc663_mode4_setup,
18346 .init_hook = alc663_mode4_inithook,
18352 * BIOS auto configuration
18355 /* convert from MIX nid to DAC */
18356 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18358 if (nid == 0x0f)
18359 return 0x02;
18360 else if (nid >= 0x0c && nid <= 0x0e)
18361 return nid - 0x0c + 0x02;
18362 else if (nid == 0x26) /* ALC887-VD has this DAC too */
18363 return 0x25;
18364 else
18365 return 0;
18368 /* get MIX nid connected to the given pin targeted to DAC */
18369 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18370 hda_nid_t dac)
18372 hda_nid_t mix[5];
18373 int i, num;
18375 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18376 for (i = 0; i < num; i++) {
18377 if (alc662_mix_to_dac(mix[i]) == dac)
18378 return mix[i];
18380 return 0;
18383 /* look for an empty DAC slot */
18384 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18386 struct alc_spec *spec = codec->spec;
18387 hda_nid_t srcs[5];
18388 int i, j, num;
18390 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18391 if (num < 0)
18392 return 0;
18393 for (i = 0; i < num; i++) {
18394 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18395 if (!nid)
18396 continue;
18397 for (j = 0; j < spec->multiout.num_dacs; j++)
18398 if (spec->multiout.dac_nids[j] == nid)
18399 break;
18400 if (j >= spec->multiout.num_dacs)
18401 return nid;
18403 return 0;
18406 /* fill in the dac_nids table from the parsed pin configuration */
18407 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18408 const struct auto_pin_cfg *cfg)
18410 struct alc_spec *spec = codec->spec;
18411 int i;
18412 hda_nid_t dac;
18414 spec->multiout.dac_nids = spec->private_dac_nids;
18415 for (i = 0; i < cfg->line_outs; i++) {
18416 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18417 if (!dac)
18418 continue;
18419 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18421 return 0;
18424 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18425 hda_nid_t nid, unsigned int chs)
18427 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
18428 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18431 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18432 hda_nid_t nid, unsigned int chs)
18434 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18435 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18438 #define alc662_add_stereo_vol(spec, pfx, nid) \
18439 alc662_add_vol_ctl(spec, pfx, nid, 3)
18440 #define alc662_add_stereo_sw(spec, pfx, nid) \
18441 alc662_add_sw_ctl(spec, pfx, nid, 3)
18443 /* add playback controls from the parsed DAC table */
18444 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18445 const struct auto_pin_cfg *cfg)
18447 struct alc_spec *spec = codec->spec;
18448 static const char *chname[4] = {
18449 "Front", "Surround", NULL /*CLFE*/, "Side"
18451 hda_nid_t nid, mix;
18452 int i, err;
18454 for (i = 0; i < cfg->line_outs; i++) {
18455 nid = spec->multiout.dac_nids[i];
18456 if (!nid)
18457 continue;
18458 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18459 if (!mix)
18460 continue;
18461 if (i == 2) {
18462 /* Center/LFE */
18463 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18464 if (err < 0)
18465 return err;
18466 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
18467 if (err < 0)
18468 return err;
18469 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
18470 if (err < 0)
18471 return err;
18472 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
18473 if (err < 0)
18474 return err;
18475 } else {
18476 const char *pfx;
18477 if (cfg->line_outs == 1 &&
18478 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
18479 if (cfg->hp_outs)
18480 pfx = "Speaker";
18481 else
18482 pfx = "PCM";
18483 } else
18484 pfx = chname[i];
18485 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18486 if (err < 0)
18487 return err;
18488 if (cfg->line_outs == 1 &&
18489 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18490 pfx = "Speaker";
18491 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18492 if (err < 0)
18493 return err;
18496 return 0;
18499 /* add playback controls for speaker and HP outputs */
18500 /* return DAC nid if any new DAC is assigned */
18501 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18502 const char *pfx)
18504 struct alc_spec *spec = codec->spec;
18505 hda_nid_t nid, mix;
18506 int err;
18508 if (!pin)
18509 return 0;
18510 nid = alc662_look_for_dac(codec, pin);
18511 if (!nid) {
18512 /* the corresponding DAC is already occupied */
18513 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18514 return 0; /* no way */
18515 /* create a switch only */
18516 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18517 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18520 mix = alc662_dac_to_mix(codec, pin, nid);
18521 if (!mix)
18522 return 0;
18523 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18524 if (err < 0)
18525 return err;
18526 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18527 if (err < 0)
18528 return err;
18529 return nid;
18532 /* create playback/capture controls for input pins */
18533 #define alc662_auto_create_input_ctls \
18534 alc882_auto_create_input_ctls
18536 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18537 hda_nid_t nid, int pin_type,
18538 hda_nid_t dac)
18540 int i, num;
18541 hda_nid_t srcs[4];
18543 alc_set_pin_output(codec, nid, pin_type);
18544 /* need the manual connection? */
18545 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18546 if (num <= 1)
18547 return;
18548 for (i = 0; i < num; i++) {
18549 if (alc662_mix_to_dac(srcs[i]) != dac)
18550 continue;
18551 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18552 return;
18556 static void alc662_auto_init_multi_out(struct hda_codec *codec)
18558 struct alc_spec *spec = codec->spec;
18559 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18560 int i;
18562 for (i = 0; i <= HDA_SIDE; i++) {
18563 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18564 if (nid)
18565 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
18566 spec->multiout.dac_nids[i]);
18570 static void alc662_auto_init_hp_out(struct hda_codec *codec)
18572 struct alc_spec *spec = codec->spec;
18573 hda_nid_t pin;
18575 pin = spec->autocfg.hp_pins[0];
18576 if (pin)
18577 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18578 spec->multiout.hp_nid);
18579 pin = spec->autocfg.speaker_pins[0];
18580 if (pin)
18581 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18582 spec->multiout.extra_out_nid[0]);
18585 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18587 static void alc662_auto_init_analog_input(struct hda_codec *codec)
18589 struct alc_spec *spec = codec->spec;
18590 int i;
18592 for (i = 0; i < AUTO_PIN_LAST; i++) {
18593 hda_nid_t nid = spec->autocfg.input_pins[i];
18594 if (alc_is_input_pin(codec, nid)) {
18595 alc_set_input_pin(codec, nid, i);
18596 if (nid != ALC662_PIN_CD_NID &&
18597 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
18598 snd_hda_codec_write(codec, nid, 0,
18599 AC_VERB_SET_AMP_GAIN_MUTE,
18600 AMP_OUT_MUTE);
18605 #define alc662_auto_init_input_src alc882_auto_init_input_src
18607 static int alc662_parse_auto_config(struct hda_codec *codec)
18609 struct alc_spec *spec = codec->spec;
18610 int err;
18611 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18613 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18614 alc662_ignore);
18615 if (err < 0)
18616 return err;
18617 if (!spec->autocfg.line_outs)
18618 return 0; /* can't find valid BIOS pin config */
18620 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
18621 if (err < 0)
18622 return err;
18623 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
18624 if (err < 0)
18625 return err;
18626 err = alc662_auto_create_extra_out(codec,
18627 spec->autocfg.speaker_pins[0],
18628 "Speaker");
18629 if (err < 0)
18630 return err;
18631 if (err)
18632 spec->multiout.extra_out_nid[0] = err;
18633 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18634 "Headphone");
18635 if (err < 0)
18636 return err;
18637 if (err)
18638 spec->multiout.hp_nid = err;
18639 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
18640 if (err < 0)
18641 return err;
18643 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18645 if (spec->autocfg.dig_outs)
18646 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18648 if (spec->kctls.list)
18649 add_mixer(spec, spec->kctls.list);
18651 spec->num_mux_defs = 1;
18652 spec->input_mux = &spec->private_imux[0];
18654 add_verb(spec, alc662_init_verbs);
18655 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18656 codec->vendor_id == 0x10ec0665)
18657 add_verb(spec, alc663_init_verbs);
18659 if (codec->vendor_id == 0x10ec0272)
18660 add_verb(spec, alc272_init_verbs);
18662 err = alc_auto_add_mic_boost(codec);
18663 if (err < 0)
18664 return err;
18666 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18667 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18668 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18669 else
18670 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18672 return 1;
18675 /* additional initialization for auto-configuration model */
18676 static void alc662_auto_init(struct hda_codec *codec)
18678 struct alc_spec *spec = codec->spec;
18679 alc662_auto_init_multi_out(codec);
18680 alc662_auto_init_hp_out(codec);
18681 alc662_auto_init_analog_input(codec);
18682 alc662_auto_init_input_src(codec);
18683 if (spec->unsol_event)
18684 alc_inithook(codec);
18687 enum {
18688 ALC662_FIXUP_ASPIRE,
18689 ALC662_FIXUP_IDEAPAD,
18692 static const struct alc_fixup alc662_fixups[] = {
18693 [ALC662_FIXUP_ASPIRE] = {
18694 .pins = (const struct alc_pincfg[]) {
18695 { 0x15, 0x99130112 }, /* subwoofer */
18699 [ALC662_FIXUP_IDEAPAD] = {
18700 .pins = (const struct alc_pincfg[]) {
18701 { 0x17, 0x99130112 }, /* subwoofer */
18707 static struct snd_pci_quirk alc662_fixup_tbl[] = {
18708 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
18709 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
18710 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
18711 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
18717 static int patch_alc662(struct hda_codec *codec)
18719 struct alc_spec *spec;
18720 int err, board_config;
18722 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18723 if (!spec)
18724 return -ENOMEM;
18726 codec->spec = spec;
18728 alc_auto_parse_customize_define(codec);
18730 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18732 if (alc_read_coef_idx(codec, 0) == 0x8020)
18733 alc_codec_rename(codec, "ALC661");
18734 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18735 codec->bus->pci->subsystem_vendor == 0x1025 &&
18736 spec->cdefine.platform_type == 1)
18737 alc_codec_rename(codec, "ALC272X");
18739 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18740 alc662_models,
18741 alc662_cfg_tbl);
18742 if (board_config < 0) {
18743 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18744 codec->chip_name);
18745 board_config = ALC662_AUTO;
18748 if (board_config == ALC662_AUTO) {
18749 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1);
18750 /* automatic parse from the BIOS config */
18751 err = alc662_parse_auto_config(codec);
18752 if (err < 0) {
18753 alc_free(codec);
18754 return err;
18755 } else if (!err) {
18756 printk(KERN_INFO
18757 "hda_codec: Cannot set up configuration "
18758 "from BIOS. Using base mode...\n");
18759 board_config = ALC662_3ST_2ch_DIG;
18763 if (has_cdefine_beep(codec)) {
18764 err = snd_hda_attach_beep_device(codec, 0x1);
18765 if (err < 0) {
18766 alc_free(codec);
18767 return err;
18771 if (board_config != ALC662_AUTO)
18772 setup_preset(codec, &alc662_presets[board_config]);
18774 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18775 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18777 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18778 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18780 if (!spec->adc_nids) {
18781 spec->adc_nids = alc662_adc_nids;
18782 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18784 if (!spec->capsrc_nids)
18785 spec->capsrc_nids = alc662_capsrc_nids;
18787 if (!spec->cap_mixer)
18788 set_capture_mixer(codec);
18790 if (has_cdefine_beep(codec)) {
18791 switch (codec->vendor_id) {
18792 case 0x10ec0662:
18793 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18794 break;
18795 case 0x10ec0272:
18796 case 0x10ec0663:
18797 case 0x10ec0665:
18798 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18799 break;
18800 case 0x10ec0273:
18801 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18802 break;
18805 spec->vmaster_nid = 0x02;
18807 codec->patch_ops = alc_patch_ops;
18808 if (board_config == ALC662_AUTO) {
18809 spec->init_hook = alc662_auto_init;
18810 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
18813 #ifdef CONFIG_SND_HDA_POWER_SAVE
18814 if (!spec->loopback.amplist)
18815 spec->loopback.amplist = alc662_loopbacks;
18816 #endif
18818 return 0;
18821 static int patch_alc888(struct hda_codec *codec)
18823 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18824 kfree(codec->chip_name);
18825 if (codec->vendor_id == 0x10ec0887)
18826 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
18827 else
18828 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18829 if (!codec->chip_name) {
18830 alc_free(codec);
18831 return -ENOMEM;
18833 return patch_alc662(codec);
18835 return patch_alc882(codec);
18839 * patch entries
18841 static struct hda_codec_preset snd_hda_preset_realtek[] = {
18842 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
18843 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
18844 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
18845 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
18846 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
18847 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
18848 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
18849 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
18850 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
18851 .patch = patch_alc861 },
18852 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18853 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18854 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
18855 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
18856 .patch = patch_alc882 },
18857 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18858 .patch = patch_alc662 },
18859 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18860 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18861 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18862 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18863 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18864 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
18865 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
18866 .patch = patch_alc882 },
18867 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
18868 .patch = patch_alc882 },
18869 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
18870 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
18871 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
18872 .patch = patch_alc882 },
18873 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
18874 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
18875 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
18876 {} /* terminator */
18879 MODULE_ALIAS("snd-hda-codec-id:10ec*");
18881 MODULE_LICENSE("GPL");
18882 MODULE_DESCRIPTION("Realtek HD-audio codec");
18884 static struct hda_codec_preset_list realtek_list = {
18885 .preset = snd_hda_preset_realtek,
18886 .owner = THIS_MODULE,
18889 static int __init patch_realtek_init(void)
18891 return snd_hda_add_codec_preset(&realtek_list);
18894 static void __exit patch_realtek_exit(void)
18896 snd_hda_delete_codec_preset(&realtek_list);
18899 module_init(patch_realtek_init)
18900 module_exit(patch_realtek_exit)