ALSA: hda - Prefer VREF50 if BIOS sets for Realtek codecs
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / hda / patch_realtek.c
blob4d3a6f05c703712c868f7671bd442687a7611d5f
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 /* ALC680 models */
260 enum {
261 ALC680_BASE,
262 ALC680_AUTO,
263 ALC680_MODEL_LAST,
266 /* for GPIO Poll */
267 #define GPIO_MASK 0x03
269 /* extra amp-initialization sequence types */
270 enum {
271 ALC_INIT_NONE,
272 ALC_INIT_DEFAULT,
273 ALC_INIT_GPIO1,
274 ALC_INIT_GPIO2,
275 ALC_INIT_GPIO3,
278 struct alc_mic_route {
279 hda_nid_t pin;
280 unsigned char mux_idx;
281 unsigned char amix_idx;
284 #define MUX_IDX_UNDEF ((unsigned char)-1)
286 struct alc_customize_define {
287 unsigned int sku_cfg;
288 unsigned char port_connectivity;
289 unsigned char check_sum;
290 unsigned char customization;
291 unsigned char external_amp;
292 unsigned int enable_pcbeep:1;
293 unsigned int platform_type:1;
294 unsigned int swap:1;
295 unsigned int override:1;
298 struct alc_spec {
299 /* codec parameterization */
300 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
301 unsigned int num_mixers;
302 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
303 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
305 const struct hda_verb *init_verbs[10]; /* initialization verbs
306 * don't forget NULL
307 * termination!
309 unsigned int num_init_verbs;
311 char stream_name_analog[32]; /* analog PCM stream */
312 struct hda_pcm_stream *stream_analog_playback;
313 struct hda_pcm_stream *stream_analog_capture;
314 struct hda_pcm_stream *stream_analog_alt_playback;
315 struct hda_pcm_stream *stream_analog_alt_capture;
317 char stream_name_digital[32]; /* digital PCM stream */
318 struct hda_pcm_stream *stream_digital_playback;
319 struct hda_pcm_stream *stream_digital_capture;
321 /* playback */
322 struct hda_multi_out multiout; /* playback set-up
323 * max_channels, dacs must be set
324 * dig_out_nid and hp_nid are optional
326 hda_nid_t alt_dac_nid;
327 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
328 int dig_out_type;
330 /* capture */
331 unsigned int num_adc_nids;
332 hda_nid_t *adc_nids;
333 hda_nid_t *capsrc_nids;
334 hda_nid_t dig_in_nid; /* digital-in NID; optional */
336 /* capture setup for dynamic dual-adc switch */
337 unsigned int cur_adc_idx;
338 hda_nid_t cur_adc;
339 unsigned int cur_adc_stream_tag;
340 unsigned int cur_adc_format;
342 /* capture source */
343 unsigned int num_mux_defs;
344 const struct hda_input_mux *input_mux;
345 unsigned int cur_mux[3];
346 struct alc_mic_route ext_mic;
347 struct alc_mic_route int_mic;
349 /* channel model */
350 const struct hda_channel_mode *channel_mode;
351 int num_channel_mode;
352 int need_dac_fix;
353 int const_channel_count;
354 int ext_channel_count;
356 /* PCM information */
357 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
359 /* dynamic controls, init_verbs and input_mux */
360 struct auto_pin_cfg autocfg;
361 struct alc_customize_define cdefine;
362 struct snd_array kctls;
363 struct hda_input_mux private_imux[3];
364 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
365 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
366 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
368 /* hooks */
369 void (*init_hook)(struct hda_codec *codec);
370 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
371 #ifdef CONFIG_SND_HDA_POWER_SAVE
372 void (*power_hook)(struct hda_codec *codec);
373 #endif
375 /* for pin sensing */
376 unsigned int sense_updated: 1;
377 unsigned int jack_present: 1;
378 unsigned int master_sw: 1;
379 unsigned int auto_mic:1;
381 /* other flags */
382 unsigned int no_analog :1; /* digital I/O only */
383 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
384 int init_amp;
386 /* for virtual master */
387 hda_nid_t vmaster_nid;
388 #ifdef CONFIG_SND_HDA_POWER_SAVE
389 struct hda_loopback_check loopback;
390 #endif
392 /* for PLL fix */
393 hda_nid_t pll_nid;
394 unsigned int pll_coef_idx, pll_coef_bit;
398 * configuration template - to be copied to the spec instance
400 struct alc_config_preset {
401 struct snd_kcontrol_new *mixers[5]; /* should be identical size
402 * with spec
404 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
405 const struct hda_verb *init_verbs[5];
406 unsigned int num_dacs;
407 hda_nid_t *dac_nids;
408 hda_nid_t dig_out_nid; /* optional */
409 hda_nid_t hp_nid; /* optional */
410 hda_nid_t *slave_dig_outs;
411 unsigned int num_adc_nids;
412 hda_nid_t *adc_nids;
413 hda_nid_t *capsrc_nids;
414 hda_nid_t dig_in_nid;
415 unsigned int num_channel_mode;
416 const struct hda_channel_mode *channel_mode;
417 int need_dac_fix;
418 int const_channel_count;
419 unsigned int num_mux_defs;
420 const struct hda_input_mux *input_mux;
421 void (*unsol_event)(struct hda_codec *, unsigned int);
422 void (*setup)(struct hda_codec *);
423 void (*init_hook)(struct hda_codec *);
424 #ifdef CONFIG_SND_HDA_POWER_SAVE
425 struct hda_amp_list *loopbacks;
426 void (*power_hook)(struct hda_codec *codec);
427 #endif
432 * input MUX handling
434 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
435 struct snd_ctl_elem_info *uinfo)
437 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
438 struct alc_spec *spec = codec->spec;
439 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
440 if (mux_idx >= spec->num_mux_defs)
441 mux_idx = 0;
442 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
443 mux_idx = 0;
444 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
447 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
448 struct snd_ctl_elem_value *ucontrol)
450 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
451 struct alc_spec *spec = codec->spec;
452 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
454 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
455 return 0;
458 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
463 const struct hda_input_mux *imux;
464 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
465 unsigned int mux_idx;
466 hda_nid_t nid = spec->capsrc_nids ?
467 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
468 unsigned int type;
470 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
471 imux = &spec->input_mux[mux_idx];
472 if (!imux->num_items && mux_idx > 0)
473 imux = &spec->input_mux[0];
475 type = get_wcaps_type(get_wcaps(codec, nid));
476 if (type == AC_WID_AUD_MIX) {
477 /* Matrix-mixer style (e.g. ALC882) */
478 unsigned int *cur_val = &spec->cur_mux[adc_idx];
479 unsigned int i, idx;
481 idx = ucontrol->value.enumerated.item[0];
482 if (idx >= imux->num_items)
483 idx = imux->num_items - 1;
484 if (*cur_val == idx)
485 return 0;
486 for (i = 0; i < imux->num_items; i++) {
487 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
488 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
489 imux->items[i].index,
490 HDA_AMP_MUTE, v);
492 *cur_val = idx;
493 return 1;
494 } else {
495 /* MUX style (e.g. ALC880) */
496 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
497 &spec->cur_mux[adc_idx]);
502 * channel mode setting
504 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_info *uinfo)
507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct alc_spec *spec = codec->spec;
509 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
510 spec->num_channel_mode);
513 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
514 struct snd_ctl_elem_value *ucontrol)
516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
517 struct alc_spec *spec = codec->spec;
518 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
519 spec->num_channel_mode,
520 spec->ext_channel_count);
523 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_value *ucontrol)
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
528 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
529 spec->num_channel_mode,
530 &spec->ext_channel_count);
531 if (err >= 0 && !spec->const_channel_count) {
532 spec->multiout.max_channels = spec->ext_channel_count;
533 if (spec->need_dac_fix)
534 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
536 return err;
540 * Control the mode of pin widget settings via the mixer. "pc" is used
541 * instead of "%" to avoid consequences of accidently treating the % as
542 * being part of a format specifier. Maximum allowed length of a value is
543 * 63 characters plus NULL terminator.
545 * Note: some retasking pin complexes seem to ignore requests for input
546 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
547 * are requested. Therefore order this list so that this behaviour will not
548 * cause problems when mixer clients move through the enum sequentially.
549 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
550 * March 2006.
552 static char *alc_pin_mode_names[] = {
553 "Mic 50pc bias", "Mic 80pc bias",
554 "Line in", "Line out", "Headphone out",
556 static unsigned char alc_pin_mode_values[] = {
557 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
559 /* The control can present all 5 options, or it can limit the options based
560 * in the pin being assumed to be exclusively an input or an output pin. In
561 * addition, "input" pins may or may not process the mic bias option
562 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
563 * accept requests for bias as of chip versions up to March 2006) and/or
564 * wiring in the computer.
566 #define ALC_PIN_DIR_IN 0x00
567 #define ALC_PIN_DIR_OUT 0x01
568 #define ALC_PIN_DIR_INOUT 0x02
569 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
570 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
572 /* Info about the pin modes supported by the different pin direction modes.
573 * For each direction the minimum and maximum values are given.
575 static signed char alc_pin_mode_dir_info[5][2] = {
576 { 0, 2 }, /* ALC_PIN_DIR_IN */
577 { 3, 4 }, /* ALC_PIN_DIR_OUT */
578 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
579 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
580 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
582 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
583 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
584 #define alc_pin_mode_n_items(_dir) \
585 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
587 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
590 unsigned int item_num = uinfo->value.enumerated.item;
591 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
593 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
594 uinfo->count = 1;
595 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
597 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
598 item_num = alc_pin_mode_min(dir);
599 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
600 return 0;
603 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
604 struct snd_ctl_elem_value *ucontrol)
606 unsigned int i;
607 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
608 hda_nid_t nid = kcontrol->private_value & 0xffff;
609 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
610 long *valp = ucontrol->value.integer.value;
611 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
612 AC_VERB_GET_PIN_WIDGET_CONTROL,
613 0x00);
615 /* Find enumerated value for current pinctl setting */
616 i = alc_pin_mode_min(dir);
617 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
618 i++;
619 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
620 return 0;
623 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
626 signed int change;
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628 hda_nid_t nid = kcontrol->private_value & 0xffff;
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630 long val = *ucontrol->value.integer.value;
631 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
632 AC_VERB_GET_PIN_WIDGET_CONTROL,
633 0x00);
635 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
636 val = alc_pin_mode_min(dir);
638 change = pinctl != alc_pin_mode_values[val];
639 if (change) {
640 /* Set pin mode to that requested */
641 snd_hda_codec_write_cache(codec, nid, 0,
642 AC_VERB_SET_PIN_WIDGET_CONTROL,
643 alc_pin_mode_values[val]);
645 /* Also enable the retasking pin's input/output as required
646 * for the requested pin mode. Enum values of 2 or less are
647 * input modes.
649 * Dynamically switching the input/output buffers probably
650 * reduces noise slightly (particularly on input) so we'll
651 * do it. However, having both input and output buffers
652 * enabled simultaneously doesn't seem to be problematic if
653 * this turns out to be necessary in the future.
655 if (val <= 2) {
656 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
657 HDA_AMP_MUTE, HDA_AMP_MUTE);
658 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
659 HDA_AMP_MUTE, 0);
660 } else {
661 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
662 HDA_AMP_MUTE, HDA_AMP_MUTE);
663 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
664 HDA_AMP_MUTE, 0);
667 return change;
670 #define ALC_PIN_MODE(xname, nid, dir) \
671 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
672 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
673 .info = alc_pin_mode_info, \
674 .get = alc_pin_mode_get, \
675 .put = alc_pin_mode_put, \
676 .private_value = nid | (dir<<16) }
678 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
679 * together using a mask with more than one bit set. This control is
680 * currently used only by the ALC260 test model. At this stage they are not
681 * needed for any "production" models.
683 #ifdef CONFIG_SND_DEBUG
684 #define alc_gpio_data_info snd_ctl_boolean_mono_info
686 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
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 *valp = ucontrol->value.integer.value;
693 unsigned int val = snd_hda_codec_read(codec, nid, 0,
694 AC_VERB_GET_GPIO_DATA, 0x00);
696 *valp = (val & mask) != 0;
697 return 0;
699 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
700 struct snd_ctl_elem_value *ucontrol)
702 signed int change;
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long val = *ucontrol->value.integer.value;
707 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_GPIO_DATA,
709 0x00);
711 /* Set/unset the masked GPIO bit(s) as needed */
712 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
713 if (val == 0)
714 gpio_data &= ~mask;
715 else
716 gpio_data |= mask;
717 snd_hda_codec_write_cache(codec, nid, 0,
718 AC_VERB_SET_GPIO_DATA, gpio_data);
720 return change;
722 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
723 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
724 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
725 .info = alc_gpio_data_info, \
726 .get = alc_gpio_data_get, \
727 .put = alc_gpio_data_put, \
728 .private_value = nid | (mask<<16) }
729 #endif /* CONFIG_SND_DEBUG */
731 /* A switch control to allow the enabling of the digital IO pins on the
732 * ALC260. This is incredibly simplistic; the intention of this control is
733 * to provide something in the test model allowing digital outputs to be
734 * identified if present. If models are found which can utilise these
735 * outputs a more complete mixer control can be devised for those models if
736 * necessary.
738 #ifdef CONFIG_SND_DEBUG
739 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
741 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
742 struct snd_ctl_elem_value *ucontrol)
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 *valp = ucontrol->value.integer.value;
748 unsigned int val = snd_hda_codec_read(codec, nid, 0,
749 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
751 *valp = (val & mask) != 0;
752 return 0;
754 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
755 struct snd_ctl_elem_value *ucontrol)
757 signed int change;
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long val = *ucontrol->value.integer.value;
762 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
763 AC_VERB_GET_DIGI_CONVERT_1,
764 0x00);
766 /* Set/unset the masked control bit(s) as needed */
767 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
768 if (val==0)
769 ctrl_data &= ~mask;
770 else
771 ctrl_data |= mask;
772 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
773 ctrl_data);
775 return change;
777 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
778 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
779 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
780 .info = alc_spdif_ctrl_info, \
781 .get = alc_spdif_ctrl_get, \
782 .put = alc_spdif_ctrl_put, \
783 .private_value = nid | (mask<<16) }
784 #endif /* CONFIG_SND_DEBUG */
786 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
787 * Again, this is only used in the ALC26x test models to help identify when
788 * the EAPD line must be asserted for features to work.
790 #ifdef CONFIG_SND_DEBUG
791 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
793 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long *valp = ucontrol->value.integer.value;
800 unsigned int val = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
803 *valp = (val & mask) != 0;
804 return 0;
807 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
808 struct snd_ctl_elem_value *ucontrol)
810 int change;
811 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
812 hda_nid_t nid = kcontrol->private_value & 0xffff;
813 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
814 long val = *ucontrol->value.integer.value;
815 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
816 AC_VERB_GET_EAPD_BTLENABLE,
817 0x00);
819 /* Set/unset the masked control bit(s) as needed */
820 change = (!val ? 0 : mask) != (ctrl_data & mask);
821 if (!val)
822 ctrl_data &= ~mask;
823 else
824 ctrl_data |= mask;
825 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
826 ctrl_data);
828 return change;
831 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
832 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
833 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
834 .info = alc_eapd_ctrl_info, \
835 .get = alc_eapd_ctrl_get, \
836 .put = alc_eapd_ctrl_put, \
837 .private_value = nid | (mask<<16) }
838 #endif /* CONFIG_SND_DEBUG */
841 * set up the input pin config (depending on the given auto-pin type)
843 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
844 int auto_pin_type)
846 unsigned int val = PIN_IN;
848 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
849 unsigned int pincap;
850 unsigned int oldval;
851 oldval = snd_hda_codec_read(codec, nid, 0,
852 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
853 pincap = snd_hda_query_pin_caps(codec, nid);
854 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
855 /* if the default pin setup is vref50, we give it priority */
856 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
857 val = PIN_VREF80;
858 else if (pincap & AC_PINCAP_VREF_50)
859 val = PIN_VREF50;
860 else if (pincap & AC_PINCAP_VREF_100)
861 val = PIN_VREF100;
862 else if (pincap & AC_PINCAP_VREF_GRD)
863 val = PIN_VREFGRD;
865 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
870 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
872 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
873 return;
874 spec->mixers[spec->num_mixers++] = mix;
877 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
879 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
880 return;
881 spec->init_verbs[spec->num_init_verbs++] = verb;
885 * set up from the preset table
887 static void setup_preset(struct hda_codec *codec,
888 const struct alc_config_preset *preset)
890 struct alc_spec *spec = codec->spec;
891 int i;
893 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
894 add_mixer(spec, preset->mixers[i]);
895 spec->cap_mixer = preset->cap_mixer;
896 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
897 i++)
898 add_verb(spec, preset->init_verbs[i]);
900 spec->channel_mode = preset->channel_mode;
901 spec->num_channel_mode = preset->num_channel_mode;
902 spec->need_dac_fix = preset->need_dac_fix;
903 spec->const_channel_count = preset->const_channel_count;
905 if (preset->const_channel_count)
906 spec->multiout.max_channels = preset->const_channel_count;
907 else
908 spec->multiout.max_channels = spec->channel_mode[0].channels;
909 spec->ext_channel_count = spec->channel_mode[0].channels;
911 spec->multiout.num_dacs = preset->num_dacs;
912 spec->multiout.dac_nids = preset->dac_nids;
913 spec->multiout.dig_out_nid = preset->dig_out_nid;
914 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
915 spec->multiout.hp_nid = preset->hp_nid;
917 spec->num_mux_defs = preset->num_mux_defs;
918 if (!spec->num_mux_defs)
919 spec->num_mux_defs = 1;
920 spec->input_mux = preset->input_mux;
922 spec->num_adc_nids = preset->num_adc_nids;
923 spec->adc_nids = preset->adc_nids;
924 spec->capsrc_nids = preset->capsrc_nids;
925 spec->dig_in_nid = preset->dig_in_nid;
927 spec->unsol_event = preset->unsol_event;
928 spec->init_hook = preset->init_hook;
929 #ifdef CONFIG_SND_HDA_POWER_SAVE
930 spec->power_hook = preset->power_hook;
931 spec->loopback.amplist = preset->loopbacks;
932 #endif
934 if (preset->setup)
935 preset->setup(codec);
938 /* Enable GPIO mask and set output */
939 static struct hda_verb alc_gpio1_init_verbs[] = {
940 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
941 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
942 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
946 static struct hda_verb alc_gpio2_init_verbs[] = {
947 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
948 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
949 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
953 static struct hda_verb alc_gpio3_init_verbs[] = {
954 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
955 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
956 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
961 * Fix hardware PLL issue
962 * On some codecs, the analog PLL gating control must be off while
963 * the default value is 1.
965 static void alc_fix_pll(struct hda_codec *codec)
967 struct alc_spec *spec = codec->spec;
968 unsigned int val;
970 if (!spec->pll_nid)
971 return;
972 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
973 spec->pll_coef_idx);
974 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
975 AC_VERB_GET_PROC_COEF, 0);
976 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
977 spec->pll_coef_idx);
978 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
979 val & ~(1 << spec->pll_coef_bit));
982 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
983 unsigned int coef_idx, unsigned int coef_bit)
985 struct alc_spec *spec = codec->spec;
986 spec->pll_nid = nid;
987 spec->pll_coef_idx = coef_idx;
988 spec->pll_coef_bit = coef_bit;
989 alc_fix_pll(codec);
992 static void alc_automute_pin(struct hda_codec *codec)
994 struct alc_spec *spec = codec->spec;
995 unsigned int nid = spec->autocfg.hp_pins[0];
996 int i;
998 if (!nid)
999 return;
1000 spec->jack_present = snd_hda_jack_detect(codec, nid);
1001 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1002 nid = spec->autocfg.speaker_pins[i];
1003 if (!nid)
1004 break;
1005 snd_hda_codec_write(codec, nid, 0,
1006 AC_VERB_SET_PIN_WIDGET_CONTROL,
1007 spec->jack_present ? 0 : PIN_OUT);
1011 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1012 hda_nid_t nid)
1014 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1015 int i, nums;
1017 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1018 for (i = 0; i < nums; i++)
1019 if (conn[i] == nid)
1020 return i;
1021 return -1;
1024 /* switch the current ADC according to the jack state */
1025 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1027 struct alc_spec *spec = codec->spec;
1028 unsigned int present;
1029 hda_nid_t new_adc;
1031 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1032 if (present)
1033 spec->cur_adc_idx = 1;
1034 else
1035 spec->cur_adc_idx = 0;
1036 new_adc = spec->adc_nids[spec->cur_adc_idx];
1037 if (spec->cur_adc && spec->cur_adc != new_adc) {
1038 /* stream is running, let's swap the current ADC */
1039 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1040 spec->cur_adc = new_adc;
1041 snd_hda_codec_setup_stream(codec, new_adc,
1042 spec->cur_adc_stream_tag, 0,
1043 spec->cur_adc_format);
1047 static void alc_mic_automute(struct hda_codec *codec)
1049 struct alc_spec *spec = codec->spec;
1050 struct alc_mic_route *dead, *alive;
1051 unsigned int present, type;
1052 hda_nid_t cap_nid;
1054 if (!spec->auto_mic)
1055 return;
1056 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1057 return;
1058 if (snd_BUG_ON(!spec->adc_nids))
1059 return;
1061 if (spec->dual_adc_switch) {
1062 alc_dual_mic_adc_auto_switch(codec);
1063 return;
1066 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1068 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1069 if (present) {
1070 alive = &spec->ext_mic;
1071 dead = &spec->int_mic;
1072 } else {
1073 alive = &spec->int_mic;
1074 dead = &spec->ext_mic;
1077 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1078 if (type == AC_WID_AUD_MIX) {
1079 /* Matrix-mixer style (e.g. ALC882) */
1080 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1081 alive->mux_idx,
1082 HDA_AMP_MUTE, 0);
1083 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1084 dead->mux_idx,
1085 HDA_AMP_MUTE, HDA_AMP_MUTE);
1086 } else {
1087 /* MUX style (e.g. ALC880) */
1088 snd_hda_codec_write_cache(codec, cap_nid, 0,
1089 AC_VERB_SET_CONNECT_SEL,
1090 alive->mux_idx);
1093 /* FIXME: analog mixer */
1096 /* unsolicited event for HP jack sensing */
1097 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1099 if (codec->vendor_id == 0x10ec0880)
1100 res >>= 28;
1101 else
1102 res >>= 26;
1103 switch (res) {
1104 case ALC880_HP_EVENT:
1105 alc_automute_pin(codec);
1106 break;
1107 case ALC880_MIC_EVENT:
1108 alc_mic_automute(codec);
1109 break;
1113 static void alc_inithook(struct hda_codec *codec)
1115 alc_automute_pin(codec);
1116 alc_mic_automute(codec);
1119 /* additional initialization for ALC888 variants */
1120 static void alc888_coef_init(struct hda_codec *codec)
1122 unsigned int tmp;
1124 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1125 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1126 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1127 if ((tmp & 0xf0) == 0x20)
1128 /* alc888S-VC */
1129 snd_hda_codec_read(codec, 0x20, 0,
1130 AC_VERB_SET_PROC_COEF, 0x830);
1131 else
1132 /* alc888-VB */
1133 snd_hda_codec_read(codec, 0x20, 0,
1134 AC_VERB_SET_PROC_COEF, 0x3030);
1137 static void alc889_coef_init(struct hda_codec *codec)
1139 unsigned int tmp;
1141 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1142 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1143 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1144 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1147 /* turn on/off EAPD control (only if available) */
1148 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1150 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1151 return;
1152 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1153 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1154 on ? 2 : 0);
1157 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1159 unsigned int tmp;
1161 switch (type) {
1162 case ALC_INIT_GPIO1:
1163 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1164 break;
1165 case ALC_INIT_GPIO2:
1166 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1167 break;
1168 case ALC_INIT_GPIO3:
1169 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1170 break;
1171 case ALC_INIT_DEFAULT:
1172 switch (codec->vendor_id) {
1173 case 0x10ec0260:
1174 set_eapd(codec, 0x0f, 1);
1175 set_eapd(codec, 0x10, 1);
1176 break;
1177 case 0x10ec0262:
1178 case 0x10ec0267:
1179 case 0x10ec0268:
1180 case 0x10ec0269:
1181 case 0x10ec0270:
1182 case 0x10ec0272:
1183 case 0x10ec0660:
1184 case 0x10ec0662:
1185 case 0x10ec0663:
1186 case 0x10ec0862:
1187 case 0x10ec0889:
1188 set_eapd(codec, 0x14, 1);
1189 set_eapd(codec, 0x15, 1);
1190 break;
1192 switch (codec->vendor_id) {
1193 case 0x10ec0260:
1194 snd_hda_codec_write(codec, 0x1a, 0,
1195 AC_VERB_SET_COEF_INDEX, 7);
1196 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1197 AC_VERB_GET_PROC_COEF, 0);
1198 snd_hda_codec_write(codec, 0x1a, 0,
1199 AC_VERB_SET_COEF_INDEX, 7);
1200 snd_hda_codec_write(codec, 0x1a, 0,
1201 AC_VERB_SET_PROC_COEF,
1202 tmp | 0x2010);
1203 break;
1204 case 0x10ec0262:
1205 case 0x10ec0880:
1206 case 0x10ec0882:
1207 case 0x10ec0883:
1208 case 0x10ec0885:
1209 case 0x10ec0887:
1210 case 0x10ec0889:
1211 alc889_coef_init(codec);
1212 break;
1213 case 0x10ec0888:
1214 alc888_coef_init(codec);
1215 break;
1216 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1217 case 0x10ec0267:
1218 case 0x10ec0268:
1219 snd_hda_codec_write(codec, 0x20, 0,
1220 AC_VERB_SET_COEF_INDEX, 7);
1221 tmp = snd_hda_codec_read(codec, 0x20, 0,
1222 AC_VERB_GET_PROC_COEF, 0);
1223 snd_hda_codec_write(codec, 0x20, 0,
1224 AC_VERB_SET_COEF_INDEX, 7);
1225 snd_hda_codec_write(codec, 0x20, 0,
1226 AC_VERB_SET_PROC_COEF,
1227 tmp | 0x3000);
1228 break;
1229 #endif /* XXX */
1231 break;
1235 static void alc_init_auto_hp(struct hda_codec *codec)
1237 struct alc_spec *spec = codec->spec;
1239 if (!spec->autocfg.hp_pins[0])
1240 return;
1242 if (!spec->autocfg.speaker_pins[0]) {
1243 if (spec->autocfg.line_out_pins[0] &&
1244 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1245 spec->autocfg.speaker_pins[0] =
1246 spec->autocfg.line_out_pins[0];
1247 else
1248 return;
1251 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1252 spec->autocfg.hp_pins[0]);
1253 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1254 AC_VERB_SET_UNSOLICITED_ENABLE,
1255 AC_USRSP_EN | ALC880_HP_EVENT);
1256 spec->unsol_event = alc_sku_unsol_event;
1259 static void alc_init_auto_mic(struct hda_codec *codec)
1261 struct alc_spec *spec = codec->spec;
1262 struct auto_pin_cfg *cfg = &spec->autocfg;
1263 hda_nid_t fixed, ext;
1264 int i;
1266 /* there must be only two mic inputs exclusively */
1267 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1268 if (cfg->input_pins[i])
1269 return;
1271 fixed = ext = 0;
1272 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1273 hda_nid_t nid = cfg->input_pins[i];
1274 unsigned int defcfg;
1275 if (!nid)
1276 return;
1277 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1278 switch (get_defcfg_connect(defcfg)) {
1279 case AC_JACK_PORT_FIXED:
1280 if (fixed)
1281 return; /* already occupied */
1282 fixed = nid;
1283 break;
1284 case AC_JACK_PORT_COMPLEX:
1285 if (ext)
1286 return; /* already occupied */
1287 ext = nid;
1288 break;
1289 default:
1290 return; /* invalid entry */
1293 if (!ext || !fixed)
1294 return;
1295 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1296 return; /* no unsol support */
1297 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1298 ext, fixed);
1299 spec->ext_mic.pin = ext;
1300 spec->int_mic.pin = fixed;
1301 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1302 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1303 spec->auto_mic = 1;
1304 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1305 AC_VERB_SET_UNSOLICITED_ENABLE,
1306 AC_USRSP_EN | ALC880_MIC_EVENT);
1307 spec->unsol_event = alc_sku_unsol_event;
1310 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1312 unsigned int ass, tmp, i;
1313 unsigned nid = 0;
1314 struct alc_spec *spec = codec->spec;
1316 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1318 ass = codec->subsystem_id & 0xffff;
1319 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1320 goto do_sku;
1322 nid = 0x1d;
1323 if (codec->vendor_id == 0x10ec0260)
1324 nid = 0x17;
1325 ass = snd_hda_codec_get_pincfg(codec, nid);
1327 if (!(ass & 1)) {
1328 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1329 codec->chip_name, ass);
1330 return -1;
1333 /* check sum */
1334 tmp = 0;
1335 for (i = 1; i < 16; i++) {
1336 if ((ass >> i) & 1)
1337 tmp++;
1339 if (((ass >> 16) & 0xf) != tmp)
1340 return -1;
1342 spec->cdefine.port_connectivity = ass >> 30;
1343 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1344 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1345 spec->cdefine.customization = ass >> 8;
1346 do_sku:
1347 spec->cdefine.sku_cfg = ass;
1348 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1349 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1350 spec->cdefine.swap = (ass & 0x2) >> 1;
1351 spec->cdefine.override = ass & 0x1;
1353 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1354 nid, spec->cdefine.sku_cfg);
1355 snd_printd("SKU: port_connectivity=0x%x\n",
1356 spec->cdefine.port_connectivity);
1357 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1358 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1359 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1360 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1361 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1362 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1363 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1365 return 0;
1368 /* check subsystem ID and set up device-specific initialization;
1369 * return 1 if initialized, 0 if invalid SSID
1371 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1372 * 31 ~ 16 : Manufacture ID
1373 * 15 ~ 8 : SKU ID
1374 * 7 ~ 0 : Assembly ID
1375 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1377 static int alc_subsystem_id(struct hda_codec *codec,
1378 hda_nid_t porta, hda_nid_t porte,
1379 hda_nid_t portd, hda_nid_t porti)
1381 unsigned int ass, tmp, i;
1382 unsigned nid;
1383 struct alc_spec *spec = codec->spec;
1385 ass = codec->subsystem_id & 0xffff;
1386 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1387 goto do_sku;
1389 /* invalid SSID, check the special NID pin defcfg instead */
1391 * 31~30 : port connectivity
1392 * 29~21 : reserve
1393 * 20 : PCBEEP input
1394 * 19~16 : Check sum (15:1)
1395 * 15~1 : Custom
1396 * 0 : override
1398 nid = 0x1d;
1399 if (codec->vendor_id == 0x10ec0260)
1400 nid = 0x17;
1401 ass = snd_hda_codec_get_pincfg(codec, nid);
1402 snd_printd("realtek: No valid SSID, "
1403 "checking pincfg 0x%08x for NID 0x%x\n",
1404 ass, nid);
1405 if (!(ass & 1))
1406 return 0;
1407 if ((ass >> 30) != 1) /* no physical connection */
1408 return 0;
1410 /* check sum */
1411 tmp = 0;
1412 for (i = 1; i < 16; i++) {
1413 if ((ass >> i) & 1)
1414 tmp++;
1416 if (((ass >> 16) & 0xf) != tmp)
1417 return 0;
1418 do_sku:
1419 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1420 ass & 0xffff, codec->vendor_id);
1422 * 0 : override
1423 * 1 : Swap Jack
1424 * 2 : 0 --> Desktop, 1 --> Laptop
1425 * 3~5 : External Amplifier control
1426 * 7~6 : Reserved
1428 tmp = (ass & 0x38) >> 3; /* external Amp control */
1429 switch (tmp) {
1430 case 1:
1431 spec->init_amp = ALC_INIT_GPIO1;
1432 break;
1433 case 3:
1434 spec->init_amp = ALC_INIT_GPIO2;
1435 break;
1436 case 7:
1437 spec->init_amp = ALC_INIT_GPIO3;
1438 break;
1439 case 5:
1440 spec->init_amp = ALC_INIT_DEFAULT;
1441 break;
1444 /* is laptop or Desktop and enable the function "Mute internal speaker
1445 * when the external headphone out jack is plugged"
1447 if (!(ass & 0x8000))
1448 return 1;
1450 * 10~8 : Jack location
1451 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1452 * 14~13: Resvered
1453 * 15 : 1 --> enable the function "Mute internal speaker
1454 * when the external headphone out jack is plugged"
1456 if (!spec->autocfg.hp_pins[0]) {
1457 hda_nid_t nid;
1458 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1459 if (tmp == 0)
1460 nid = porta;
1461 else if (tmp == 1)
1462 nid = porte;
1463 else if (tmp == 2)
1464 nid = portd;
1465 else if (tmp == 3)
1466 nid = porti;
1467 else
1468 return 1;
1469 for (i = 0; i < spec->autocfg.line_outs; i++)
1470 if (spec->autocfg.line_out_pins[i] == nid)
1471 return 1;
1472 spec->autocfg.hp_pins[0] = nid;
1475 alc_init_auto_hp(codec);
1476 alc_init_auto_mic(codec);
1477 return 1;
1480 static void alc_ssid_check(struct hda_codec *codec,
1481 hda_nid_t porta, hda_nid_t porte,
1482 hda_nid_t portd, hda_nid_t porti)
1484 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1485 struct alc_spec *spec = codec->spec;
1486 snd_printd("realtek: "
1487 "Enable default setup for auto mode as fallback\n");
1488 spec->init_amp = ALC_INIT_DEFAULT;
1489 alc_init_auto_hp(codec);
1490 alc_init_auto_mic(codec);
1495 * Fix-up pin default configurations and add default verbs
1498 struct alc_pincfg {
1499 hda_nid_t nid;
1500 u32 val;
1503 struct alc_fixup {
1504 const struct alc_pincfg *pins;
1505 const struct hda_verb *verbs;
1508 static void alc_pick_fixup(struct hda_codec *codec,
1509 const struct snd_pci_quirk *quirk,
1510 const struct alc_fixup *fix,
1511 int pre_init)
1513 const struct alc_pincfg *cfg;
1515 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1516 if (!quirk)
1517 return;
1518 fix += quirk->value;
1519 cfg = fix->pins;
1520 if (pre_init && cfg) {
1521 #ifdef CONFIG_SND_DEBUG_VERBOSE
1522 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1523 codec->chip_name, quirk->name);
1524 #endif
1525 for (; cfg->nid; cfg++)
1526 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1528 if (!pre_init && fix->verbs) {
1529 #ifdef CONFIG_SND_DEBUG_VERBOSE
1530 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1531 codec->chip_name, quirk->name);
1532 #endif
1533 add_verb(codec->spec, fix->verbs);
1537 static int alc_read_coef_idx(struct hda_codec *codec,
1538 unsigned int coef_idx)
1540 unsigned int val;
1541 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1542 coef_idx);
1543 val = snd_hda_codec_read(codec, 0x20, 0,
1544 AC_VERB_GET_PROC_COEF, 0);
1545 return val;
1548 /* set right pin controls for digital I/O */
1549 static void alc_auto_init_digital(struct hda_codec *codec)
1551 struct alc_spec *spec = codec->spec;
1552 int i;
1553 hda_nid_t pin;
1555 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1556 pin = spec->autocfg.dig_out_pins[i];
1557 if (pin) {
1558 snd_hda_codec_write(codec, pin, 0,
1559 AC_VERB_SET_PIN_WIDGET_CONTROL,
1560 PIN_OUT);
1563 pin = spec->autocfg.dig_in_pin;
1564 if (pin)
1565 snd_hda_codec_write(codec, pin, 0,
1566 AC_VERB_SET_PIN_WIDGET_CONTROL,
1567 PIN_IN);
1570 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1571 static void alc_auto_parse_digital(struct hda_codec *codec)
1573 struct alc_spec *spec = codec->spec;
1574 int i, err;
1575 hda_nid_t dig_nid;
1577 /* support multiple SPDIFs; the secondary is set up as a slave */
1578 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1579 err = snd_hda_get_connections(codec,
1580 spec->autocfg.dig_out_pins[i],
1581 &dig_nid, 1);
1582 if (err < 0)
1583 continue;
1584 if (!i) {
1585 spec->multiout.dig_out_nid = dig_nid;
1586 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1587 } else {
1588 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1589 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1590 break;
1591 spec->slave_dig_outs[i - 1] = dig_nid;
1595 if (spec->autocfg.dig_in_pin) {
1596 hda_nid_t dig_nid;
1597 err = snd_hda_get_connections(codec,
1598 spec->autocfg.dig_in_pin,
1599 &dig_nid, 1);
1600 if (err > 0)
1601 spec->dig_in_nid = dig_nid;
1606 * ALC888
1610 * 2ch mode
1612 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1613 /* Mic-in jack as mic in */
1614 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1615 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1616 /* Line-in jack as Line in */
1617 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1618 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1619 /* Line-Out as Front */
1620 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1621 { } /* end */
1625 * 4ch mode
1627 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1628 /* Mic-in jack as mic in */
1629 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1630 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1631 /* Line-in jack as Surround */
1632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1634 /* Line-Out as Front */
1635 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 { } /* end */
1640 * 6ch mode
1642 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1643 /* Mic-in jack as CLFE */
1644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1646 /* Line-in jack as Surround */
1647 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1648 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1649 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1650 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1651 { } /* end */
1655 * 8ch mode
1657 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1658 /* Mic-in jack as CLFE */
1659 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1660 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1661 /* Line-in jack as Surround */
1662 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1663 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1664 /* Line-Out as Side */
1665 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1666 { } /* end */
1669 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1670 { 2, alc888_4ST_ch2_intel_init },
1671 { 4, alc888_4ST_ch4_intel_init },
1672 { 6, alc888_4ST_ch6_intel_init },
1673 { 8, alc888_4ST_ch8_intel_init },
1677 * ALC888 Fujitsu Siemens Amillo xa3530
1680 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1681 /* Front Mic: set to PIN_IN (empty by default) */
1682 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1683 /* Connect Internal HP to Front */
1684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1687 /* Connect Bass HP to Front */
1688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1691 /* Connect Line-Out side jack (SPDIF) to Side */
1692 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1695 /* Connect Mic jack to CLFE */
1696 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1697 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1699 /* Connect Line-in jack to Surround */
1700 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1701 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1702 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1703 /* Connect HP out jack to Front */
1704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1707 /* Enable unsolicited event for HP jack and Line-out jack */
1708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1709 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1713 static void alc_automute_amp(struct hda_codec *codec)
1715 struct alc_spec *spec = codec->spec;
1716 unsigned int mute;
1717 hda_nid_t nid;
1718 int i;
1720 spec->jack_present = 0;
1721 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1722 nid = spec->autocfg.hp_pins[i];
1723 if (!nid)
1724 break;
1725 if (snd_hda_jack_detect(codec, nid)) {
1726 spec->jack_present = 1;
1727 break;
1731 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1732 /* Toggle internal speakers muting */
1733 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1734 nid = spec->autocfg.speaker_pins[i];
1735 if (!nid)
1736 break;
1737 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1738 HDA_AMP_MUTE, mute);
1742 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1743 unsigned int res)
1745 if (codec->vendor_id == 0x10ec0880)
1746 res >>= 28;
1747 else
1748 res >>= 26;
1749 if (res == ALC880_HP_EVENT)
1750 alc_automute_amp(codec);
1753 static void alc889_automute_setup(struct hda_codec *codec)
1755 struct alc_spec *spec = codec->spec;
1757 spec->autocfg.hp_pins[0] = 0x15;
1758 spec->autocfg.speaker_pins[0] = 0x14;
1759 spec->autocfg.speaker_pins[1] = 0x16;
1760 spec->autocfg.speaker_pins[2] = 0x17;
1761 spec->autocfg.speaker_pins[3] = 0x19;
1762 spec->autocfg.speaker_pins[4] = 0x1a;
1765 static void alc889_intel_init_hook(struct hda_codec *codec)
1767 alc889_coef_init(codec);
1768 alc_automute_amp(codec);
1771 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1773 struct alc_spec *spec = codec->spec;
1775 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1776 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1777 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1778 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1782 * ALC888 Acer Aspire 4930G model
1785 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1786 /* Front Mic: set to PIN_IN (empty by default) */
1787 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1788 /* Unselect Front Mic by default in input mixer 3 */
1789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1790 /* Enable unsolicited event for HP jack */
1791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1792 /* Connect Internal HP to front */
1793 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1795 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1796 /* Connect HP out to front */
1797 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1798 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1804 * ALC888 Acer Aspire 6530G model
1807 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1808 /* Route to built-in subwoofer as well as speakers */
1809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1811 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1813 /* Bias voltage on for external mic port */
1814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1815 /* Front Mic: set to PIN_IN (empty by default) */
1816 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1817 /* Unselect Front Mic by default in input mixer 3 */
1818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1819 /* Enable unsolicited event for HP jack */
1820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1821 /* Enable speaker output */
1822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1823 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1825 /* Enable headphone output */
1826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1829 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1834 * ALC889 Acer Aspire 8930G model
1837 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1838 /* Front Mic: set to PIN_IN (empty by default) */
1839 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1840 /* Unselect Front Mic by default in input mixer 3 */
1841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1842 /* Enable unsolicited event for HP jack */
1843 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1844 /* Connect Internal Front to Front */
1845 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1847 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1848 /* Connect Internal Rear to Rear */
1849 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1850 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1852 /* Connect Internal CLFE to CLFE */
1853 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1854 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1855 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1856 /* Connect HP out to Front */
1857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1859 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1860 /* Enable all DACs */
1861 /* DAC DISABLE/MUTE 1? */
1862 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1863 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1864 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1865 /* DAC DISABLE/MUTE 2? */
1866 /* some bit here disables the other DACs. Init=0x4900 */
1867 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1868 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1869 /* DMIC fix
1870 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1871 * which makes the stereo useless. However, either the mic or the ALC889
1872 * makes the signal become a difference/sum signal instead of standard
1873 * stereo, which is annoying. So instead we flip this bit which makes the
1874 * codec replicate the sum signal to both channels, turning it into a
1875 * normal mono mic.
1877 /* DMIC_CONTROL? Init value = 0x0001 */
1878 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1879 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1883 static struct hda_input_mux alc888_2_capture_sources[2] = {
1884 /* Front mic only available on one ADC */
1886 .num_items = 4,
1887 .items = {
1888 { "Mic", 0x0 },
1889 { "Line", 0x2 },
1890 { "CD", 0x4 },
1891 { "Front Mic", 0xb },
1895 .num_items = 3,
1896 .items = {
1897 { "Mic", 0x0 },
1898 { "Line", 0x2 },
1899 { "CD", 0x4 },
1904 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1905 /* Interal mic only available on one ADC */
1907 .num_items = 5,
1908 .items = {
1909 { "Ext Mic", 0x0 },
1910 { "Line In", 0x2 },
1911 { "CD", 0x4 },
1912 { "Input Mix", 0xa },
1913 { "Int Mic", 0xb },
1917 .num_items = 4,
1918 .items = {
1919 { "Ext Mic", 0x0 },
1920 { "Line In", 0x2 },
1921 { "CD", 0x4 },
1922 { "Input Mix", 0xa },
1927 static struct hda_input_mux alc889_capture_sources[3] = {
1928 /* Digital mic only available on first "ADC" */
1930 .num_items = 5,
1931 .items = {
1932 { "Mic", 0x0 },
1933 { "Line", 0x2 },
1934 { "CD", 0x4 },
1935 { "Front Mic", 0xb },
1936 { "Input Mix", 0xa },
1940 .num_items = 4,
1941 .items = {
1942 { "Mic", 0x0 },
1943 { "Line", 0x2 },
1944 { "CD", 0x4 },
1945 { "Input Mix", 0xa },
1949 .num_items = 4,
1950 .items = {
1951 { "Mic", 0x0 },
1952 { "Line", 0x2 },
1953 { "CD", 0x4 },
1954 { "Input Mix", 0xa },
1959 static struct snd_kcontrol_new alc888_base_mixer[] = {
1960 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1961 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1962 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1963 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1964 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1965 HDA_OUTPUT),
1966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1973 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1974 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1978 { } /* end */
1981 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1982 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1983 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1984 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1985 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1986 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1987 HDA_OUTPUT),
1988 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1989 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1990 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1996 { } /* end */
2000 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2002 struct alc_spec *spec = codec->spec;
2004 spec->autocfg.hp_pins[0] = 0x15;
2005 spec->autocfg.speaker_pins[0] = 0x14;
2006 spec->autocfg.speaker_pins[1] = 0x16;
2007 spec->autocfg.speaker_pins[2] = 0x17;
2010 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2012 struct alc_spec *spec = codec->spec;
2014 spec->autocfg.hp_pins[0] = 0x15;
2015 spec->autocfg.speaker_pins[0] = 0x14;
2016 spec->autocfg.speaker_pins[1] = 0x16;
2017 spec->autocfg.speaker_pins[2] = 0x17;
2020 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2022 struct alc_spec *spec = codec->spec;
2024 spec->autocfg.hp_pins[0] = 0x15;
2025 spec->autocfg.speaker_pins[0] = 0x14;
2026 spec->autocfg.speaker_pins[1] = 0x16;
2027 spec->autocfg.speaker_pins[2] = 0x1b;
2031 * ALC880 3-stack model
2033 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2034 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2035 * F-Mic = 0x1b, HP = 0x19
2038 static hda_nid_t alc880_dac_nids[4] = {
2039 /* front, rear, clfe, rear_surr */
2040 0x02, 0x05, 0x04, 0x03
2043 static hda_nid_t alc880_adc_nids[3] = {
2044 /* ADC0-2 */
2045 0x07, 0x08, 0x09,
2048 /* The datasheet says the node 0x07 is connected from inputs,
2049 * but it shows zero connection in the real implementation on some devices.
2050 * Note: this is a 915GAV bug, fixed on 915GLV
2052 static hda_nid_t alc880_adc_nids_alt[2] = {
2053 /* ADC1-2 */
2054 0x08, 0x09,
2057 #define ALC880_DIGOUT_NID 0x06
2058 #define ALC880_DIGIN_NID 0x0a
2060 static struct hda_input_mux alc880_capture_source = {
2061 .num_items = 4,
2062 .items = {
2063 { "Mic", 0x0 },
2064 { "Front Mic", 0x3 },
2065 { "Line", 0x2 },
2066 { "CD", 0x4 },
2070 /* channel source setting (2/6 channel selection for 3-stack) */
2071 /* 2ch mode */
2072 static struct hda_verb alc880_threestack_ch2_init[] = {
2073 /* set line-in to input, mute it */
2074 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2075 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2076 /* set mic-in to input vref 80%, mute it */
2077 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2078 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2079 { } /* end */
2082 /* 6ch mode */
2083 static struct hda_verb alc880_threestack_ch6_init[] = {
2084 /* set line-in to output, unmute it */
2085 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2086 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2087 /* set mic-in to output, unmute it */
2088 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2089 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2090 { } /* end */
2093 static struct hda_channel_mode alc880_threestack_modes[2] = {
2094 { 2, alc880_threestack_ch2_init },
2095 { 6, alc880_threestack_ch6_init },
2098 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2099 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2100 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2102 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2114 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2118 .name = "Channel Mode",
2119 .info = alc_ch_mode_info,
2120 .get = alc_ch_mode_get,
2121 .put = alc_ch_mode_put,
2123 { } /* end */
2126 /* capture mixer elements */
2127 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2128 struct snd_ctl_elem_info *uinfo)
2130 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2131 struct alc_spec *spec = codec->spec;
2132 int err;
2134 mutex_lock(&codec->control_mutex);
2135 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2136 HDA_INPUT);
2137 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2138 mutex_unlock(&codec->control_mutex);
2139 return err;
2142 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2143 unsigned int size, unsigned int __user *tlv)
2145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2146 struct alc_spec *spec = codec->spec;
2147 int err;
2149 mutex_lock(&codec->control_mutex);
2150 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2151 HDA_INPUT);
2152 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2153 mutex_unlock(&codec->control_mutex);
2154 return err;
2157 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2158 struct snd_ctl_elem_value *ucontrol);
2160 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2161 struct snd_ctl_elem_value *ucontrol,
2162 getput_call_t func)
2164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2165 struct alc_spec *spec = codec->spec;
2166 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2167 int err;
2169 mutex_lock(&codec->control_mutex);
2170 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2171 3, 0, HDA_INPUT);
2172 err = func(kcontrol, ucontrol);
2173 mutex_unlock(&codec->control_mutex);
2174 return err;
2177 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2178 struct snd_ctl_elem_value *ucontrol)
2180 return alc_cap_getput_caller(kcontrol, ucontrol,
2181 snd_hda_mixer_amp_volume_get);
2184 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2185 struct snd_ctl_elem_value *ucontrol)
2187 return alc_cap_getput_caller(kcontrol, ucontrol,
2188 snd_hda_mixer_amp_volume_put);
2191 /* capture mixer elements */
2192 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2194 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2195 struct snd_ctl_elem_value *ucontrol)
2197 return alc_cap_getput_caller(kcontrol, ucontrol,
2198 snd_hda_mixer_amp_switch_get);
2201 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2202 struct snd_ctl_elem_value *ucontrol)
2204 return alc_cap_getput_caller(kcontrol, ucontrol,
2205 snd_hda_mixer_amp_switch_put);
2208 #define _DEFINE_CAPMIX(num) \
2210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2211 .name = "Capture Switch", \
2212 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2213 .count = num, \
2214 .info = alc_cap_sw_info, \
2215 .get = alc_cap_sw_get, \
2216 .put = alc_cap_sw_put, \
2217 }, \
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2220 .name = "Capture Volume", \
2221 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2222 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2223 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2224 .count = num, \
2225 .info = alc_cap_vol_info, \
2226 .get = alc_cap_vol_get, \
2227 .put = alc_cap_vol_put, \
2228 .tlv = { .c = alc_cap_vol_tlv }, \
2231 #define _DEFINE_CAPSRC(num) \
2233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2234 /* .name = "Capture Source", */ \
2235 .name = "Input Source", \
2236 .count = num, \
2237 .info = alc_mux_enum_info, \
2238 .get = alc_mux_enum_get, \
2239 .put = alc_mux_enum_put, \
2242 #define DEFINE_CAPMIX(num) \
2243 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2244 _DEFINE_CAPMIX(num), \
2245 _DEFINE_CAPSRC(num), \
2246 { } /* end */ \
2249 #define DEFINE_CAPMIX_NOSRC(num) \
2250 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2251 _DEFINE_CAPMIX(num), \
2252 { } /* end */ \
2255 /* up to three ADCs */
2256 DEFINE_CAPMIX(1);
2257 DEFINE_CAPMIX(2);
2258 DEFINE_CAPMIX(3);
2259 DEFINE_CAPMIX_NOSRC(1);
2260 DEFINE_CAPMIX_NOSRC(2);
2261 DEFINE_CAPMIX_NOSRC(3);
2264 * ALC880 5-stack model
2266 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2267 * Side = 0x02 (0xd)
2268 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2269 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2272 /* additional mixers to alc880_three_stack_mixer */
2273 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2274 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2275 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2276 { } /* end */
2279 /* channel source setting (6/8 channel selection for 5-stack) */
2280 /* 6ch mode */
2281 static struct hda_verb alc880_fivestack_ch6_init[] = {
2282 /* set line-in to input, mute it */
2283 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2284 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2285 { } /* end */
2288 /* 8ch mode */
2289 static struct hda_verb alc880_fivestack_ch8_init[] = {
2290 /* set line-in to output, unmute it */
2291 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2292 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2293 { } /* end */
2296 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2297 { 6, alc880_fivestack_ch6_init },
2298 { 8, alc880_fivestack_ch8_init },
2303 * ALC880 6-stack model
2305 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2306 * Side = 0x05 (0x0f)
2307 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2308 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2311 static hda_nid_t alc880_6st_dac_nids[4] = {
2312 /* front, rear, clfe, rear_surr */
2313 0x02, 0x03, 0x04, 0x05
2316 static struct hda_input_mux alc880_6stack_capture_source = {
2317 .num_items = 4,
2318 .items = {
2319 { "Mic", 0x0 },
2320 { "Front Mic", 0x1 },
2321 { "Line", 0x2 },
2322 { "CD", 0x4 },
2326 /* fixed 8-channels */
2327 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2328 { 8, NULL },
2331 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2332 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2333 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2334 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2335 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2336 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2337 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2338 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2339 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2340 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2341 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2342 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2343 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2344 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2345 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2352 .name = "Channel Mode",
2353 .info = alc_ch_mode_info,
2354 .get = alc_ch_mode_get,
2355 .put = alc_ch_mode_put,
2357 { } /* end */
2362 * ALC880 W810 model
2364 * W810 has rear IO for:
2365 * Front (DAC 02)
2366 * Surround (DAC 03)
2367 * Center/LFE (DAC 04)
2368 * Digital out (06)
2370 * The system also has a pair of internal speakers, and a headphone jack.
2371 * These are both connected to Line2 on the codec, hence to DAC 02.
2373 * There is a variable resistor to control the speaker or headphone
2374 * volume. This is a hardware-only device without a software API.
2376 * Plugging headphones in will disable the internal speakers. This is
2377 * implemented in hardware, not via the driver using jack sense. In
2378 * a similar fashion, plugging into the rear socket marked "front" will
2379 * disable both the speakers and headphones.
2381 * For input, there's a microphone jack, and an "audio in" jack.
2382 * These may not do anything useful with this driver yet, because I
2383 * haven't setup any initialization verbs for these yet...
2386 static hda_nid_t alc880_w810_dac_nids[3] = {
2387 /* front, rear/surround, clfe */
2388 0x02, 0x03, 0x04
2391 /* fixed 6 channels */
2392 static struct hda_channel_mode alc880_w810_modes[1] = {
2393 { 6, NULL }
2396 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2397 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2398 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2399 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2400 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2401 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2402 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2403 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2404 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2405 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2406 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2407 { } /* end */
2412 * Z710V model
2414 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2415 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2416 * Line = 0x1a
2419 static hda_nid_t alc880_z71v_dac_nids[1] = {
2420 0x02
2422 #define ALC880_Z71V_HP_DAC 0x03
2424 /* fixed 2 channels */
2425 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2426 { 2, NULL }
2429 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2433 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2437 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2438 { } /* end */
2443 * ALC880 F1734 model
2445 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2446 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2449 static hda_nid_t alc880_f1734_dac_nids[1] = {
2450 0x03
2452 #define ALC880_F1734_HP_DAC 0x02
2454 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2455 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2456 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2457 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2458 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2459 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2460 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2463 { } /* end */
2466 static struct hda_input_mux alc880_f1734_capture_source = {
2467 .num_items = 2,
2468 .items = {
2469 { "Mic", 0x1 },
2470 { "CD", 0x4 },
2476 * ALC880 ASUS model
2478 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2479 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2480 * Mic = 0x18, Line = 0x1a
2483 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2484 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2486 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2487 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2488 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2490 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2491 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2492 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2493 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2494 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2495 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2496 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2500 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2503 .name = "Channel Mode",
2504 .info = alc_ch_mode_info,
2505 .get = alc_ch_mode_get,
2506 .put = alc_ch_mode_put,
2508 { } /* end */
2512 * ALC880 ASUS W1V model
2514 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2515 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2516 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2519 /* additional mixers to alc880_asus_mixer */
2520 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2521 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2522 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2523 { } /* end */
2526 /* TCL S700 */
2527 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2528 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2529 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2530 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2532 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2534 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2535 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2537 { } /* end */
2540 /* Uniwill */
2541 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2542 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2543 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2544 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2545 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2546 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2547 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2548 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2551 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2552 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2553 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2555 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2560 .name = "Channel Mode",
2561 .info = alc_ch_mode_info,
2562 .get = alc_ch_mode_get,
2563 .put = alc_ch_mode_put,
2565 { } /* end */
2568 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2569 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2571 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2572 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2573 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2574 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2575 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2576 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2578 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2579 { } /* end */
2582 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2584 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2586 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2588 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2589 { } /* end */
2593 * virtual master controls
2597 * slave controls for virtual master
2599 static const char *alc_slave_vols[] = {
2600 "Front Playback Volume",
2601 "Surround Playback Volume",
2602 "Center Playback Volume",
2603 "LFE Playback Volume",
2604 "Side Playback Volume",
2605 "Headphone Playback Volume",
2606 "Speaker Playback Volume",
2607 "Mono Playback Volume",
2608 "Line-Out Playback Volume",
2609 "PCM Playback Volume",
2610 NULL,
2613 static const char *alc_slave_sws[] = {
2614 "Front Playback Switch",
2615 "Surround Playback Switch",
2616 "Center Playback Switch",
2617 "LFE Playback Switch",
2618 "Side Playback Switch",
2619 "Headphone Playback Switch",
2620 "Speaker Playback Switch",
2621 "Mono Playback Switch",
2622 "IEC958 Playback Switch",
2623 "Line-Out Playback Switch",
2624 "PCM Playback Switch",
2625 NULL,
2629 * build control elements
2632 #define NID_MAPPING (-1)
2634 #define SUBDEV_SPEAKER_ (0 << 6)
2635 #define SUBDEV_HP_ (1 << 6)
2636 #define SUBDEV_LINE_ (2 << 6)
2637 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2638 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2639 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2641 static void alc_free_kctls(struct hda_codec *codec);
2643 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2644 /* additional beep mixers; the actual parameters are overwritten at build */
2645 static struct snd_kcontrol_new alc_beep_mixer[] = {
2646 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2647 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2648 { } /* end */
2650 #endif
2652 static int alc_build_controls(struct hda_codec *codec)
2654 struct alc_spec *spec = codec->spec;
2655 struct snd_kcontrol *kctl = NULL;
2656 struct snd_kcontrol_new *knew;
2657 int i, j, err;
2658 unsigned int u;
2659 hda_nid_t nid;
2661 for (i = 0; i < spec->num_mixers; i++) {
2662 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2663 if (err < 0)
2664 return err;
2666 if (spec->cap_mixer) {
2667 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2668 if (err < 0)
2669 return err;
2671 if (spec->multiout.dig_out_nid) {
2672 err = snd_hda_create_spdif_out_ctls(codec,
2673 spec->multiout.dig_out_nid);
2674 if (err < 0)
2675 return err;
2676 if (!spec->no_analog) {
2677 err = snd_hda_create_spdif_share_sw(codec,
2678 &spec->multiout);
2679 if (err < 0)
2680 return err;
2681 spec->multiout.share_spdif = 1;
2684 if (spec->dig_in_nid) {
2685 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2686 if (err < 0)
2687 return err;
2690 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2691 /* create beep controls if needed */
2692 if (spec->beep_amp) {
2693 struct snd_kcontrol_new *knew;
2694 for (knew = alc_beep_mixer; knew->name; knew++) {
2695 struct snd_kcontrol *kctl;
2696 kctl = snd_ctl_new1(knew, codec);
2697 if (!kctl)
2698 return -ENOMEM;
2699 kctl->private_value = spec->beep_amp;
2700 err = snd_hda_ctl_add(codec, 0, kctl);
2701 if (err < 0)
2702 return err;
2705 #endif
2707 /* if we have no master control, let's create it */
2708 if (!spec->no_analog &&
2709 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2710 unsigned int vmaster_tlv[4];
2711 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2712 HDA_OUTPUT, vmaster_tlv);
2713 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2714 vmaster_tlv, alc_slave_vols);
2715 if (err < 0)
2716 return err;
2718 if (!spec->no_analog &&
2719 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2720 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2721 NULL, alc_slave_sws);
2722 if (err < 0)
2723 return err;
2726 /* assign Capture Source enums to NID */
2727 if (spec->capsrc_nids || spec->adc_nids) {
2728 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2729 if (!kctl)
2730 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2731 for (i = 0; kctl && i < kctl->count; i++) {
2732 hda_nid_t *nids = spec->capsrc_nids;
2733 if (!nids)
2734 nids = spec->adc_nids;
2735 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2736 if (err < 0)
2737 return err;
2740 if (spec->cap_mixer) {
2741 const char *kname = kctl ? kctl->id.name : NULL;
2742 for (knew = spec->cap_mixer; knew->name; knew++) {
2743 if (kname && strcmp(knew->name, kname) == 0)
2744 continue;
2745 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2746 for (i = 0; kctl && i < kctl->count; i++) {
2747 err = snd_hda_add_nid(codec, kctl, i,
2748 spec->adc_nids[i]);
2749 if (err < 0)
2750 return err;
2755 /* other nid->control mapping */
2756 for (i = 0; i < spec->num_mixers; i++) {
2757 for (knew = spec->mixers[i]; knew->name; knew++) {
2758 if (knew->iface != NID_MAPPING)
2759 continue;
2760 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2761 if (kctl == NULL)
2762 continue;
2763 u = knew->subdevice;
2764 for (j = 0; j < 4; j++, u >>= 8) {
2765 nid = u & 0x3f;
2766 if (nid == 0)
2767 continue;
2768 switch (u & 0xc0) {
2769 case SUBDEV_SPEAKER_:
2770 nid = spec->autocfg.speaker_pins[nid];
2771 break;
2772 case SUBDEV_LINE_:
2773 nid = spec->autocfg.line_out_pins[nid];
2774 break;
2775 case SUBDEV_HP_:
2776 nid = spec->autocfg.hp_pins[nid];
2777 break;
2778 default:
2779 continue;
2781 err = snd_hda_add_nid(codec, kctl, 0, nid);
2782 if (err < 0)
2783 return err;
2785 u = knew->private_value;
2786 for (j = 0; j < 4; j++, u >>= 8) {
2787 nid = u & 0xff;
2788 if (nid == 0)
2789 continue;
2790 err = snd_hda_add_nid(codec, kctl, 0, nid);
2791 if (err < 0)
2792 return err;
2797 alc_free_kctls(codec); /* no longer needed */
2799 return 0;
2804 * initialize the codec volumes, etc
2808 * generic initialization of ADC, input mixers and output mixers
2810 static struct hda_verb alc880_volume_init_verbs[] = {
2812 * Unmute ADC0-2 and set the default input to mic-in
2814 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2816 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2817 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2818 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2819 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2821 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2822 * mixer widget
2823 * Note: PASD motherboards uses the Line In 2 as the input for front
2824 * panel mic (mic 2)
2826 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2827 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2833 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2836 * Set up output mixers (0x0c - 0x0f)
2838 /* set vol=0 to output mixers */
2839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2840 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2841 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2842 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2843 /* set up input amps for analog loopback */
2844 /* Amp Indices: DAC = 0, mixer = 1 */
2845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2847 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2848 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2849 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2850 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2852 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2858 * 3-stack pin configuration:
2859 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2861 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2863 * preset connection lists of input pins
2864 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2866 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2867 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2868 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2871 * Set pin mode and muting
2873 /* set front pin widgets 0x14 for output */
2874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2875 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2876 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2877 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2878 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2879 /* Mic2 (as headphone out) for HP output */
2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2882 /* Line In pin widget for input */
2883 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2884 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2885 /* Line2 (as front mic) pin widget for input and vref at 80% */
2886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2888 /* CD pin widget for input */
2889 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2895 * 5-stack pin configuration:
2896 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2897 * line-in/side = 0x1a, f-mic = 0x1b
2899 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2901 * preset connection lists of input pins
2902 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2904 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2905 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2908 * Set pin mode and muting
2910 /* set pin widgets 0x14-0x17 for output */
2911 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2913 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2914 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2915 /* unmute pins for output (no gain on this amp) */
2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2919 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2921 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2922 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2923 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2924 /* Mic2 (as headphone out) for HP output */
2925 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2926 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2927 /* Line In pin widget for input */
2928 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2929 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2930 /* Line2 (as front mic) pin widget for input and vref at 80% */
2931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2932 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2933 /* CD pin widget for input */
2934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2940 * W810 pin configuration:
2941 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2943 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2944 /* hphone/speaker input selector: front DAC */
2945 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2947 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2948 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2949 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2955 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2961 * Z71V pin configuration:
2962 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2964 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2970 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2979 * 6-stack pin configuration:
2980 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2981 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2983 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2987 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2991 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2992 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2993 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2995 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2996 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2998 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2999 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3000 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3001 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3002 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3003 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3009 * Uniwill pin configuration:
3010 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3011 * line = 0x1a
3013 static struct hda_verb alc880_uniwill_init_verbs[] = {
3014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3017 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3020 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3021 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3023 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3024 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3026 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3028 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3036 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3037 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3038 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3039 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3041 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3048 * Uniwill P53
3049 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3051 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3062 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3064 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3069 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3074 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3075 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3080 static struct hda_verb alc880_beep_init_verbs[] = {
3081 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3085 /* auto-toggle front mic */
3086 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
3088 unsigned int present;
3089 unsigned char bits;
3091 present = snd_hda_jack_detect(codec, 0x18);
3092 bits = present ? HDA_AMP_MUTE : 0;
3093 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3096 static void alc880_uniwill_setup(struct hda_codec *codec)
3098 struct alc_spec *spec = codec->spec;
3100 spec->autocfg.hp_pins[0] = 0x14;
3101 spec->autocfg.speaker_pins[0] = 0x15;
3102 spec->autocfg.speaker_pins[0] = 0x16;
3105 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3107 alc_automute_amp(codec);
3108 alc880_uniwill_mic_automute(codec);
3111 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3112 unsigned int res)
3114 /* Looks like the unsol event is incompatible with the standard
3115 * definition. 4bit tag is placed at 28 bit!
3117 switch (res >> 28) {
3118 case ALC880_MIC_EVENT:
3119 alc880_uniwill_mic_automute(codec);
3120 break;
3121 default:
3122 alc_automute_amp_unsol_event(codec, res);
3123 break;
3127 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3129 struct alc_spec *spec = codec->spec;
3131 spec->autocfg.hp_pins[0] = 0x14;
3132 spec->autocfg.speaker_pins[0] = 0x15;
3135 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3137 unsigned int present;
3139 present = snd_hda_codec_read(codec, 0x21, 0,
3140 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3141 present &= HDA_AMP_VOLMASK;
3142 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3143 HDA_AMP_VOLMASK, present);
3144 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3145 HDA_AMP_VOLMASK, present);
3148 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3149 unsigned int res)
3151 /* Looks like the unsol event is incompatible with the standard
3152 * definition. 4bit tag is placed at 28 bit!
3154 if ((res >> 28) == ALC880_DCVOL_EVENT)
3155 alc880_uniwill_p53_dcvol_automute(codec);
3156 else
3157 alc_automute_amp_unsol_event(codec, res);
3161 * F1734 pin configuration:
3162 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3164 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3165 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3166 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3167 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3168 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3169 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3173 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3174 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3176 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3177 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3180 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3181 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3184 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3187 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3193 * ASUS pin configuration:
3194 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3196 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3197 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3198 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3199 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3200 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3203 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3204 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3206 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3209 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3211 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3212 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3216 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3217 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3218 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3219 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3224 /* Enable GPIO mask and set output */
3225 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3226 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3227 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3229 /* Clevo m520g init */
3230 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3231 /* headphone output */
3232 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3233 /* line-out */
3234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3236 /* Line-in */
3237 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 /* CD */
3240 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3241 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3242 /* Mic1 (rear panel) */
3243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3244 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3245 /* Mic2 (front panel) */
3246 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3248 /* headphone */
3249 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3250 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3251 /* change to EAPD mode */
3252 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3253 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3258 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3259 /* change to EAPD mode */
3260 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3261 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3263 /* Headphone output */
3264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3265 /* Front output*/
3266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3267 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3269 /* Line In pin widget for input */
3270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3271 /* CD pin widget for input */
3272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3273 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3274 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3276 /* change to EAPD mode */
3277 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3278 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3284 * LG m1 express dual
3286 * Pin assignment:
3287 * Rear Line-In/Out (blue): 0x14
3288 * Build-in Mic-In: 0x15
3289 * Speaker-out: 0x17
3290 * HP-Out (green): 0x1b
3291 * Mic-In/Out (red): 0x19
3292 * SPDIF-Out: 0x1e
3295 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3296 static hda_nid_t alc880_lg_dac_nids[3] = {
3297 0x05, 0x02, 0x03
3300 /* seems analog CD is not working */
3301 static struct hda_input_mux alc880_lg_capture_source = {
3302 .num_items = 3,
3303 .items = {
3304 { "Mic", 0x1 },
3305 { "Line", 0x5 },
3306 { "Internal Mic", 0x6 },
3310 /* 2,4,6 channel modes */
3311 static struct hda_verb alc880_lg_ch2_init[] = {
3312 /* set line-in and mic-in to input */
3313 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3314 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3318 static struct hda_verb alc880_lg_ch4_init[] = {
3319 /* set line-in to out and mic-in to input */
3320 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3321 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3325 static struct hda_verb alc880_lg_ch6_init[] = {
3326 /* set line-in and mic-in to output */
3327 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3328 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3332 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3333 { 2, alc880_lg_ch2_init },
3334 { 4, alc880_lg_ch4_init },
3335 { 6, alc880_lg_ch6_init },
3338 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3340 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3341 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3342 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3343 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3344 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3345 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3346 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3347 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3348 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3351 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3352 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3354 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3355 .name = "Channel Mode",
3356 .info = alc_ch_mode_info,
3357 .get = alc_ch_mode_get,
3358 .put = alc_ch_mode_put,
3360 { } /* end */
3363 static struct hda_verb alc880_lg_init_verbs[] = {
3364 /* set capture source to mic-in */
3365 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3368 /* mute all amp mixer inputs */
3369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3372 /* line-in to input */
3373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3375 /* built-in mic */
3376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3378 /* speaker-out */
3379 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3380 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3381 /* mic-in to input */
3382 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3383 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3384 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3385 /* HP-out */
3386 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3387 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3388 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3389 /* jack sense */
3390 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3394 /* toggle speaker-output according to the hp-jack state */
3395 static void alc880_lg_setup(struct hda_codec *codec)
3397 struct alc_spec *spec = codec->spec;
3399 spec->autocfg.hp_pins[0] = 0x1b;
3400 spec->autocfg.speaker_pins[0] = 0x17;
3404 * LG LW20
3406 * Pin assignment:
3407 * Speaker-out: 0x14
3408 * Mic-In: 0x18
3409 * Built-in Mic-In: 0x19
3410 * Line-In: 0x1b
3411 * HP-Out: 0x1a
3412 * SPDIF-Out: 0x1e
3415 static struct hda_input_mux alc880_lg_lw_capture_source = {
3416 .num_items = 3,
3417 .items = {
3418 { "Mic", 0x0 },
3419 { "Internal Mic", 0x1 },
3420 { "Line In", 0x2 },
3424 #define alc880_lg_lw_modes alc880_threestack_modes
3426 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3427 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3428 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3430 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3439 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3440 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3443 .name = "Channel Mode",
3444 .info = alc_ch_mode_info,
3445 .get = alc_ch_mode_get,
3446 .put = alc_ch_mode_put,
3448 { } /* end */
3451 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3452 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3453 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3454 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3456 /* set capture source to mic-in */
3457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3459 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3461 /* speaker-out */
3462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 /* HP-out */
3465 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3466 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467 /* mic-in to input */
3468 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3470 /* built-in mic */
3471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3473 /* jack sense */
3474 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3478 /* toggle speaker-output according to the hp-jack state */
3479 static void alc880_lg_lw_setup(struct hda_codec *codec)
3481 struct alc_spec *spec = codec->spec;
3483 spec->autocfg.hp_pins[0] = 0x1b;
3484 spec->autocfg.speaker_pins[0] = 0x14;
3487 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3488 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3489 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3492 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3493 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3494 { } /* end */
3497 static struct hda_input_mux alc880_medion_rim_capture_source = {
3498 .num_items = 2,
3499 .items = {
3500 { "Mic", 0x0 },
3501 { "Internal Mic", 0x1 },
3505 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3506 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3511 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3514 /* Mic2 (as headphone out) for HP output */
3515 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3516 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3517 /* Internal Speaker */
3518 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3522 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3528 /* toggle speaker-output according to the hp-jack state */
3529 static void alc880_medion_rim_automute(struct hda_codec *codec)
3531 struct alc_spec *spec = codec->spec;
3532 alc_automute_amp(codec);
3533 /* toggle EAPD */
3534 if (spec->jack_present)
3535 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3536 else
3537 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3540 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3541 unsigned int res)
3543 /* Looks like the unsol event is incompatible with the standard
3544 * definition. 4bit tag is placed at 28 bit!
3546 if ((res >> 28) == ALC880_HP_EVENT)
3547 alc880_medion_rim_automute(codec);
3550 static void alc880_medion_rim_setup(struct hda_codec *codec)
3552 struct alc_spec *spec = codec->spec;
3554 spec->autocfg.hp_pins[0] = 0x14;
3555 spec->autocfg.speaker_pins[0] = 0x1b;
3558 #ifdef CONFIG_SND_HDA_POWER_SAVE
3559 static struct hda_amp_list alc880_loopbacks[] = {
3560 { 0x0b, HDA_INPUT, 0 },
3561 { 0x0b, HDA_INPUT, 1 },
3562 { 0x0b, HDA_INPUT, 2 },
3563 { 0x0b, HDA_INPUT, 3 },
3564 { 0x0b, HDA_INPUT, 4 },
3565 { } /* end */
3568 static struct hda_amp_list alc880_lg_loopbacks[] = {
3569 { 0x0b, HDA_INPUT, 1 },
3570 { 0x0b, HDA_INPUT, 6 },
3571 { 0x0b, HDA_INPUT, 7 },
3572 { } /* end */
3574 #endif
3577 * Common callbacks
3580 static int alc_init(struct hda_codec *codec)
3582 struct alc_spec *spec = codec->spec;
3583 unsigned int i;
3585 alc_fix_pll(codec);
3586 alc_auto_init_amp(codec, spec->init_amp);
3588 for (i = 0; i < spec->num_init_verbs; i++)
3589 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3591 if (spec->init_hook)
3592 spec->init_hook(codec);
3594 #ifdef CONFIG_SND_HDA_POWER_SAVE
3595 if (codec->patch_ops.check_power_status)
3596 codec->patch_ops.check_power_status(codec, 0x01);
3597 #endif
3598 return 0;
3601 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3603 struct alc_spec *spec = codec->spec;
3605 if (spec->unsol_event)
3606 spec->unsol_event(codec, res);
3609 #ifdef CONFIG_SND_HDA_POWER_SAVE
3610 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3612 struct alc_spec *spec = codec->spec;
3613 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3615 #endif
3618 * Analog playback callbacks
3620 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3621 struct hda_codec *codec,
3622 struct snd_pcm_substream *substream)
3624 struct alc_spec *spec = codec->spec;
3625 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3626 hinfo);
3629 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3630 struct hda_codec *codec,
3631 unsigned int stream_tag,
3632 unsigned int format,
3633 struct snd_pcm_substream *substream)
3635 struct alc_spec *spec = codec->spec;
3636 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3637 stream_tag, format, substream);
3640 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3641 struct hda_codec *codec,
3642 struct snd_pcm_substream *substream)
3644 struct alc_spec *spec = codec->spec;
3645 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3649 * Digital out
3651 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3652 struct hda_codec *codec,
3653 struct snd_pcm_substream *substream)
3655 struct alc_spec *spec = codec->spec;
3656 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3659 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3660 struct hda_codec *codec,
3661 unsigned int stream_tag,
3662 unsigned int format,
3663 struct snd_pcm_substream *substream)
3665 struct alc_spec *spec = codec->spec;
3666 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3667 stream_tag, format, substream);
3670 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3671 struct hda_codec *codec,
3672 struct snd_pcm_substream *substream)
3674 struct alc_spec *spec = codec->spec;
3675 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3678 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3679 struct hda_codec *codec,
3680 struct snd_pcm_substream *substream)
3682 struct alc_spec *spec = codec->spec;
3683 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3687 * Analog capture
3689 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3690 struct hda_codec *codec,
3691 unsigned int stream_tag,
3692 unsigned int format,
3693 struct snd_pcm_substream *substream)
3695 struct alc_spec *spec = codec->spec;
3697 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3698 stream_tag, 0, format);
3699 return 0;
3702 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3703 struct hda_codec *codec,
3704 struct snd_pcm_substream *substream)
3706 struct alc_spec *spec = codec->spec;
3708 snd_hda_codec_cleanup_stream(codec,
3709 spec->adc_nids[substream->number + 1]);
3710 return 0;
3713 /* analog capture with dynamic dual-adc changes */
3714 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3715 struct hda_codec *codec,
3716 unsigned int stream_tag,
3717 unsigned int format,
3718 struct snd_pcm_substream *substream)
3720 struct alc_spec *spec = codec->spec;
3721 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
3722 spec->cur_adc_stream_tag = stream_tag;
3723 spec->cur_adc_format = format;
3724 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
3725 return 0;
3728 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3729 struct hda_codec *codec,
3730 struct snd_pcm_substream *substream)
3732 struct alc_spec *spec = codec->spec;
3733 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3734 spec->cur_adc = 0;
3735 return 0;
3738 static struct hda_pcm_stream dualmic_pcm_analog_capture = {
3739 .substreams = 1,
3740 .channels_min = 2,
3741 .channels_max = 2,
3742 .nid = 0, /* fill later */
3743 .ops = {
3744 .prepare = dualmic_capture_pcm_prepare,
3745 .cleanup = dualmic_capture_pcm_cleanup
3751 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3752 .substreams = 1,
3753 .channels_min = 2,
3754 .channels_max = 8,
3755 /* NID is set in alc_build_pcms */
3756 .ops = {
3757 .open = alc880_playback_pcm_open,
3758 .prepare = alc880_playback_pcm_prepare,
3759 .cleanup = alc880_playback_pcm_cleanup
3763 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3764 .substreams = 1,
3765 .channels_min = 2,
3766 .channels_max = 2,
3767 /* NID is set in alc_build_pcms */
3770 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3771 .substreams = 1,
3772 .channels_min = 2,
3773 .channels_max = 2,
3774 /* NID is set in alc_build_pcms */
3777 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3778 .substreams = 2, /* can be overridden */
3779 .channels_min = 2,
3780 .channels_max = 2,
3781 /* NID is set in alc_build_pcms */
3782 .ops = {
3783 .prepare = alc880_alt_capture_pcm_prepare,
3784 .cleanup = alc880_alt_capture_pcm_cleanup
3788 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3789 .substreams = 1,
3790 .channels_min = 2,
3791 .channels_max = 2,
3792 /* NID is set in alc_build_pcms */
3793 .ops = {
3794 .open = alc880_dig_playback_pcm_open,
3795 .close = alc880_dig_playback_pcm_close,
3796 .prepare = alc880_dig_playback_pcm_prepare,
3797 .cleanup = alc880_dig_playback_pcm_cleanup
3801 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3802 .substreams = 1,
3803 .channels_min = 2,
3804 .channels_max = 2,
3805 /* NID is set in alc_build_pcms */
3808 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3809 static struct hda_pcm_stream alc_pcm_null_stream = {
3810 .substreams = 0,
3811 .channels_min = 0,
3812 .channels_max = 0,
3815 static int alc_build_pcms(struct hda_codec *codec)
3817 struct alc_spec *spec = codec->spec;
3818 struct hda_pcm *info = spec->pcm_rec;
3819 int i;
3821 codec->num_pcms = 1;
3822 codec->pcm_info = info;
3824 if (spec->no_analog)
3825 goto skip_analog;
3827 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3828 "%s Analog", codec->chip_name);
3829 info->name = spec->stream_name_analog;
3831 if (spec->stream_analog_playback) {
3832 if (snd_BUG_ON(!spec->multiout.dac_nids))
3833 return -EINVAL;
3834 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3835 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3837 if (spec->stream_analog_capture) {
3838 if (snd_BUG_ON(!spec->adc_nids))
3839 return -EINVAL;
3840 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3841 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3844 if (spec->channel_mode) {
3845 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3846 for (i = 0; i < spec->num_channel_mode; i++) {
3847 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3848 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3853 skip_analog:
3854 /* SPDIF for stream index #1 */
3855 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3856 snprintf(spec->stream_name_digital,
3857 sizeof(spec->stream_name_digital),
3858 "%s Digital", codec->chip_name);
3859 codec->num_pcms = 2;
3860 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3861 info = spec->pcm_rec + 1;
3862 info->name = spec->stream_name_digital;
3863 if (spec->dig_out_type)
3864 info->pcm_type = spec->dig_out_type;
3865 else
3866 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3867 if (spec->multiout.dig_out_nid &&
3868 spec->stream_digital_playback) {
3869 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3870 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3872 if (spec->dig_in_nid &&
3873 spec->stream_digital_capture) {
3874 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3875 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3877 /* FIXME: do we need this for all Realtek codec models? */
3878 codec->spdif_status_reset = 1;
3881 if (spec->no_analog)
3882 return 0;
3884 /* If the use of more than one ADC is requested for the current
3885 * model, configure a second analog capture-only PCM.
3887 /* Additional Analaog capture for index #2 */
3888 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3889 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3890 codec->num_pcms = 3;
3891 info = spec->pcm_rec + 2;
3892 info->name = spec->stream_name_analog;
3893 if (spec->alt_dac_nid) {
3894 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3895 *spec->stream_analog_alt_playback;
3896 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3897 spec->alt_dac_nid;
3898 } else {
3899 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3900 alc_pcm_null_stream;
3901 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3903 if (spec->num_adc_nids > 1) {
3904 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3905 *spec->stream_analog_alt_capture;
3906 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3907 spec->adc_nids[1];
3908 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3909 spec->num_adc_nids - 1;
3910 } else {
3911 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3912 alc_pcm_null_stream;
3913 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3917 return 0;
3920 static inline void alc_shutup(struct hda_codec *codec)
3922 snd_hda_shutup_pins(codec);
3925 static void alc_free_kctls(struct hda_codec *codec)
3927 struct alc_spec *spec = codec->spec;
3929 if (spec->kctls.list) {
3930 struct snd_kcontrol_new *kctl = spec->kctls.list;
3931 int i;
3932 for (i = 0; i < spec->kctls.used; i++)
3933 kfree(kctl[i].name);
3935 snd_array_free(&spec->kctls);
3938 static void alc_free(struct hda_codec *codec)
3940 struct alc_spec *spec = codec->spec;
3942 if (!spec)
3943 return;
3945 alc_shutup(codec);
3946 alc_free_kctls(codec);
3947 kfree(spec);
3948 snd_hda_detach_beep_device(codec);
3951 #ifdef CONFIG_SND_HDA_POWER_SAVE
3952 static void alc_power_eapd(struct hda_codec *codec)
3954 /* We currently only handle front, HP */
3955 switch (codec->vendor_id) {
3956 case 0x10ec0260:
3957 set_eapd(codec, 0x0f, 0);
3958 set_eapd(codec, 0x10, 0);
3959 break;
3960 case 0x10ec0262:
3961 case 0x10ec0267:
3962 case 0x10ec0268:
3963 case 0x10ec0269:
3964 case 0x10ec0270:
3965 case 0x10ec0272:
3966 case 0x10ec0660:
3967 case 0x10ec0662:
3968 case 0x10ec0663:
3969 case 0x10ec0862:
3970 case 0x10ec0889:
3971 set_eapd(codec, 0x14, 0);
3972 set_eapd(codec, 0x15, 0);
3973 break;
3977 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3979 struct alc_spec *spec = codec->spec;
3980 alc_shutup(codec);
3981 if (spec && spec->power_hook)
3982 spec->power_hook(codec);
3983 return 0;
3985 #endif
3987 #ifdef SND_HDA_NEEDS_RESUME
3988 static int alc_resume(struct hda_codec *codec)
3990 codec->patch_ops.init(codec);
3991 snd_hda_codec_resume_amp(codec);
3992 snd_hda_codec_resume_cache(codec);
3993 #ifdef CONFIG_SND_HDA_POWER_SAVE
3994 if (codec->patch_ops.check_power_status)
3995 codec->patch_ops.check_power_status(codec, 0x01);
3996 #endif
3997 return 0;
3999 #endif
4003 static struct hda_codec_ops alc_patch_ops = {
4004 .build_controls = alc_build_controls,
4005 .build_pcms = alc_build_pcms,
4006 .init = alc_init,
4007 .free = alc_free,
4008 .unsol_event = alc_unsol_event,
4009 #ifdef SND_HDA_NEEDS_RESUME
4010 .resume = alc_resume,
4011 #endif
4012 #ifdef CONFIG_SND_HDA_POWER_SAVE
4013 .suspend = alc_suspend,
4014 .check_power_status = alc_check_power_status,
4015 #endif
4016 .reboot_notify = alc_shutup,
4019 /* replace the codec chip_name with the given string */
4020 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4022 kfree(codec->chip_name);
4023 codec->chip_name = kstrdup(name, GFP_KERNEL);
4024 if (!codec->chip_name) {
4025 alc_free(codec);
4026 return -ENOMEM;
4028 return 0;
4032 * Test configuration for debugging
4034 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4035 * enum controls.
4037 #ifdef CONFIG_SND_DEBUG
4038 static hda_nid_t alc880_test_dac_nids[4] = {
4039 0x02, 0x03, 0x04, 0x05
4042 static struct hda_input_mux alc880_test_capture_source = {
4043 .num_items = 7,
4044 .items = {
4045 { "In-1", 0x0 },
4046 { "In-2", 0x1 },
4047 { "In-3", 0x2 },
4048 { "In-4", 0x3 },
4049 { "CD", 0x4 },
4050 { "Front", 0x5 },
4051 { "Surround", 0x6 },
4055 static struct hda_channel_mode alc880_test_modes[4] = {
4056 { 2, NULL },
4057 { 4, NULL },
4058 { 6, NULL },
4059 { 8, NULL },
4062 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4063 struct snd_ctl_elem_info *uinfo)
4065 static char *texts[] = {
4066 "N/A", "Line Out", "HP Out",
4067 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4069 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4070 uinfo->count = 1;
4071 uinfo->value.enumerated.items = 8;
4072 if (uinfo->value.enumerated.item >= 8)
4073 uinfo->value.enumerated.item = 7;
4074 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4075 return 0;
4078 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4079 struct snd_ctl_elem_value *ucontrol)
4081 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4082 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4083 unsigned int pin_ctl, item = 0;
4085 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4086 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4087 if (pin_ctl & AC_PINCTL_OUT_EN) {
4088 if (pin_ctl & AC_PINCTL_HP_EN)
4089 item = 2;
4090 else
4091 item = 1;
4092 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4093 switch (pin_ctl & AC_PINCTL_VREFEN) {
4094 case AC_PINCTL_VREF_HIZ: item = 3; break;
4095 case AC_PINCTL_VREF_50: item = 4; break;
4096 case AC_PINCTL_VREF_GRD: item = 5; break;
4097 case AC_PINCTL_VREF_80: item = 6; break;
4098 case AC_PINCTL_VREF_100: item = 7; break;
4101 ucontrol->value.enumerated.item[0] = item;
4102 return 0;
4105 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4106 struct snd_ctl_elem_value *ucontrol)
4108 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4109 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4110 static unsigned int ctls[] = {
4111 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4112 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4113 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4114 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4115 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4116 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4118 unsigned int old_ctl, new_ctl;
4120 old_ctl = snd_hda_codec_read(codec, nid, 0,
4121 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4122 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4123 if (old_ctl != new_ctl) {
4124 int val;
4125 snd_hda_codec_write_cache(codec, nid, 0,
4126 AC_VERB_SET_PIN_WIDGET_CONTROL,
4127 new_ctl);
4128 val = ucontrol->value.enumerated.item[0] >= 3 ?
4129 HDA_AMP_MUTE : 0;
4130 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4131 HDA_AMP_MUTE, val);
4132 return 1;
4134 return 0;
4137 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4138 struct snd_ctl_elem_info *uinfo)
4140 static char *texts[] = {
4141 "Front", "Surround", "CLFE", "Side"
4143 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4144 uinfo->count = 1;
4145 uinfo->value.enumerated.items = 4;
4146 if (uinfo->value.enumerated.item >= 4)
4147 uinfo->value.enumerated.item = 3;
4148 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4149 return 0;
4152 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4153 struct snd_ctl_elem_value *ucontrol)
4155 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4156 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4157 unsigned int sel;
4159 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4160 ucontrol->value.enumerated.item[0] = sel & 3;
4161 return 0;
4164 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4165 struct snd_ctl_elem_value *ucontrol)
4167 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4168 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4169 unsigned int sel;
4171 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4172 if (ucontrol->value.enumerated.item[0] != sel) {
4173 sel = ucontrol->value.enumerated.item[0] & 3;
4174 snd_hda_codec_write_cache(codec, nid, 0,
4175 AC_VERB_SET_CONNECT_SEL, sel);
4176 return 1;
4178 return 0;
4181 #define PIN_CTL_TEST(xname,nid) { \
4182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4183 .name = xname, \
4184 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4185 .info = alc_test_pin_ctl_info, \
4186 .get = alc_test_pin_ctl_get, \
4187 .put = alc_test_pin_ctl_put, \
4188 .private_value = nid \
4191 #define PIN_SRC_TEST(xname,nid) { \
4192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4193 .name = xname, \
4194 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4195 .info = alc_test_pin_src_info, \
4196 .get = alc_test_pin_src_get, \
4197 .put = alc_test_pin_src_put, \
4198 .private_value = nid \
4201 static struct snd_kcontrol_new alc880_test_mixer[] = {
4202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4204 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4208 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4210 PIN_CTL_TEST("Front Pin Mode", 0x14),
4211 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4212 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4213 PIN_CTL_TEST("Side Pin Mode", 0x17),
4214 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4215 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4216 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4217 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4218 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4219 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4220 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4221 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4222 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4223 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4224 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4225 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4226 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4227 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4228 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4229 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4233 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4234 .name = "Channel Mode",
4235 .info = alc_ch_mode_info,
4236 .get = alc_ch_mode_get,
4237 .put = alc_ch_mode_put,
4239 { } /* end */
4242 static struct hda_verb alc880_test_init_verbs[] = {
4243 /* Unmute inputs of 0x0c - 0x0f */
4244 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4245 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4246 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4247 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4248 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4252 /* Vol output for 0x0c-0x0f */
4253 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4254 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4257 /* Set output pins 0x14-0x17 */
4258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4260 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4261 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4262 /* Unmute output pins 0x14-0x17 */
4263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4264 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4265 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4267 /* Set input pins 0x18-0x1c */
4268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4269 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4270 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4271 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4272 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4273 /* Mute input pins 0x18-0x1b */
4274 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4275 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4276 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4278 /* ADC set up */
4279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4280 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4281 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4282 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4283 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4284 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4285 /* Analog input/passthru */
4286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4293 #endif
4298 static const char *alc880_models[ALC880_MODEL_LAST] = {
4299 [ALC880_3ST] = "3stack",
4300 [ALC880_TCL_S700] = "tcl",
4301 [ALC880_3ST_DIG] = "3stack-digout",
4302 [ALC880_CLEVO] = "clevo",
4303 [ALC880_5ST] = "5stack",
4304 [ALC880_5ST_DIG] = "5stack-digout",
4305 [ALC880_W810] = "w810",
4306 [ALC880_Z71V] = "z71v",
4307 [ALC880_6ST] = "6stack",
4308 [ALC880_6ST_DIG] = "6stack-digout",
4309 [ALC880_ASUS] = "asus",
4310 [ALC880_ASUS_W1V] = "asus-w1v",
4311 [ALC880_ASUS_DIG] = "asus-dig",
4312 [ALC880_ASUS_DIG2] = "asus-dig2",
4313 [ALC880_UNIWILL_DIG] = "uniwill",
4314 [ALC880_UNIWILL_P53] = "uniwill-p53",
4315 [ALC880_FUJITSU] = "fujitsu",
4316 [ALC880_F1734] = "F1734",
4317 [ALC880_LG] = "lg",
4318 [ALC880_LG_LW] = "lg-lw",
4319 [ALC880_MEDION_RIM] = "medion",
4320 #ifdef CONFIG_SND_DEBUG
4321 [ALC880_TEST] = "test",
4322 #endif
4323 [ALC880_AUTO] = "auto",
4326 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4327 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4328 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4329 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4330 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4331 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4332 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4333 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4334 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4335 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4336 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4337 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4338 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4339 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4340 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4341 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4342 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4343 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4344 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4345 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4346 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4347 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4348 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4349 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4350 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4351 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4352 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4353 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4354 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4355 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4356 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4357 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4358 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4359 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4360 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4361 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4362 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4363 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4364 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4365 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4366 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4367 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4368 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4369 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4370 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4371 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4372 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4373 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4374 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4375 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4376 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4377 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4378 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4379 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4380 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4381 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4382 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4383 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4384 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4385 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4386 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4387 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4388 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4389 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4390 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4391 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4392 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4393 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4394 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4395 /* default Intel */
4396 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4397 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4398 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4403 * ALC880 codec presets
4405 static struct alc_config_preset alc880_presets[] = {
4406 [ALC880_3ST] = {
4407 .mixers = { alc880_three_stack_mixer },
4408 .init_verbs = { alc880_volume_init_verbs,
4409 alc880_pin_3stack_init_verbs },
4410 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4411 .dac_nids = alc880_dac_nids,
4412 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4413 .channel_mode = alc880_threestack_modes,
4414 .need_dac_fix = 1,
4415 .input_mux = &alc880_capture_source,
4417 [ALC880_3ST_DIG] = {
4418 .mixers = { alc880_three_stack_mixer },
4419 .init_verbs = { alc880_volume_init_verbs,
4420 alc880_pin_3stack_init_verbs },
4421 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4422 .dac_nids = alc880_dac_nids,
4423 .dig_out_nid = ALC880_DIGOUT_NID,
4424 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4425 .channel_mode = alc880_threestack_modes,
4426 .need_dac_fix = 1,
4427 .input_mux = &alc880_capture_source,
4429 [ALC880_TCL_S700] = {
4430 .mixers = { alc880_tcl_s700_mixer },
4431 .init_verbs = { alc880_volume_init_verbs,
4432 alc880_pin_tcl_S700_init_verbs,
4433 alc880_gpio2_init_verbs },
4434 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4435 .dac_nids = alc880_dac_nids,
4436 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4437 .num_adc_nids = 1, /* single ADC */
4438 .hp_nid = 0x03,
4439 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4440 .channel_mode = alc880_2_jack_modes,
4441 .input_mux = &alc880_capture_source,
4443 [ALC880_5ST] = {
4444 .mixers = { alc880_three_stack_mixer,
4445 alc880_five_stack_mixer},
4446 .init_verbs = { alc880_volume_init_verbs,
4447 alc880_pin_5stack_init_verbs },
4448 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4449 .dac_nids = alc880_dac_nids,
4450 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4451 .channel_mode = alc880_fivestack_modes,
4452 .input_mux = &alc880_capture_source,
4454 [ALC880_5ST_DIG] = {
4455 .mixers = { alc880_three_stack_mixer,
4456 alc880_five_stack_mixer },
4457 .init_verbs = { alc880_volume_init_verbs,
4458 alc880_pin_5stack_init_verbs },
4459 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4460 .dac_nids = alc880_dac_nids,
4461 .dig_out_nid = ALC880_DIGOUT_NID,
4462 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4463 .channel_mode = alc880_fivestack_modes,
4464 .input_mux = &alc880_capture_source,
4466 [ALC880_6ST] = {
4467 .mixers = { alc880_six_stack_mixer },
4468 .init_verbs = { alc880_volume_init_verbs,
4469 alc880_pin_6stack_init_verbs },
4470 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4471 .dac_nids = alc880_6st_dac_nids,
4472 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4473 .channel_mode = alc880_sixstack_modes,
4474 .input_mux = &alc880_6stack_capture_source,
4476 [ALC880_6ST_DIG] = {
4477 .mixers = { alc880_six_stack_mixer },
4478 .init_verbs = { alc880_volume_init_verbs,
4479 alc880_pin_6stack_init_verbs },
4480 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4481 .dac_nids = alc880_6st_dac_nids,
4482 .dig_out_nid = ALC880_DIGOUT_NID,
4483 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4484 .channel_mode = alc880_sixstack_modes,
4485 .input_mux = &alc880_6stack_capture_source,
4487 [ALC880_W810] = {
4488 .mixers = { alc880_w810_base_mixer },
4489 .init_verbs = { alc880_volume_init_verbs,
4490 alc880_pin_w810_init_verbs,
4491 alc880_gpio2_init_verbs },
4492 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4493 .dac_nids = alc880_w810_dac_nids,
4494 .dig_out_nid = ALC880_DIGOUT_NID,
4495 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4496 .channel_mode = alc880_w810_modes,
4497 .input_mux = &alc880_capture_source,
4499 [ALC880_Z71V] = {
4500 .mixers = { alc880_z71v_mixer },
4501 .init_verbs = { alc880_volume_init_verbs,
4502 alc880_pin_z71v_init_verbs },
4503 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4504 .dac_nids = alc880_z71v_dac_nids,
4505 .dig_out_nid = ALC880_DIGOUT_NID,
4506 .hp_nid = 0x03,
4507 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4508 .channel_mode = alc880_2_jack_modes,
4509 .input_mux = &alc880_capture_source,
4511 [ALC880_F1734] = {
4512 .mixers = { alc880_f1734_mixer },
4513 .init_verbs = { alc880_volume_init_verbs,
4514 alc880_pin_f1734_init_verbs },
4515 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4516 .dac_nids = alc880_f1734_dac_nids,
4517 .hp_nid = 0x02,
4518 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4519 .channel_mode = alc880_2_jack_modes,
4520 .input_mux = &alc880_f1734_capture_source,
4521 .unsol_event = alc880_uniwill_p53_unsol_event,
4522 .setup = alc880_uniwill_p53_setup,
4523 .init_hook = alc_automute_amp,
4525 [ALC880_ASUS] = {
4526 .mixers = { alc880_asus_mixer },
4527 .init_verbs = { alc880_volume_init_verbs,
4528 alc880_pin_asus_init_verbs,
4529 alc880_gpio1_init_verbs },
4530 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4531 .dac_nids = alc880_asus_dac_nids,
4532 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4533 .channel_mode = alc880_asus_modes,
4534 .need_dac_fix = 1,
4535 .input_mux = &alc880_capture_source,
4537 [ALC880_ASUS_DIG] = {
4538 .mixers = { alc880_asus_mixer },
4539 .init_verbs = { alc880_volume_init_verbs,
4540 alc880_pin_asus_init_verbs,
4541 alc880_gpio1_init_verbs },
4542 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4543 .dac_nids = alc880_asus_dac_nids,
4544 .dig_out_nid = ALC880_DIGOUT_NID,
4545 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4546 .channel_mode = alc880_asus_modes,
4547 .need_dac_fix = 1,
4548 .input_mux = &alc880_capture_source,
4550 [ALC880_ASUS_DIG2] = {
4551 .mixers = { alc880_asus_mixer },
4552 .init_verbs = { alc880_volume_init_verbs,
4553 alc880_pin_asus_init_verbs,
4554 alc880_gpio2_init_verbs }, /* use GPIO2 */
4555 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4556 .dac_nids = alc880_asus_dac_nids,
4557 .dig_out_nid = ALC880_DIGOUT_NID,
4558 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4559 .channel_mode = alc880_asus_modes,
4560 .need_dac_fix = 1,
4561 .input_mux = &alc880_capture_source,
4563 [ALC880_ASUS_W1V] = {
4564 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4565 .init_verbs = { alc880_volume_init_verbs,
4566 alc880_pin_asus_init_verbs,
4567 alc880_gpio1_init_verbs },
4568 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4569 .dac_nids = alc880_asus_dac_nids,
4570 .dig_out_nid = ALC880_DIGOUT_NID,
4571 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4572 .channel_mode = alc880_asus_modes,
4573 .need_dac_fix = 1,
4574 .input_mux = &alc880_capture_source,
4576 [ALC880_UNIWILL_DIG] = {
4577 .mixers = { alc880_asus_mixer },
4578 .init_verbs = { alc880_volume_init_verbs,
4579 alc880_pin_asus_init_verbs },
4580 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4581 .dac_nids = alc880_asus_dac_nids,
4582 .dig_out_nid = ALC880_DIGOUT_NID,
4583 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4584 .channel_mode = alc880_asus_modes,
4585 .need_dac_fix = 1,
4586 .input_mux = &alc880_capture_source,
4588 [ALC880_UNIWILL] = {
4589 .mixers = { alc880_uniwill_mixer },
4590 .init_verbs = { alc880_volume_init_verbs,
4591 alc880_uniwill_init_verbs },
4592 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4593 .dac_nids = alc880_asus_dac_nids,
4594 .dig_out_nid = ALC880_DIGOUT_NID,
4595 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4596 .channel_mode = alc880_threestack_modes,
4597 .need_dac_fix = 1,
4598 .input_mux = &alc880_capture_source,
4599 .unsol_event = alc880_uniwill_unsol_event,
4600 .setup = alc880_uniwill_setup,
4601 .init_hook = alc880_uniwill_init_hook,
4603 [ALC880_UNIWILL_P53] = {
4604 .mixers = { alc880_uniwill_p53_mixer },
4605 .init_verbs = { alc880_volume_init_verbs,
4606 alc880_uniwill_p53_init_verbs },
4607 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4608 .dac_nids = alc880_asus_dac_nids,
4609 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4610 .channel_mode = alc880_threestack_modes,
4611 .input_mux = &alc880_capture_source,
4612 .unsol_event = alc880_uniwill_p53_unsol_event,
4613 .setup = alc880_uniwill_p53_setup,
4614 .init_hook = alc_automute_amp,
4616 [ALC880_FUJITSU] = {
4617 .mixers = { alc880_fujitsu_mixer },
4618 .init_verbs = { alc880_volume_init_verbs,
4619 alc880_uniwill_p53_init_verbs,
4620 alc880_beep_init_verbs },
4621 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4622 .dac_nids = alc880_dac_nids,
4623 .dig_out_nid = ALC880_DIGOUT_NID,
4624 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4625 .channel_mode = alc880_2_jack_modes,
4626 .input_mux = &alc880_capture_source,
4627 .unsol_event = alc880_uniwill_p53_unsol_event,
4628 .setup = alc880_uniwill_p53_setup,
4629 .init_hook = alc_automute_amp,
4631 [ALC880_CLEVO] = {
4632 .mixers = { alc880_three_stack_mixer },
4633 .init_verbs = { alc880_volume_init_verbs,
4634 alc880_pin_clevo_init_verbs },
4635 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4636 .dac_nids = alc880_dac_nids,
4637 .hp_nid = 0x03,
4638 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4639 .channel_mode = alc880_threestack_modes,
4640 .need_dac_fix = 1,
4641 .input_mux = &alc880_capture_source,
4643 [ALC880_LG] = {
4644 .mixers = { alc880_lg_mixer },
4645 .init_verbs = { alc880_volume_init_verbs,
4646 alc880_lg_init_verbs },
4647 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4648 .dac_nids = alc880_lg_dac_nids,
4649 .dig_out_nid = ALC880_DIGOUT_NID,
4650 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4651 .channel_mode = alc880_lg_ch_modes,
4652 .need_dac_fix = 1,
4653 .input_mux = &alc880_lg_capture_source,
4654 .unsol_event = alc_automute_amp_unsol_event,
4655 .setup = alc880_lg_setup,
4656 .init_hook = alc_automute_amp,
4657 #ifdef CONFIG_SND_HDA_POWER_SAVE
4658 .loopbacks = alc880_lg_loopbacks,
4659 #endif
4661 [ALC880_LG_LW] = {
4662 .mixers = { alc880_lg_lw_mixer },
4663 .init_verbs = { alc880_volume_init_verbs,
4664 alc880_lg_lw_init_verbs },
4665 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4666 .dac_nids = alc880_dac_nids,
4667 .dig_out_nid = ALC880_DIGOUT_NID,
4668 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4669 .channel_mode = alc880_lg_lw_modes,
4670 .input_mux = &alc880_lg_lw_capture_source,
4671 .unsol_event = alc_automute_amp_unsol_event,
4672 .setup = alc880_lg_lw_setup,
4673 .init_hook = alc_automute_amp,
4675 [ALC880_MEDION_RIM] = {
4676 .mixers = { alc880_medion_rim_mixer },
4677 .init_verbs = { alc880_volume_init_verbs,
4678 alc880_medion_rim_init_verbs,
4679 alc_gpio2_init_verbs },
4680 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4681 .dac_nids = alc880_dac_nids,
4682 .dig_out_nid = ALC880_DIGOUT_NID,
4683 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4684 .channel_mode = alc880_2_jack_modes,
4685 .input_mux = &alc880_medion_rim_capture_source,
4686 .unsol_event = alc880_medion_rim_unsol_event,
4687 .setup = alc880_medion_rim_setup,
4688 .init_hook = alc880_medion_rim_automute,
4690 #ifdef CONFIG_SND_DEBUG
4691 [ALC880_TEST] = {
4692 .mixers = { alc880_test_mixer },
4693 .init_verbs = { alc880_test_init_verbs },
4694 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4695 .dac_nids = alc880_test_dac_nids,
4696 .dig_out_nid = ALC880_DIGOUT_NID,
4697 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4698 .channel_mode = alc880_test_modes,
4699 .input_mux = &alc880_test_capture_source,
4701 #endif
4705 * Automatic parse of I/O pins from the BIOS configuration
4708 enum {
4709 ALC_CTL_WIDGET_VOL,
4710 ALC_CTL_WIDGET_MUTE,
4711 ALC_CTL_BIND_MUTE,
4713 static struct snd_kcontrol_new alc880_control_templates[] = {
4714 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4715 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4716 HDA_BIND_MUTE(NULL, 0, 0, 0),
4719 /* add dynamic controls */
4720 static int add_control(struct alc_spec *spec, int type, const char *name,
4721 unsigned long val)
4723 struct snd_kcontrol_new *knew;
4725 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4726 knew = snd_array_new(&spec->kctls);
4727 if (!knew)
4728 return -ENOMEM;
4729 *knew = alc880_control_templates[type];
4730 knew->name = kstrdup(name, GFP_KERNEL);
4731 if (!knew->name)
4732 return -ENOMEM;
4733 if (get_amp_nid_(val))
4734 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4735 knew->private_value = val;
4736 return 0;
4739 static int add_control_with_pfx(struct alc_spec *spec, int type,
4740 const char *pfx, const char *dir,
4741 const char *sfx, unsigned long val)
4743 char name[32];
4744 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4745 return add_control(spec, type, name, val);
4748 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4749 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4750 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4751 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4753 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4754 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4755 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4756 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4757 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4758 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4759 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4760 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4761 #define ALC880_PIN_CD_NID 0x1c
4763 /* fill in the dac_nids table from the parsed pin configuration */
4764 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4765 const struct auto_pin_cfg *cfg)
4767 hda_nid_t nid;
4768 int assigned[4];
4769 int i, j;
4771 memset(assigned, 0, sizeof(assigned));
4772 spec->multiout.dac_nids = spec->private_dac_nids;
4774 /* check the pins hardwired to audio widget */
4775 for (i = 0; i < cfg->line_outs; i++) {
4776 nid = cfg->line_out_pins[i];
4777 if (alc880_is_fixed_pin(nid)) {
4778 int idx = alc880_fixed_pin_idx(nid);
4779 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4780 assigned[idx] = 1;
4783 /* left pins can be connect to any audio widget */
4784 for (i = 0; i < cfg->line_outs; i++) {
4785 nid = cfg->line_out_pins[i];
4786 if (alc880_is_fixed_pin(nid))
4787 continue;
4788 /* search for an empty channel */
4789 for (j = 0; j < cfg->line_outs; j++) {
4790 if (!assigned[j]) {
4791 spec->multiout.dac_nids[i] =
4792 alc880_idx_to_dac(j);
4793 assigned[j] = 1;
4794 break;
4798 spec->multiout.num_dacs = cfg->line_outs;
4799 return 0;
4802 /* add playback controls from the parsed DAC table */
4803 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4804 const struct auto_pin_cfg *cfg)
4806 static const char *chname[4] = {
4807 "Front", "Surround", NULL /*CLFE*/, "Side"
4809 hda_nid_t nid;
4810 int i, err;
4812 for (i = 0; i < cfg->line_outs; i++) {
4813 if (!spec->multiout.dac_nids[i])
4814 continue;
4815 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4816 if (i == 2) {
4817 /* Center/LFE */
4818 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4819 "Center",
4820 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4821 HDA_OUTPUT));
4822 if (err < 0)
4823 return err;
4824 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4825 "LFE",
4826 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4827 HDA_OUTPUT));
4828 if (err < 0)
4829 return err;
4830 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4831 "Center",
4832 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4833 HDA_INPUT));
4834 if (err < 0)
4835 return err;
4836 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4837 "LFE",
4838 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4839 HDA_INPUT));
4840 if (err < 0)
4841 return err;
4842 } else {
4843 const char *pfx;
4844 if (cfg->line_outs == 1 &&
4845 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4846 pfx = "Speaker";
4847 else
4848 pfx = chname[i];
4849 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4850 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4851 HDA_OUTPUT));
4852 if (err < 0)
4853 return err;
4854 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4855 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4856 HDA_INPUT));
4857 if (err < 0)
4858 return err;
4861 return 0;
4864 /* add playback controls for speaker and HP outputs */
4865 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4866 const char *pfx)
4868 hda_nid_t nid;
4869 int err;
4871 if (!pin)
4872 return 0;
4874 if (alc880_is_fixed_pin(pin)) {
4875 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4876 /* specify the DAC as the extra output */
4877 if (!spec->multiout.hp_nid)
4878 spec->multiout.hp_nid = nid;
4879 else
4880 spec->multiout.extra_out_nid[0] = nid;
4881 /* control HP volume/switch on the output mixer amp */
4882 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4883 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4884 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4885 if (err < 0)
4886 return err;
4887 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4888 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4889 if (err < 0)
4890 return err;
4891 } else if (alc880_is_multi_pin(pin)) {
4892 /* set manual connection */
4893 /* we have only a switch on HP-out PIN */
4894 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4895 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4896 if (err < 0)
4897 return err;
4899 return 0;
4902 /* create input playback/capture controls for the given pin */
4903 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4904 const char *ctlname,
4905 int idx, hda_nid_t mix_nid)
4907 int err;
4909 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4910 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4911 if (err < 0)
4912 return err;
4913 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4914 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4915 if (err < 0)
4916 return err;
4917 return 0;
4920 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4922 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4923 return (pincap & AC_PINCAP_IN) != 0;
4926 /* create playback/capture controls for input pins */
4927 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4928 const struct auto_pin_cfg *cfg,
4929 hda_nid_t mixer,
4930 hda_nid_t cap1, hda_nid_t cap2)
4932 struct alc_spec *spec = codec->spec;
4933 struct hda_input_mux *imux = &spec->private_imux[0];
4934 int i, err, idx;
4936 for (i = 0; i < AUTO_PIN_LAST; i++) {
4937 hda_nid_t pin;
4939 pin = cfg->input_pins[i];
4940 if (!alc_is_input_pin(codec, pin))
4941 continue;
4943 if (mixer) {
4944 idx = get_connection_index(codec, mixer, pin);
4945 if (idx >= 0) {
4946 err = new_analog_input(spec, pin,
4947 auto_pin_cfg_labels[i],
4948 idx, mixer);
4949 if (err < 0)
4950 return err;
4954 if (!cap1)
4955 continue;
4956 idx = get_connection_index(codec, cap1, pin);
4957 if (idx < 0 && cap2)
4958 idx = get_connection_index(codec, cap2, pin);
4959 if (idx >= 0) {
4960 imux->items[imux->num_items].label =
4961 auto_pin_cfg_labels[i];
4962 imux->items[imux->num_items].index = idx;
4963 imux->num_items++;
4966 return 0;
4969 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4970 const struct auto_pin_cfg *cfg)
4972 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4975 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4976 unsigned int pin_type)
4978 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4979 pin_type);
4980 /* unmute pin */
4981 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4982 AMP_OUT_UNMUTE);
4985 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4986 hda_nid_t nid, int pin_type,
4987 int dac_idx)
4989 alc_set_pin_output(codec, nid, pin_type);
4990 /* need the manual connection? */
4991 if (alc880_is_multi_pin(nid)) {
4992 struct alc_spec *spec = codec->spec;
4993 int idx = alc880_multi_pin_idx(nid);
4994 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4995 AC_VERB_SET_CONNECT_SEL,
4996 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5000 static int get_pin_type(int line_out_type)
5002 if (line_out_type == AUTO_PIN_HP_OUT)
5003 return PIN_HP;
5004 else
5005 return PIN_OUT;
5008 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5010 struct alc_spec *spec = codec->spec;
5011 int i;
5013 for (i = 0; i < spec->autocfg.line_outs; i++) {
5014 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5015 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5016 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5020 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5022 struct alc_spec *spec = codec->spec;
5023 hda_nid_t pin;
5025 pin = spec->autocfg.speaker_pins[0];
5026 if (pin) /* connect to front */
5027 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5028 pin = spec->autocfg.hp_pins[0];
5029 if (pin) /* connect to front */
5030 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5033 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5035 struct alc_spec *spec = codec->spec;
5036 int i;
5038 for (i = 0; i < AUTO_PIN_LAST; i++) {
5039 hda_nid_t nid = spec->autocfg.input_pins[i];
5040 if (alc_is_input_pin(codec, nid)) {
5041 alc_set_input_pin(codec, nid, i);
5042 if (nid != ALC880_PIN_CD_NID &&
5043 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5044 snd_hda_codec_write(codec, nid, 0,
5045 AC_VERB_SET_AMP_GAIN_MUTE,
5046 AMP_OUT_MUTE);
5051 static void alc880_auto_init_input_src(struct hda_codec *codec)
5053 struct alc_spec *spec = codec->spec;
5054 int c;
5056 for (c = 0; c < spec->num_adc_nids; c++) {
5057 unsigned int mux_idx;
5058 const struct hda_input_mux *imux;
5059 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5060 imux = &spec->input_mux[mux_idx];
5061 if (!imux->num_items && mux_idx > 0)
5062 imux = &spec->input_mux[0];
5063 if (imux)
5064 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5065 AC_VERB_SET_CONNECT_SEL,
5066 imux->items[0].index);
5070 /* parse the BIOS configuration and set up the alc_spec */
5071 /* return 1 if successful, 0 if the proper config is not found,
5072 * or a negative error code
5074 static int alc880_parse_auto_config(struct hda_codec *codec)
5076 struct alc_spec *spec = codec->spec;
5077 int err;
5078 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5080 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5081 alc880_ignore);
5082 if (err < 0)
5083 return err;
5084 if (!spec->autocfg.line_outs)
5085 return 0; /* can't find valid BIOS pin config */
5087 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5088 if (err < 0)
5089 return err;
5090 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5091 if (err < 0)
5092 return err;
5093 err = alc880_auto_create_extra_out(spec,
5094 spec->autocfg.speaker_pins[0],
5095 "Speaker");
5096 if (err < 0)
5097 return err;
5098 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5099 "Headphone");
5100 if (err < 0)
5101 return err;
5102 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5103 if (err < 0)
5104 return err;
5106 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5108 alc_auto_parse_digital(codec);
5110 if (spec->kctls.list)
5111 add_mixer(spec, spec->kctls.list);
5113 add_verb(spec, alc880_volume_init_verbs);
5115 spec->num_mux_defs = 1;
5116 spec->input_mux = &spec->private_imux[0];
5118 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5120 return 1;
5123 /* additional initialization for auto-configuration model */
5124 static void alc880_auto_init(struct hda_codec *codec)
5126 struct alc_spec *spec = codec->spec;
5127 alc880_auto_init_multi_out(codec);
5128 alc880_auto_init_extra_out(codec);
5129 alc880_auto_init_analog_input(codec);
5130 alc880_auto_init_input_src(codec);
5131 alc_auto_init_digital(codec);
5132 if (spec->unsol_event)
5133 alc_inithook(codec);
5136 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5137 * one of two digital mic pins, e.g. on ALC272
5139 static void fixup_automic_adc(struct hda_codec *codec)
5141 struct alc_spec *spec = codec->spec;
5142 int i;
5144 for (i = 0; i < spec->num_adc_nids; i++) {
5145 hda_nid_t cap = spec->capsrc_nids ?
5146 spec->capsrc_nids[i] : spec->adc_nids[i];
5147 int iidx, eidx;
5149 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5150 if (iidx < 0)
5151 continue;
5152 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5153 if (eidx < 0)
5154 continue;
5155 spec->int_mic.mux_idx = iidx;
5156 spec->ext_mic.mux_idx = eidx;
5157 if (spec->capsrc_nids)
5158 spec->capsrc_nids += i;
5159 spec->adc_nids += i;
5160 spec->num_adc_nids = 1;
5161 return;
5163 snd_printd(KERN_INFO "hda_codec: %s: "
5164 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5165 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5166 spec->auto_mic = 0; /* disable auto-mic to be sure */
5169 /* set the default connection to that pin */
5170 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5172 struct alc_spec *spec = codec->spec;
5173 int i;
5175 for (i = 0; i < spec->num_adc_nids; i++) {
5176 hda_nid_t cap = spec->capsrc_nids ?
5177 spec->capsrc_nids[i] : spec->adc_nids[i];
5178 int idx;
5180 idx = get_connection_index(codec, cap, pin);
5181 if (idx < 0)
5182 continue;
5183 /* select or unmute this route */
5184 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5185 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5186 HDA_AMP_MUTE, 0);
5187 } else {
5188 snd_hda_codec_write_cache(codec, cap, 0,
5189 AC_VERB_SET_CONNECT_SEL, idx);
5191 return i; /* return the found index */
5193 return -1; /* not found */
5196 /* choose the ADC/MUX containing the input pin and initialize the setup */
5197 static void fixup_single_adc(struct hda_codec *codec)
5199 struct alc_spec *spec = codec->spec;
5200 hda_nid_t pin = 0;
5201 int i;
5203 /* search for the input pin; there must be only one */
5204 for (i = 0; i < AUTO_PIN_LAST; i++) {
5205 if (spec->autocfg.input_pins[i]) {
5206 pin = spec->autocfg.input_pins[i];
5207 break;
5210 if (!pin)
5211 return;
5212 i = init_capsrc_for_pin(codec, pin);
5213 if (i >= 0) {
5214 /* use only this ADC */
5215 if (spec->capsrc_nids)
5216 spec->capsrc_nids += i;
5217 spec->adc_nids += i;
5218 spec->num_adc_nids = 1;
5222 /* initialize dual adcs */
5223 static void fixup_dual_adc_switch(struct hda_codec *codec)
5225 struct alc_spec *spec = codec->spec;
5226 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5227 init_capsrc_for_pin(codec, spec->int_mic.pin);
5230 static void set_capture_mixer(struct hda_codec *codec)
5232 struct alc_spec *spec = codec->spec;
5233 static struct snd_kcontrol_new *caps[2][3] = {
5234 { alc_capture_mixer_nosrc1,
5235 alc_capture_mixer_nosrc2,
5236 alc_capture_mixer_nosrc3 },
5237 { alc_capture_mixer1,
5238 alc_capture_mixer2,
5239 alc_capture_mixer3 },
5241 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5242 int mux = 0;
5243 int num_adcs = spec->num_adc_nids;
5244 if (spec->dual_adc_switch)
5245 fixup_dual_adc_switch(codec);
5246 else if (spec->auto_mic)
5247 fixup_automic_adc(codec);
5248 else if (spec->input_mux) {
5249 if (spec->input_mux->num_items > 1)
5250 mux = 1;
5251 else if (spec->input_mux->num_items == 1)
5252 fixup_single_adc(codec);
5254 if (spec->dual_adc_switch)
5255 num_adcs = 1;
5256 spec->cap_mixer = caps[mux][num_adcs - 1];
5260 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5261 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5262 int num_nids)
5264 struct alc_spec *spec = codec->spec;
5265 int n;
5266 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5268 for (n = 0; n < num_nids; n++) {
5269 hda_nid_t adc, cap;
5270 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5271 int nconns, i, j;
5273 adc = nids[n];
5274 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5275 continue;
5276 cap = adc;
5277 nconns = snd_hda_get_connections(codec, cap, conn,
5278 ARRAY_SIZE(conn));
5279 if (nconns == 1) {
5280 cap = conn[0];
5281 nconns = snd_hda_get_connections(codec, cap, conn,
5282 ARRAY_SIZE(conn));
5284 if (nconns <= 0)
5285 continue;
5286 if (!fallback_adc) {
5287 fallback_adc = adc;
5288 fallback_cap = cap;
5290 for (i = 0; i < AUTO_PIN_LAST; i++) {
5291 hda_nid_t nid = spec->autocfg.input_pins[i];
5292 if (!nid)
5293 continue;
5294 for (j = 0; j < nconns; j++) {
5295 if (conn[j] == nid)
5296 break;
5298 if (j >= nconns)
5299 break;
5301 if (i >= AUTO_PIN_LAST) {
5302 int num_adcs = spec->num_adc_nids;
5303 spec->private_adc_nids[num_adcs] = adc;
5304 spec->private_capsrc_nids[num_adcs] = cap;
5305 spec->num_adc_nids++;
5306 spec->adc_nids = spec->private_adc_nids;
5307 if (adc != cap)
5308 spec->capsrc_nids = spec->private_capsrc_nids;
5311 if (!spec->num_adc_nids) {
5312 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5313 " using fallback 0x%x\n",
5314 codec->chip_name, fallback_adc);
5315 spec->private_adc_nids[0] = fallback_adc;
5316 spec->adc_nids = spec->private_adc_nids;
5317 if (fallback_adc != fallback_cap) {
5318 spec->private_capsrc_nids[0] = fallback_cap;
5319 spec->capsrc_nids = spec->private_adc_nids;
5324 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5325 #define set_beep_amp(spec, nid, idx, dir) \
5326 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5328 static struct snd_pci_quirk beep_white_list[] = {
5329 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5333 static inline int has_cdefine_beep(struct hda_codec *codec)
5335 struct alc_spec *spec = codec->spec;
5336 const struct snd_pci_quirk *q;
5337 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5338 if (q)
5339 return q->value;
5340 return spec->cdefine.enable_pcbeep;
5342 #else
5343 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5344 #define has_cdefine_beep(codec) 0
5345 #endif
5348 * OK, here we have finally the patch for ALC880
5351 static int patch_alc880(struct hda_codec *codec)
5353 struct alc_spec *spec;
5354 int board_config;
5355 int err;
5357 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5358 if (spec == NULL)
5359 return -ENOMEM;
5361 codec->spec = spec;
5363 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5364 alc880_models,
5365 alc880_cfg_tbl);
5366 if (board_config < 0) {
5367 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5368 codec->chip_name);
5369 board_config = ALC880_AUTO;
5372 if (board_config == ALC880_AUTO) {
5373 /* automatic parse from the BIOS config */
5374 err = alc880_parse_auto_config(codec);
5375 if (err < 0) {
5376 alc_free(codec);
5377 return err;
5378 } else if (!err) {
5379 printk(KERN_INFO
5380 "hda_codec: Cannot set up configuration "
5381 "from BIOS. Using 3-stack mode...\n");
5382 board_config = ALC880_3ST;
5386 err = snd_hda_attach_beep_device(codec, 0x1);
5387 if (err < 0) {
5388 alc_free(codec);
5389 return err;
5392 if (board_config != ALC880_AUTO)
5393 setup_preset(codec, &alc880_presets[board_config]);
5395 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5396 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5397 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5399 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5400 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5402 if (!spec->adc_nids && spec->input_mux) {
5403 /* check whether NID 0x07 is valid */
5404 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5405 /* get type */
5406 wcap = get_wcaps_type(wcap);
5407 if (wcap != AC_WID_AUD_IN) {
5408 spec->adc_nids = alc880_adc_nids_alt;
5409 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5410 } else {
5411 spec->adc_nids = alc880_adc_nids;
5412 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5415 set_capture_mixer(codec);
5416 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5418 spec->vmaster_nid = 0x0c;
5420 codec->patch_ops = alc_patch_ops;
5421 if (board_config == ALC880_AUTO)
5422 spec->init_hook = alc880_auto_init;
5423 #ifdef CONFIG_SND_HDA_POWER_SAVE
5424 if (!spec->loopback.amplist)
5425 spec->loopback.amplist = alc880_loopbacks;
5426 #endif
5428 return 0;
5433 * ALC260 support
5436 static hda_nid_t alc260_dac_nids[1] = {
5437 /* front */
5438 0x02,
5441 static hda_nid_t alc260_adc_nids[1] = {
5442 /* ADC0 */
5443 0x04,
5446 static hda_nid_t alc260_adc_nids_alt[1] = {
5447 /* ADC1 */
5448 0x05,
5451 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5452 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5454 static hda_nid_t alc260_dual_adc_nids[2] = {
5455 /* ADC0, ADC1 */
5456 0x04, 0x05
5459 #define ALC260_DIGOUT_NID 0x03
5460 #define ALC260_DIGIN_NID 0x06
5462 static struct hda_input_mux alc260_capture_source = {
5463 .num_items = 4,
5464 .items = {
5465 { "Mic", 0x0 },
5466 { "Front Mic", 0x1 },
5467 { "Line", 0x2 },
5468 { "CD", 0x4 },
5472 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5473 * headphone jack and the internal CD lines since these are the only pins at
5474 * which audio can appear. For flexibility, also allow the option of
5475 * recording the mixer output on the second ADC (ADC0 doesn't have a
5476 * connection to the mixer output).
5478 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5480 .num_items = 3,
5481 .items = {
5482 { "Mic/Line", 0x0 },
5483 { "CD", 0x4 },
5484 { "Headphone", 0x2 },
5488 .num_items = 4,
5489 .items = {
5490 { "Mic/Line", 0x0 },
5491 { "CD", 0x4 },
5492 { "Headphone", 0x2 },
5493 { "Mixer", 0x5 },
5499 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5500 * the Fujitsu S702x, but jacks are marked differently.
5502 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5504 .num_items = 4,
5505 .items = {
5506 { "Mic", 0x0 },
5507 { "Line", 0x2 },
5508 { "CD", 0x4 },
5509 { "Headphone", 0x5 },
5513 .num_items = 5,
5514 .items = {
5515 { "Mic", 0x0 },
5516 { "Line", 0x2 },
5517 { "CD", 0x4 },
5518 { "Headphone", 0x6 },
5519 { "Mixer", 0x5 },
5524 /* Maxdata Favorit 100XS */
5525 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5527 .num_items = 2,
5528 .items = {
5529 { "Line/Mic", 0x0 },
5530 { "CD", 0x4 },
5534 .num_items = 3,
5535 .items = {
5536 { "Line/Mic", 0x0 },
5537 { "CD", 0x4 },
5538 { "Mixer", 0x5 },
5544 * This is just place-holder, so there's something for alc_build_pcms to look
5545 * at when it calculates the maximum number of channels. ALC260 has no mixer
5546 * element which allows changing the channel mode, so the verb list is
5547 * never used.
5549 static struct hda_channel_mode alc260_modes[1] = {
5550 { 2, NULL },
5554 /* Mixer combinations
5556 * basic: base_output + input + pc_beep + capture
5557 * HP: base_output + input + capture_alt
5558 * HP_3013: hp_3013 + input + capture
5559 * fujitsu: fujitsu + capture
5560 * acer: acer + capture
5563 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5564 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5565 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5568 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5569 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5570 { } /* end */
5573 static struct snd_kcontrol_new alc260_input_mixer[] = {
5574 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5575 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5576 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5577 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5579 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5582 { } /* end */
5585 /* update HP, line and mono out pins according to the master switch */
5586 static void alc260_hp_master_update(struct hda_codec *codec,
5587 hda_nid_t hp, hda_nid_t line,
5588 hda_nid_t mono)
5590 struct alc_spec *spec = codec->spec;
5591 unsigned int val = spec->master_sw ? PIN_HP : 0;
5592 /* change HP and line-out pins */
5593 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5594 val);
5595 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5596 val);
5597 /* mono (speaker) depending on the HP jack sense */
5598 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5599 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5600 val);
5603 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5604 struct snd_ctl_elem_value *ucontrol)
5606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5607 struct alc_spec *spec = codec->spec;
5608 *ucontrol->value.integer.value = spec->master_sw;
5609 return 0;
5612 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5613 struct snd_ctl_elem_value *ucontrol)
5615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5616 struct alc_spec *spec = codec->spec;
5617 int val = !!*ucontrol->value.integer.value;
5618 hda_nid_t hp, line, mono;
5620 if (val == spec->master_sw)
5621 return 0;
5622 spec->master_sw = val;
5623 hp = (kcontrol->private_value >> 16) & 0xff;
5624 line = (kcontrol->private_value >> 8) & 0xff;
5625 mono = kcontrol->private_value & 0xff;
5626 alc260_hp_master_update(codec, hp, line, mono);
5627 return 1;
5630 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5632 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5633 .name = "Master Playback Switch",
5634 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5635 .info = snd_ctl_boolean_mono_info,
5636 .get = alc260_hp_master_sw_get,
5637 .put = alc260_hp_master_sw_put,
5638 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5640 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5641 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5642 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5643 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5644 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5645 HDA_OUTPUT),
5646 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5647 { } /* end */
5650 static struct hda_verb alc260_hp_unsol_verbs[] = {
5651 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5655 static void alc260_hp_automute(struct hda_codec *codec)
5657 struct alc_spec *spec = codec->spec;
5659 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5660 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5663 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5665 if ((res >> 26) == ALC880_HP_EVENT)
5666 alc260_hp_automute(codec);
5669 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5672 .name = "Master Playback Switch",
5673 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5674 .info = snd_ctl_boolean_mono_info,
5675 .get = alc260_hp_master_sw_get,
5676 .put = alc260_hp_master_sw_put,
5677 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5679 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5680 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5681 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5682 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5683 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5685 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5686 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5687 { } /* end */
5690 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5691 .ops = &snd_hda_bind_vol,
5692 .values = {
5693 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5694 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5695 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5700 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5701 .ops = &snd_hda_bind_sw,
5702 .values = {
5703 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5704 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5709 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5710 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5711 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5713 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5714 { } /* end */
5717 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5718 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5722 static void alc260_hp_3013_automute(struct hda_codec *codec)
5724 struct alc_spec *spec = codec->spec;
5726 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5727 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5730 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5731 unsigned int res)
5733 if ((res >> 26) == ALC880_HP_EVENT)
5734 alc260_hp_3013_automute(codec);
5737 static void alc260_hp_3012_automute(struct hda_codec *codec)
5739 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5741 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5742 bits);
5743 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5744 bits);
5745 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5746 bits);
5749 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5750 unsigned int res)
5752 if ((res >> 26) == ALC880_HP_EVENT)
5753 alc260_hp_3012_automute(codec);
5756 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5757 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5759 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5760 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5761 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5762 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5763 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5764 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5765 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5766 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5767 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5768 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5769 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5770 { } /* end */
5773 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5774 * versions of the ALC260 don't act on requests to enable mic bias from NID
5775 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5776 * datasheet doesn't mention this restriction. At this stage it's not clear
5777 * whether this behaviour is intentional or is a hardware bug in chip
5778 * revisions available in early 2006. Therefore for now allow the
5779 * "Headphone Jack Mode" control to span all choices, but if it turns out
5780 * that the lack of mic bias for this NID is intentional we could change the
5781 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5783 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5784 * don't appear to make the mic bias available from the "line" jack, even
5785 * though the NID used for this jack (0x14) can supply it. The theory is
5786 * that perhaps Acer have included blocking capacitors between the ALC260
5787 * and the output jack. If this turns out to be the case for all such
5788 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5789 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5791 * The C20x Tablet series have a mono internal speaker which is controlled
5792 * via the chip's Mono sum widget and pin complex, so include the necessary
5793 * controls for such models. On models without a "mono speaker" the control
5794 * won't do anything.
5796 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5797 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5798 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5799 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5800 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5801 HDA_OUTPUT),
5802 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5803 HDA_INPUT),
5804 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5805 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5807 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5808 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5809 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5810 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5811 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5812 { } /* end */
5815 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5817 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5818 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5819 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5820 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5821 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5822 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5823 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5824 { } /* end */
5827 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5828 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5830 static struct snd_kcontrol_new alc260_will_mixer[] = {
5831 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5832 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5834 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5835 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5836 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5837 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5838 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5839 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5840 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5841 { } /* end */
5844 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5845 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5847 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5848 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5849 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5851 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5852 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5853 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5854 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5855 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5856 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5857 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5858 { } /* end */
5862 * initialization verbs
5864 static struct hda_verb alc260_init_verbs[] = {
5865 /* Line In pin widget for input */
5866 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5867 /* CD pin widget for input */
5868 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5869 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5870 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5871 /* Mic2 (front panel) pin widget for input and vref at 80% */
5872 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5873 /* LINE-2 is used for line-out in rear */
5874 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5875 /* select line-out */
5876 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5877 /* LINE-OUT pin */
5878 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5879 /* enable HP */
5880 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5881 /* enable Mono */
5882 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5883 /* mute capture amp left and right */
5884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5885 /* set connection select to line in (default select for this ADC) */
5886 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5887 /* mute capture amp left and right */
5888 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889 /* set connection select to line in (default select for this ADC) */
5890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5891 /* set vol=0 Line-Out mixer amp left and right */
5892 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5893 /* unmute pin widget amp left and right (no gain on this amp) */
5894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5895 /* set vol=0 HP mixer amp left and right */
5896 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5897 /* unmute pin widget amp left and right (no gain on this amp) */
5898 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5899 /* set vol=0 Mono mixer amp left and right */
5900 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5901 /* unmute pin widget amp left and right (no gain on this amp) */
5902 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5903 /* unmute LINE-2 out pin */
5904 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5905 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5906 * Line In 2 = 0x03
5908 /* mute analog inputs */
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5914 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5915 /* mute Front out path */
5916 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5918 /* mute Headphone out path */
5919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5920 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5921 /* mute Mono out path */
5922 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5923 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5927 #if 0 /* should be identical with alc260_init_verbs? */
5928 static struct hda_verb alc260_hp_init_verbs[] = {
5929 /* Headphone and output */
5930 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5931 /* mono output */
5932 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5933 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5934 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5935 /* Mic2 (front panel) pin widget for input and vref at 80% */
5936 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5937 /* Line In pin widget for input */
5938 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5939 /* Line-2 pin widget for output */
5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5941 /* CD pin widget for input */
5942 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5943 /* unmute amp left and right */
5944 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5945 /* set connection select to line in (default select for this ADC) */
5946 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5947 /* unmute Line-Out mixer amp left and right (volume = 0) */
5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5949 /* mute pin widget amp left and right (no gain on this amp) */
5950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5951 /* unmute HP mixer amp left and right (volume = 0) */
5952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5953 /* mute pin widget amp left and right (no gain on this amp) */
5954 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5955 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5956 * Line In 2 = 0x03
5958 /* mute analog inputs */
5959 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5960 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5962 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5963 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5964 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5965 /* Unmute Front out path */
5966 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5967 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5968 /* Unmute Headphone out path */
5969 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5970 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5971 /* Unmute Mono out path */
5972 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5973 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5976 #endif
5978 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5979 /* Line out and output */
5980 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5981 /* mono output */
5982 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5983 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5984 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5985 /* Mic2 (front panel) pin widget for input and vref at 80% */
5986 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5987 /* Line In pin widget for input */
5988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5989 /* Headphone pin widget for output */
5990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5991 /* CD pin widget for input */
5992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5993 /* unmute amp left and right */
5994 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5995 /* set connection select to line in (default select for this ADC) */
5996 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5997 /* unmute Line-Out mixer amp left and right (volume = 0) */
5998 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5999 /* mute pin widget amp left and right (no gain on this amp) */
6000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6001 /* unmute HP mixer amp left and right (volume = 0) */
6002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6003 /* mute pin widget amp left and right (no gain on this amp) */
6004 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6005 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6006 * Line In 2 = 0x03
6008 /* mute analog inputs */
6009 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6012 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6013 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6014 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6015 /* Unmute Front out path */
6016 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6018 /* Unmute Headphone out path */
6019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6021 /* Unmute Mono out path */
6022 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6027 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6028 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6029 * audio = 0x16, internal speaker = 0x10.
6031 static struct hda_verb alc260_fujitsu_init_verbs[] = {
6032 /* Disable all GPIOs */
6033 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6034 /* Internal speaker is connected to headphone pin */
6035 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6036 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6038 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6039 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6040 /* Ensure all other unused pins are disabled and muted. */
6041 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6043 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6044 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6045 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6046 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6050 /* Disable digital (SPDIF) pins */
6051 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6052 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6054 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6055 * when acting as an output.
6057 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6059 /* Start with output sum widgets muted and their output gains at min */
6060 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6062 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6064 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6066 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6067 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6068 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6070 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6071 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6072 /* Unmute Line1 pin widget output buffer since it starts as an output.
6073 * If the pin mode is changed by the user the pin mode control will
6074 * take care of enabling the pin's input/output buffers as needed.
6075 * Therefore there's no need to enable the input buffer at this
6076 * stage.
6078 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6079 /* Unmute input buffer of pin widget used for Line-in (no equiv
6080 * mixer ctrl)
6082 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6084 /* Mute capture amp left and right */
6085 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6086 /* Set ADC connection select to match default mixer setting - line
6087 * in (on mic1 pin)
6089 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6091 /* Do the same for the second ADC: mute capture input amp and
6092 * set ADC connection to line in (on mic1 pin)
6094 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6095 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6097 /* Mute all inputs to mixer widget (even unconnected ones) */
6098 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6100 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6101 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6102 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6104 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6105 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6110 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6111 * similar laptops (adapted from Fujitsu init verbs).
6113 static struct hda_verb alc260_acer_init_verbs[] = {
6114 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6115 * the headphone jack. Turn this on and rely on the standard mute
6116 * methods whenever the user wants to turn these outputs off.
6118 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6119 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6120 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6121 /* Internal speaker/Headphone jack is connected to Line-out pin */
6122 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6123 /* Internal microphone/Mic jack is connected to Mic1 pin */
6124 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6125 /* Line In jack is connected to Line1 pin */
6126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6127 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6128 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6129 /* Ensure all other unused pins are disabled and muted. */
6130 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6131 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6132 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6133 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6136 /* Disable digital (SPDIF) pins */
6137 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6138 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6140 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6141 * bus when acting as outputs.
6143 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6144 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6146 /* Start with output sum widgets muted and their output gains at min */
6147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6148 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6149 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6150 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6152 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6153 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6154 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6155 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6157 /* Unmute Line-out pin widget amp left and right
6158 * (no equiv mixer ctrl)
6160 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6161 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6162 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6163 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6164 * inputs. If the pin mode is changed by the user the pin mode control
6165 * will take care of enabling the pin's input/output buffers as needed.
6166 * Therefore there's no need to enable the input buffer at this
6167 * stage.
6169 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172 /* Mute capture amp left and right */
6173 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6174 /* Set ADC connection select to match default mixer setting - mic
6175 * (on mic1 pin)
6177 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6179 /* Do similar with the second ADC: mute capture input amp and
6180 * set ADC connection to mic to match ALSA's default state.
6182 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6183 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6185 /* Mute all inputs to mixer widget (even unconnected ones) */
6186 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6187 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6188 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6189 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6190 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6191 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6192 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6198 /* Initialisation sequence for Maxdata Favorit 100XS
6199 * (adapted from Acer init verbs).
6201 static struct hda_verb alc260_favorit100_init_verbs[] = {
6202 /* GPIO 0 enables the output jack.
6203 * Turn this on and rely on the standard mute
6204 * methods whenever the user wants to turn these outputs off.
6206 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6207 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6208 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6209 /* Line/Mic input jack is connected to Mic1 pin */
6210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6211 /* Ensure all other unused pins are disabled and muted. */
6212 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6213 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6214 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6215 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6216 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6217 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6218 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6219 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6221 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6222 /* Disable digital (SPDIF) pins */
6223 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6224 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6226 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6227 * bus when acting as outputs.
6229 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6230 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6232 /* Start with output sum widgets muted and their output gains at min */
6233 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6236 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6238 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6239 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6240 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6241 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6243 /* Unmute Line-out pin widget amp left and right
6244 * (no equiv mixer ctrl)
6246 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6247 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6248 * inputs. If the pin mode is changed by the user the pin mode control
6249 * will take care of enabling the pin's input/output buffers as needed.
6250 * Therefore there's no need to enable the input buffer at this
6251 * stage.
6253 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6255 /* Mute capture amp left and right */
6256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6257 /* Set ADC connection select to match default mixer setting - mic
6258 * (on mic1 pin)
6260 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6262 /* Do similar with the second ADC: mute capture input amp and
6263 * set ADC connection to mic to match ALSA's default state.
6265 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6266 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6268 /* Mute all inputs to mixer widget (even unconnected ones) */
6269 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6270 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6271 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6272 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6273 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6281 static struct hda_verb alc260_will_verbs[] = {
6282 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6283 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6285 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6286 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6287 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6291 static struct hda_verb alc260_replacer_672v_verbs[] = {
6292 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6293 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6294 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6296 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6297 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6298 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6300 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6304 /* toggle speaker-output according to the hp-jack state */
6305 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6307 unsigned int present;
6309 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6310 present = snd_hda_jack_detect(codec, 0x0f);
6311 if (present) {
6312 snd_hda_codec_write_cache(codec, 0x01, 0,
6313 AC_VERB_SET_GPIO_DATA, 1);
6314 snd_hda_codec_write_cache(codec, 0x0f, 0,
6315 AC_VERB_SET_PIN_WIDGET_CONTROL,
6316 PIN_HP);
6317 } else {
6318 snd_hda_codec_write_cache(codec, 0x01, 0,
6319 AC_VERB_SET_GPIO_DATA, 0);
6320 snd_hda_codec_write_cache(codec, 0x0f, 0,
6321 AC_VERB_SET_PIN_WIDGET_CONTROL,
6322 PIN_OUT);
6326 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6327 unsigned int res)
6329 if ((res >> 26) == ALC880_HP_EVENT)
6330 alc260_replacer_672v_automute(codec);
6333 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6334 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6336 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6337 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6338 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6341 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6342 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6347 /* Test configuration for debugging, modelled after the ALC880 test
6348 * configuration.
6350 #ifdef CONFIG_SND_DEBUG
6351 static hda_nid_t alc260_test_dac_nids[1] = {
6352 0x02,
6354 static hda_nid_t alc260_test_adc_nids[2] = {
6355 0x04, 0x05,
6357 /* For testing the ALC260, each input MUX needs its own definition since
6358 * the signal assignments are different. This assumes that the first ADC
6359 * is NID 0x04.
6361 static struct hda_input_mux alc260_test_capture_sources[2] = {
6363 .num_items = 7,
6364 .items = {
6365 { "MIC1 pin", 0x0 },
6366 { "MIC2 pin", 0x1 },
6367 { "LINE1 pin", 0x2 },
6368 { "LINE2 pin", 0x3 },
6369 { "CD pin", 0x4 },
6370 { "LINE-OUT pin", 0x5 },
6371 { "HP-OUT pin", 0x6 },
6375 .num_items = 8,
6376 .items = {
6377 { "MIC1 pin", 0x0 },
6378 { "MIC2 pin", 0x1 },
6379 { "LINE1 pin", 0x2 },
6380 { "LINE2 pin", 0x3 },
6381 { "CD pin", 0x4 },
6382 { "Mixer", 0x5 },
6383 { "LINE-OUT pin", 0x6 },
6384 { "HP-OUT pin", 0x7 },
6388 static struct snd_kcontrol_new alc260_test_mixer[] = {
6389 /* Output driver widgets */
6390 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6391 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6392 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6393 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6394 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6395 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6397 /* Modes for retasking pin widgets
6398 * Note: the ALC260 doesn't seem to act on requests to enable mic
6399 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6400 * mention this restriction. At this stage it's not clear whether
6401 * this behaviour is intentional or is a hardware bug in chip
6402 * revisions available at least up until early 2006. Therefore for
6403 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6404 * choices, but if it turns out that the lack of mic bias for these
6405 * NIDs is intentional we could change their modes from
6406 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6408 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6409 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6411 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6412 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6413 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6415 /* Loopback mixer controls */
6416 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6417 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6418 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6419 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6420 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6421 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6422 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6423 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6424 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6425 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6426 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6427 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6428 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6429 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6431 /* Controls for GPIO pins, assuming they are configured as outputs */
6432 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6433 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6434 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6435 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6437 /* Switches to allow the digital IO pins to be enabled. The datasheet
6438 * is ambigious as to which NID is which; testing on laptops which
6439 * make this output available should provide clarification.
6441 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6442 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6444 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6445 * this output to turn on an external amplifier.
6447 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6448 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6450 { } /* end */
6452 static struct hda_verb alc260_test_init_verbs[] = {
6453 /* Enable all GPIOs as outputs with an initial value of 0 */
6454 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6455 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6456 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6458 /* Enable retasking pins as output, initially without power amp */
6459 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6460 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6462 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6463 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6466 /* Disable digital (SPDIF) pins initially, but users can enable
6467 * them via a mixer switch. In the case of SPDIF-out, this initverb
6468 * payload also sets the generation to 0, output to be in "consumer"
6469 * PCM format, copyright asserted, no pre-emphasis and no validity
6470 * control.
6472 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6473 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6475 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6476 * OUT1 sum bus when acting as an output.
6478 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6479 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6480 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6481 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6483 /* Start with output sum widgets muted and their output gains at min */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6486 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6489 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6492 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6494 /* Unmute retasking pin widget output buffers since the default
6495 * state appears to be output. As the pin mode is changed by the
6496 * user the pin mode control will take care of enabling the pin's
6497 * input/output buffers as needed.
6499 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6500 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6503 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6504 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6505 /* Also unmute the mono-out pin widget */
6506 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508 /* Mute capture amp left and right */
6509 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 /* Set ADC connection select to match default mixer setting (mic1
6511 * pin)
6513 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6515 /* Do the same for the second ADC: mute capture input amp and
6516 * set ADC connection to mic1 pin
6518 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6519 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6521 /* Mute all inputs to mixer widget (even unconnected ones) */
6522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6533 #endif
6535 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6536 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6538 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6539 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6542 * for BIOS auto-configuration
6545 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6546 const char *pfx, int *vol_bits)
6548 hda_nid_t nid_vol;
6549 unsigned long vol_val, sw_val;
6550 int err;
6552 if (nid >= 0x0f && nid < 0x11) {
6553 nid_vol = nid - 0x7;
6554 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6555 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6556 } else if (nid == 0x11) {
6557 nid_vol = nid - 0x7;
6558 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6559 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6560 } else if (nid >= 0x12 && nid <= 0x15) {
6561 nid_vol = 0x08;
6562 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6563 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6564 } else
6565 return 0; /* N/A */
6567 if (!(*vol_bits & (1 << nid_vol))) {
6568 /* first control for the volume widget */
6569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6570 if (err < 0)
6571 return err;
6572 *vol_bits |= (1 << nid_vol);
6574 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6575 if (err < 0)
6576 return err;
6577 return 1;
6580 /* add playback controls from the parsed DAC table */
6581 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6582 const struct auto_pin_cfg *cfg)
6584 hda_nid_t nid;
6585 int err;
6586 int vols = 0;
6588 spec->multiout.num_dacs = 1;
6589 spec->multiout.dac_nids = spec->private_dac_nids;
6590 spec->multiout.dac_nids[0] = 0x02;
6592 nid = cfg->line_out_pins[0];
6593 if (nid) {
6594 const char *pfx;
6595 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6596 pfx = "Master";
6597 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6598 pfx = "Speaker";
6599 else
6600 pfx = "Front";
6601 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6602 if (err < 0)
6603 return err;
6606 nid = cfg->speaker_pins[0];
6607 if (nid) {
6608 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6609 if (err < 0)
6610 return err;
6613 nid = cfg->hp_pins[0];
6614 if (nid) {
6615 err = alc260_add_playback_controls(spec, nid, "Headphone",
6616 &vols);
6617 if (err < 0)
6618 return err;
6620 return 0;
6623 /* create playback/capture controls for input pins */
6624 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6625 const struct auto_pin_cfg *cfg)
6627 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6630 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6631 hda_nid_t nid, int pin_type,
6632 int sel_idx)
6634 alc_set_pin_output(codec, nid, pin_type);
6635 /* need the manual connection? */
6636 if (nid >= 0x12) {
6637 int idx = nid - 0x12;
6638 snd_hda_codec_write(codec, idx + 0x0b, 0,
6639 AC_VERB_SET_CONNECT_SEL, sel_idx);
6643 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6645 struct alc_spec *spec = codec->spec;
6646 hda_nid_t nid;
6648 nid = spec->autocfg.line_out_pins[0];
6649 if (nid) {
6650 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6651 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6654 nid = spec->autocfg.speaker_pins[0];
6655 if (nid)
6656 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6658 nid = spec->autocfg.hp_pins[0];
6659 if (nid)
6660 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6663 #define ALC260_PIN_CD_NID 0x16
6664 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6666 struct alc_spec *spec = codec->spec;
6667 int i;
6669 for (i = 0; i < AUTO_PIN_LAST; i++) {
6670 hda_nid_t nid = spec->autocfg.input_pins[i];
6671 if (nid >= 0x12) {
6672 alc_set_input_pin(codec, nid, i);
6673 if (nid != ALC260_PIN_CD_NID &&
6674 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6675 snd_hda_codec_write(codec, nid, 0,
6676 AC_VERB_SET_AMP_GAIN_MUTE,
6677 AMP_OUT_MUTE);
6682 #define alc260_auto_init_input_src alc880_auto_init_input_src
6685 * generic initialization of ADC, input mixers and output mixers
6687 static struct hda_verb alc260_volume_init_verbs[] = {
6689 * Unmute ADC0-1 and set the default input to mic-in
6691 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6692 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6693 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6696 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6697 * mixer widget
6698 * Note: PASD motherboards uses the Line In 2 as the input for
6699 * front panel mic (mic 2)
6701 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6702 /* mute analog inputs */
6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6710 * Set up output mixers (0x08 - 0x0a)
6712 /* set vol=0 to output mixers */
6713 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6715 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6716 /* set up input amps for analog loopback */
6717 /* Amp Indices: DAC = 0, mixer = 1 */
6718 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6720 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6721 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6722 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6723 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6728 static int alc260_parse_auto_config(struct hda_codec *codec)
6730 struct alc_spec *spec = codec->spec;
6731 int err;
6732 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6734 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6735 alc260_ignore);
6736 if (err < 0)
6737 return err;
6738 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6739 if (err < 0)
6740 return err;
6741 if (!spec->kctls.list)
6742 return 0; /* can't find valid BIOS pin config */
6743 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6744 if (err < 0)
6745 return err;
6747 spec->multiout.max_channels = 2;
6749 if (spec->autocfg.dig_outs)
6750 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6751 if (spec->kctls.list)
6752 add_mixer(spec, spec->kctls.list);
6754 add_verb(spec, alc260_volume_init_verbs);
6756 spec->num_mux_defs = 1;
6757 spec->input_mux = &spec->private_imux[0];
6759 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6761 return 1;
6764 /* additional initialization for auto-configuration model */
6765 static void alc260_auto_init(struct hda_codec *codec)
6767 struct alc_spec *spec = codec->spec;
6768 alc260_auto_init_multi_out(codec);
6769 alc260_auto_init_analog_input(codec);
6770 alc260_auto_init_input_src(codec);
6771 alc_auto_init_digital(codec);
6772 if (spec->unsol_event)
6773 alc_inithook(codec);
6776 #ifdef CONFIG_SND_HDA_POWER_SAVE
6777 static struct hda_amp_list alc260_loopbacks[] = {
6778 { 0x07, HDA_INPUT, 0 },
6779 { 0x07, HDA_INPUT, 1 },
6780 { 0x07, HDA_INPUT, 2 },
6781 { 0x07, HDA_INPUT, 3 },
6782 { 0x07, HDA_INPUT, 4 },
6783 { } /* end */
6785 #endif
6788 * ALC260 configurations
6790 static const char *alc260_models[ALC260_MODEL_LAST] = {
6791 [ALC260_BASIC] = "basic",
6792 [ALC260_HP] = "hp",
6793 [ALC260_HP_3013] = "hp-3013",
6794 [ALC260_HP_DC7600] = "hp-dc7600",
6795 [ALC260_FUJITSU_S702X] = "fujitsu",
6796 [ALC260_ACER] = "acer",
6797 [ALC260_WILL] = "will",
6798 [ALC260_REPLACER_672V] = "replacer",
6799 [ALC260_FAVORIT100] = "favorit100",
6800 #ifdef CONFIG_SND_DEBUG
6801 [ALC260_TEST] = "test",
6802 #endif
6803 [ALC260_AUTO] = "auto",
6806 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6807 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6808 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6809 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6810 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6811 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6812 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6813 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6814 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6815 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6816 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6817 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6818 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6819 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6820 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6821 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6822 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6823 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6824 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6825 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6826 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6830 static struct alc_config_preset alc260_presets[] = {
6831 [ALC260_BASIC] = {
6832 .mixers = { alc260_base_output_mixer,
6833 alc260_input_mixer },
6834 .init_verbs = { alc260_init_verbs },
6835 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6836 .dac_nids = alc260_dac_nids,
6837 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6838 .adc_nids = alc260_dual_adc_nids,
6839 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6840 .channel_mode = alc260_modes,
6841 .input_mux = &alc260_capture_source,
6843 [ALC260_HP] = {
6844 .mixers = { alc260_hp_output_mixer,
6845 alc260_input_mixer },
6846 .init_verbs = { alc260_init_verbs,
6847 alc260_hp_unsol_verbs },
6848 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6849 .dac_nids = alc260_dac_nids,
6850 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6851 .adc_nids = alc260_adc_nids_alt,
6852 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6853 .channel_mode = alc260_modes,
6854 .input_mux = &alc260_capture_source,
6855 .unsol_event = alc260_hp_unsol_event,
6856 .init_hook = alc260_hp_automute,
6858 [ALC260_HP_DC7600] = {
6859 .mixers = { alc260_hp_dc7600_mixer,
6860 alc260_input_mixer },
6861 .init_verbs = { alc260_init_verbs,
6862 alc260_hp_dc7600_verbs },
6863 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6864 .dac_nids = alc260_dac_nids,
6865 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6866 .adc_nids = alc260_adc_nids_alt,
6867 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6868 .channel_mode = alc260_modes,
6869 .input_mux = &alc260_capture_source,
6870 .unsol_event = alc260_hp_3012_unsol_event,
6871 .init_hook = alc260_hp_3012_automute,
6873 [ALC260_HP_3013] = {
6874 .mixers = { alc260_hp_3013_mixer,
6875 alc260_input_mixer },
6876 .init_verbs = { alc260_hp_3013_init_verbs,
6877 alc260_hp_3013_unsol_verbs },
6878 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6879 .dac_nids = alc260_dac_nids,
6880 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6881 .adc_nids = alc260_adc_nids_alt,
6882 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6883 .channel_mode = alc260_modes,
6884 .input_mux = &alc260_capture_source,
6885 .unsol_event = alc260_hp_3013_unsol_event,
6886 .init_hook = alc260_hp_3013_automute,
6888 [ALC260_FUJITSU_S702X] = {
6889 .mixers = { alc260_fujitsu_mixer },
6890 .init_verbs = { alc260_fujitsu_init_verbs },
6891 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6892 .dac_nids = alc260_dac_nids,
6893 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6894 .adc_nids = alc260_dual_adc_nids,
6895 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6896 .channel_mode = alc260_modes,
6897 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6898 .input_mux = alc260_fujitsu_capture_sources,
6900 [ALC260_ACER] = {
6901 .mixers = { alc260_acer_mixer },
6902 .init_verbs = { alc260_acer_init_verbs },
6903 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6904 .dac_nids = alc260_dac_nids,
6905 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6906 .adc_nids = alc260_dual_adc_nids,
6907 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6908 .channel_mode = alc260_modes,
6909 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6910 .input_mux = alc260_acer_capture_sources,
6912 [ALC260_FAVORIT100] = {
6913 .mixers = { alc260_favorit100_mixer },
6914 .init_verbs = { alc260_favorit100_init_verbs },
6915 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6916 .dac_nids = alc260_dac_nids,
6917 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6918 .adc_nids = alc260_dual_adc_nids,
6919 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6920 .channel_mode = alc260_modes,
6921 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6922 .input_mux = alc260_favorit100_capture_sources,
6924 [ALC260_WILL] = {
6925 .mixers = { alc260_will_mixer },
6926 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6927 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6928 .dac_nids = alc260_dac_nids,
6929 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6930 .adc_nids = alc260_adc_nids,
6931 .dig_out_nid = ALC260_DIGOUT_NID,
6932 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6933 .channel_mode = alc260_modes,
6934 .input_mux = &alc260_capture_source,
6936 [ALC260_REPLACER_672V] = {
6937 .mixers = { alc260_replacer_672v_mixer },
6938 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6939 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6940 .dac_nids = alc260_dac_nids,
6941 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6942 .adc_nids = alc260_adc_nids,
6943 .dig_out_nid = ALC260_DIGOUT_NID,
6944 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6945 .channel_mode = alc260_modes,
6946 .input_mux = &alc260_capture_source,
6947 .unsol_event = alc260_replacer_672v_unsol_event,
6948 .init_hook = alc260_replacer_672v_automute,
6950 #ifdef CONFIG_SND_DEBUG
6951 [ALC260_TEST] = {
6952 .mixers = { alc260_test_mixer },
6953 .init_verbs = { alc260_test_init_verbs },
6954 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6955 .dac_nids = alc260_test_dac_nids,
6956 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6957 .adc_nids = alc260_test_adc_nids,
6958 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6959 .channel_mode = alc260_modes,
6960 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6961 .input_mux = alc260_test_capture_sources,
6963 #endif
6966 static int patch_alc260(struct hda_codec *codec)
6968 struct alc_spec *spec;
6969 int err, board_config;
6971 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6972 if (spec == NULL)
6973 return -ENOMEM;
6975 codec->spec = spec;
6977 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6978 alc260_models,
6979 alc260_cfg_tbl);
6980 if (board_config < 0) {
6981 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6982 codec->chip_name);
6983 board_config = ALC260_AUTO;
6986 if (board_config == ALC260_AUTO) {
6987 /* automatic parse from the BIOS config */
6988 err = alc260_parse_auto_config(codec);
6989 if (err < 0) {
6990 alc_free(codec);
6991 return err;
6992 } else if (!err) {
6993 printk(KERN_INFO
6994 "hda_codec: Cannot set up configuration "
6995 "from BIOS. Using base mode...\n");
6996 board_config = ALC260_BASIC;
7000 err = snd_hda_attach_beep_device(codec, 0x1);
7001 if (err < 0) {
7002 alc_free(codec);
7003 return err;
7006 if (board_config != ALC260_AUTO)
7007 setup_preset(codec, &alc260_presets[board_config]);
7009 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7010 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7012 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7013 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7015 if (!spec->adc_nids && spec->input_mux) {
7016 /* check whether NID 0x04 is valid */
7017 unsigned int wcap = get_wcaps(codec, 0x04);
7018 wcap = get_wcaps_type(wcap);
7019 /* get type */
7020 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7021 spec->adc_nids = alc260_adc_nids_alt;
7022 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7023 } else {
7024 spec->adc_nids = alc260_adc_nids;
7025 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7028 set_capture_mixer(codec);
7029 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7031 spec->vmaster_nid = 0x08;
7033 codec->patch_ops = alc_patch_ops;
7034 if (board_config == ALC260_AUTO)
7035 spec->init_hook = alc260_auto_init;
7036 #ifdef CONFIG_SND_HDA_POWER_SAVE
7037 if (!spec->loopback.amplist)
7038 spec->loopback.amplist = alc260_loopbacks;
7039 #endif
7041 return 0;
7046 * ALC882/883/885/888/889 support
7048 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7049 * configuration. Each pin widget can choose any input DACs and a mixer.
7050 * Each ADC is connected from a mixer of all inputs. This makes possible
7051 * 6-channel independent captures.
7053 * In addition, an independent DAC for the multi-playback (not used in this
7054 * driver yet).
7056 #define ALC882_DIGOUT_NID 0x06
7057 #define ALC882_DIGIN_NID 0x0a
7058 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7059 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7060 #define ALC1200_DIGOUT_NID 0x10
7063 static struct hda_channel_mode alc882_ch_modes[1] = {
7064 { 8, NULL }
7067 /* DACs */
7068 static hda_nid_t alc882_dac_nids[4] = {
7069 /* front, rear, clfe, rear_surr */
7070 0x02, 0x03, 0x04, 0x05
7072 #define alc883_dac_nids alc882_dac_nids
7074 /* ADCs */
7075 #define alc882_adc_nids alc880_adc_nids
7076 #define alc882_adc_nids_alt alc880_adc_nids_alt
7077 #define alc883_adc_nids alc882_adc_nids_alt
7078 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7079 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7080 #define alc889_adc_nids alc880_adc_nids
7082 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7083 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7084 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7085 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7086 #define alc889_capsrc_nids alc882_capsrc_nids
7088 /* input MUX */
7089 /* FIXME: should be a matrix-type input source selection */
7091 static struct hda_input_mux alc882_capture_source = {
7092 .num_items = 4,
7093 .items = {
7094 { "Mic", 0x0 },
7095 { "Front Mic", 0x1 },
7096 { "Line", 0x2 },
7097 { "CD", 0x4 },
7101 #define alc883_capture_source alc882_capture_source
7103 static struct hda_input_mux alc889_capture_source = {
7104 .num_items = 3,
7105 .items = {
7106 { "Front Mic", 0x0 },
7107 { "Mic", 0x3 },
7108 { "Line", 0x2 },
7112 static struct hda_input_mux mb5_capture_source = {
7113 .num_items = 3,
7114 .items = {
7115 { "Mic", 0x1 },
7116 { "Line", 0x7 },
7117 { "CD", 0x4 },
7121 static struct hda_input_mux macmini3_capture_source = {
7122 .num_items = 2,
7123 .items = {
7124 { "Line", 0x2 },
7125 { "CD", 0x4 },
7129 static struct hda_input_mux alc883_3stack_6ch_intel = {
7130 .num_items = 4,
7131 .items = {
7132 { "Mic", 0x1 },
7133 { "Front Mic", 0x0 },
7134 { "Line", 0x2 },
7135 { "CD", 0x4 },
7139 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7140 .num_items = 2,
7141 .items = {
7142 { "Mic", 0x1 },
7143 { "Line", 0x2 },
7147 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7148 .num_items = 4,
7149 .items = {
7150 { "Mic", 0x0 },
7151 { "Int Mic", 0x1 },
7152 { "Line", 0x2 },
7153 { "CD", 0x4 },
7157 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7158 .num_items = 2,
7159 .items = {
7160 { "Mic", 0x0 },
7161 { "Int Mic", 0x1 },
7165 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7166 .num_items = 3,
7167 .items = {
7168 { "Mic", 0x0 },
7169 { "Front Mic", 0x1 },
7170 { "Line", 0x4 },
7174 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7175 .num_items = 2,
7176 .items = {
7177 { "Mic", 0x0 },
7178 { "Line", 0x2 },
7182 static struct hda_input_mux alc889A_mb31_capture_source = {
7183 .num_items = 2,
7184 .items = {
7185 { "Mic", 0x0 },
7186 /* Front Mic (0x01) unused */
7187 { "Line", 0x2 },
7188 /* Line 2 (0x03) unused */
7189 /* CD (0x04) unused? */
7193 static struct hda_input_mux alc889A_imac91_capture_source = {
7194 .num_items = 2,
7195 .items = {
7196 { "Mic", 0x01 },
7197 { "Line", 0x2 }, /* Not sure! */
7202 * 2ch mode
7204 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7205 { 2, NULL }
7209 * 2ch mode
7211 static struct hda_verb alc882_3ST_ch2_init[] = {
7212 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7213 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7214 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7215 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7216 { } /* end */
7220 * 4ch mode
7222 static struct hda_verb alc882_3ST_ch4_init[] = {
7223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7225 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7226 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7227 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7228 { } /* end */
7232 * 6ch mode
7234 static struct hda_verb alc882_3ST_ch6_init[] = {
7235 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7236 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7237 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7238 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7239 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7240 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7241 { } /* end */
7244 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7245 { 2, alc882_3ST_ch2_init },
7246 { 4, alc882_3ST_ch4_init },
7247 { 6, alc882_3ST_ch6_init },
7250 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7253 * 2ch mode
7255 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7256 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7257 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7258 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7259 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7260 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7261 { } /* end */
7265 * 4ch mode
7267 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7268 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7269 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7274 { } /* end */
7278 * 6ch mode
7280 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7281 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7283 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7284 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7285 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7286 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7287 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7288 { } /* end */
7291 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7292 { 2, alc883_3ST_ch2_clevo_init },
7293 { 4, alc883_3ST_ch4_clevo_init },
7294 { 6, alc883_3ST_ch6_clevo_init },
7299 * 6ch mode
7301 static struct hda_verb alc882_sixstack_ch6_init[] = {
7302 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7303 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7304 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7305 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7306 { } /* end */
7310 * 8ch mode
7312 static struct hda_verb alc882_sixstack_ch8_init[] = {
7313 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7314 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7315 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7316 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7317 { } /* end */
7320 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7321 { 6, alc882_sixstack_ch6_init },
7322 { 8, alc882_sixstack_ch8_init },
7326 /* Macbook Air 2,1 */
7328 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7329 { 2, NULL },
7333 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7337 * 2ch mode
7339 static struct hda_verb alc885_mbp_ch2_init[] = {
7340 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7341 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7342 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7343 { } /* end */
7347 * 4ch mode
7349 static struct hda_verb alc885_mbp_ch4_init[] = {
7350 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7351 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7352 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7353 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7354 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7355 { } /* end */
7358 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7359 { 2, alc885_mbp_ch2_init },
7360 { 4, alc885_mbp_ch4_init },
7364 * 2ch
7365 * Speakers/Woofer/HP = Front
7366 * LineIn = Input
7368 static struct hda_verb alc885_mb5_ch2_init[] = {
7369 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7370 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7371 { } /* end */
7375 * 6ch mode
7376 * Speakers/HP = Front
7377 * Woofer = LFE
7378 * LineIn = Surround
7380 static struct hda_verb alc885_mb5_ch6_init[] = {
7381 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7382 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7384 { } /* end */
7387 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7388 { 2, alc885_mb5_ch2_init },
7389 { 6, alc885_mb5_ch6_init },
7392 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7395 * 2ch mode
7397 static struct hda_verb alc883_4ST_ch2_init[] = {
7398 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7399 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7400 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7401 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7402 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7403 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7404 { } /* end */
7408 * 4ch mode
7410 static struct hda_verb alc883_4ST_ch4_init[] = {
7411 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7412 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7413 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7414 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7415 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7416 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7417 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7418 { } /* end */
7422 * 6ch mode
7424 static struct hda_verb alc883_4ST_ch6_init[] = {
7425 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7426 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7427 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7428 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7429 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7430 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7431 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7432 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7433 { } /* end */
7437 * 8ch mode
7439 static struct hda_verb alc883_4ST_ch8_init[] = {
7440 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7441 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7442 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7443 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7444 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7445 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7446 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7447 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7448 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7449 { } /* end */
7452 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7453 { 2, alc883_4ST_ch2_init },
7454 { 4, alc883_4ST_ch4_init },
7455 { 6, alc883_4ST_ch6_init },
7456 { 8, alc883_4ST_ch8_init },
7461 * 2ch mode
7463 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7464 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7465 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7468 { } /* end */
7472 * 4ch mode
7474 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7475 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7476 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7477 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7478 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7479 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7480 { } /* end */
7484 * 6ch mode
7486 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7487 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7488 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7489 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7490 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7491 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7492 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7493 { } /* end */
7496 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7497 { 2, alc883_3ST_ch2_intel_init },
7498 { 4, alc883_3ST_ch4_intel_init },
7499 { 6, alc883_3ST_ch6_intel_init },
7503 * 2ch mode
7505 static struct hda_verb alc889_ch2_intel_init[] = {
7506 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7507 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7508 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7509 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7510 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7511 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7512 { } /* end */
7516 * 6ch mode
7518 static struct hda_verb alc889_ch6_intel_init[] = {
7519 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7520 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7521 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7522 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7523 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7524 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7525 { } /* end */
7529 * 8ch mode
7531 static struct hda_verb alc889_ch8_intel_init[] = {
7532 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7533 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7534 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7536 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7537 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7538 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7539 { } /* end */
7542 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7543 { 2, alc889_ch2_intel_init },
7544 { 6, alc889_ch6_intel_init },
7545 { 8, alc889_ch8_intel_init },
7549 * 6ch mode
7551 static struct hda_verb alc883_sixstack_ch6_init[] = {
7552 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7553 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7554 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7555 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7556 { } /* end */
7560 * 8ch mode
7562 static struct hda_verb alc883_sixstack_ch8_init[] = {
7563 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7564 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7565 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7566 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7567 { } /* end */
7570 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7571 { 6, alc883_sixstack_ch6_init },
7572 { 8, alc883_sixstack_ch8_init },
7576 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7577 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7579 static struct snd_kcontrol_new alc882_base_mixer[] = {
7580 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7581 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7582 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7583 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7584 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7585 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7586 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7587 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7589 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7591 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7592 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7593 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7594 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7595 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7596 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7597 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7598 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7599 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7600 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7601 { } /* end */
7604 /* Macbook Air 2,1 same control for HP and internal Speaker */
7606 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7607 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7608 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7613 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7614 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7615 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7616 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7617 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7618 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7620 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7622 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7623 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7624 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7625 { } /* end */
7628 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7629 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7630 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7631 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7632 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7633 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7634 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7635 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7636 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7638 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7640 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7641 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7642 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7643 { } /* end */
7646 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7647 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7648 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7649 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7650 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7651 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7652 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7653 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7654 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7655 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7656 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7657 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7658 { } /* end */
7661 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7662 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7663 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7664 { } /* end */
7668 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7669 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7670 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7673 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7674 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7675 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7676 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7678 { } /* end */
7681 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7682 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7683 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7684 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7685 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7686 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7687 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7688 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7689 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7690 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7691 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7692 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7693 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7695 { } /* end */
7698 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7699 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7701 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7703 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7704 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7705 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7710 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7711 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7712 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7713 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7714 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7715 { } /* end */
7718 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7719 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7721 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7722 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7723 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7724 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7725 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7727 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7728 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7729 { } /* end */
7732 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7735 .name = "Channel Mode",
7736 .info = alc_ch_mode_info,
7737 .get = alc_ch_mode_get,
7738 .put = alc_ch_mode_put,
7740 { } /* end */
7743 static struct hda_verb alc882_base_init_verbs[] = {
7744 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7747 /* Rear mixer */
7748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7750 /* CLFE mixer */
7751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7753 /* Side mixer */
7754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7757 /* Front Pin: output 0 (0x0c) */
7758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7761 /* Rear Pin: output 1 (0x0d) */
7762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7765 /* CLFE Pin: output 2 (0x0e) */
7766 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7768 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7769 /* Side Pin: output 3 (0x0f) */
7770 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7772 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7773 /* Mic (rear) pin: input vref at 80% */
7774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7776 /* Front Mic pin: input vref at 80% */
7777 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7778 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7779 /* Line In pin: input */
7780 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7782 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7783 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7786 /* CD pin widget for input */
7787 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7789 /* FIXME: use matrix-type input source selection */
7790 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7791 /* Input mixer2 */
7792 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7793 /* Input mixer3 */
7794 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7795 /* ADC2: mute amp left and right */
7796 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7798 /* ADC3: mute amp left and right */
7799 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7800 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7805 static struct hda_verb alc882_adc1_init_verbs[] = {
7806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7811 /* ADC1: mute amp left and right */
7812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7813 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7817 static struct hda_verb alc882_eapd_verbs[] = {
7818 /* change to EAPD mode */
7819 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7820 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7824 static struct hda_verb alc889_eapd_verbs[] = {
7825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7830 static struct hda_verb alc_hp15_unsol_verbs[] = {
7831 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7836 static struct hda_verb alc885_init_verbs[] = {
7837 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7840 /* Rear mixer */
7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7843 /* CLFE mixer */
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7846 /* Side mixer */
7847 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7850 /* Front HP Pin: output 0 (0x0c) */
7851 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7854 /* Front Pin: output 0 (0x0c) */
7855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7858 /* Rear Pin: output 1 (0x0d) */
7859 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7860 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7861 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7862 /* CLFE Pin: output 2 (0x0e) */
7863 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7864 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7865 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7866 /* Side Pin: output 3 (0x0f) */
7867 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7868 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7869 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7870 /* Mic (rear) pin: input vref at 80% */
7871 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7872 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7873 /* Front Mic pin: input vref at 80% */
7874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7876 /* Line In pin: input */
7877 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7880 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7881 /* Input mixer1 */
7882 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7883 /* Input mixer2 */
7884 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7885 /* Input mixer3 */
7886 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7887 /* ADC2: mute amp left and right */
7888 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7889 /* ADC3: mute amp left and right */
7890 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7895 static struct hda_verb alc885_init_input_verbs[] = {
7896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7903 /* Unmute Selector 24h and set the default input to front mic */
7904 static struct hda_verb alc889_init_input_verbs[] = {
7905 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7906 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7911 #define alc883_init_verbs alc882_base_init_verbs
7913 /* Mac Pro test */
7914 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7915 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7916 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7920 /* FIXME: this looks suspicious...
7921 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7922 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7924 { } /* end */
7927 static struct hda_verb alc882_macpro_init_verbs[] = {
7928 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7932 /* Front Pin: output 0 (0x0c) */
7933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7934 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7935 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7936 /* Front Mic pin: input vref at 80% */
7937 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7938 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7939 /* Speaker: output */
7940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7942 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7943 /* Headphone output (output 0 - 0x0c) */
7944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7946 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7948 /* FIXME: use matrix-type input source selection */
7949 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7950 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7951 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7952 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7953 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7954 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7955 /* Input mixer2 */
7956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7959 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7960 /* Input mixer3 */
7961 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7962 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7963 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7965 /* ADC1: mute amp left and right */
7966 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7968 /* ADC2: mute amp left and right */
7969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7970 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7971 /* ADC3: mute amp left and right */
7972 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7973 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7978 /* Macbook 5,1 */
7979 static struct hda_verb alc885_mb5_init_verbs[] = {
7980 /* DACs */
7981 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7982 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7983 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7984 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7985 /* Front mixer */
7986 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7987 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7988 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7989 /* Surround mixer */
7990 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7991 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7992 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7993 /* LFE mixer */
7994 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7995 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7996 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7997 /* HP mixer */
7998 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7999 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8000 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8001 /* Front Pin (0x0c) */
8002 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8003 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8004 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8005 /* LFE Pin (0x0e) */
8006 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8007 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8009 /* HP Pin (0x0f) */
8010 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8011 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8012 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8013 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8014 /* Front Mic pin: input vref at 80% */
8015 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8016 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8017 /* Line In pin */
8018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8021 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8027 /* Macmini 3,1 */
8028 static struct hda_verb alc885_macmini3_init_verbs[] = {
8029 /* DACs */
8030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8032 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8033 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8034 /* Front mixer */
8035 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8036 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8037 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8038 /* Surround mixer */
8039 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8040 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8042 /* LFE mixer */
8043 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8044 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8045 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8046 /* HP mixer */
8047 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8048 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8049 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8050 /* Front Pin (0x0c) */
8051 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8052 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8053 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8054 /* LFE Pin (0x0e) */
8055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8057 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8058 /* HP Pin (0x0f) */
8059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8061 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8062 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8063 /* Line In pin */
8064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8068 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8069 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8070 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8075 static struct hda_verb alc885_mba21_init_verbs[] = {
8076 /*Internal and HP Speaker Mixer*/
8077 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8078 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8079 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8080 /*Internal Speaker Pin (0x0c)*/
8081 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8082 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8083 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8084 /* HP Pin: output 0 (0x0e) */
8085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8087 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8088 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8089 /* Line in (is hp when jack connected)*/
8090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8097 /* Macbook Pro rev3 */
8098 static struct hda_verb alc885_mbp3_init_verbs[] = {
8099 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8103 /* Rear mixer */
8104 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8105 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8107 /* HP mixer */
8108 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8111 /* Front Pin: output 0 (0x0c) */
8112 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8113 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8114 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8115 /* HP Pin: output 0 (0x0e) */
8116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8117 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8118 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8119 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8120 /* Mic (rear) pin: input vref at 80% */
8121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8123 /* Front Mic pin: input vref at 80% */
8124 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8125 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8126 /* Line In pin: use output 1 when in LineOut mode */
8127 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8128 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8129 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8131 /* FIXME: use matrix-type input source selection */
8132 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8133 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8138 /* Input mixer2 */
8139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8141 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8142 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8143 /* Input mixer3 */
8144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8147 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8148 /* ADC1: mute amp left and right */
8149 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8150 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8151 /* ADC2: mute amp left and right */
8152 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8153 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8154 /* ADC3: mute amp left and right */
8155 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8156 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8161 /* iMac 9,1 */
8162 static struct hda_verb alc885_imac91_init_verbs[] = {
8163 /* Internal Speaker Pin (0x0c) */
8164 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8165 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8166 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8167 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8168 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8169 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8170 /* HP Pin: Rear */
8171 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8172 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8173 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8174 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8175 /* Line in Rear */
8176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8177 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8178 /* Front Mic pin: input vref at 80% */
8179 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8180 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8181 /* Rear mixer */
8182 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8183 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8185 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8187 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8188 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8189 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8192 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8194 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8199 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8204 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8205 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8206 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8207 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8208 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8209 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8210 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8211 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8212 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8216 /* iMac 24 mixer. */
8217 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8218 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8219 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8220 { } /* end */
8223 /* iMac 24 init verbs. */
8224 static struct hda_verb alc885_imac24_init_verbs[] = {
8225 /* Internal speakers: output 0 (0x0c) */
8226 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8227 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8228 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8229 /* Internal speakers: output 0 (0x0c) */
8230 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8231 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8232 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8233 /* Headphone: output 0 (0x0c) */
8234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8237 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8238 /* Front Mic: input vref at 80% */
8239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8244 /* Toggle speaker-output according to the hp-jack state */
8245 static void alc885_imac24_setup(struct hda_codec *codec)
8247 struct alc_spec *spec = codec->spec;
8249 spec->autocfg.hp_pins[0] = 0x14;
8250 spec->autocfg.speaker_pins[0] = 0x18;
8251 spec->autocfg.speaker_pins[1] = 0x1a;
8254 #define alc885_mb5_setup alc885_imac24_setup
8255 #define alc885_macmini3_setup alc885_imac24_setup
8257 /* Macbook Air 2,1 */
8258 static void alc885_mba21_setup(struct hda_codec *codec)
8260 struct alc_spec *spec = codec->spec;
8262 spec->autocfg.hp_pins[0] = 0x14;
8263 spec->autocfg.speaker_pins[0] = 0x18;
8268 static void alc885_mbp3_setup(struct hda_codec *codec)
8270 struct alc_spec *spec = codec->spec;
8272 spec->autocfg.hp_pins[0] = 0x15;
8273 spec->autocfg.speaker_pins[0] = 0x14;
8276 static void alc885_imac91_setup(struct hda_codec *codec)
8278 struct alc_spec *spec = codec->spec;
8280 spec->autocfg.hp_pins[0] = 0x14;
8281 spec->autocfg.speaker_pins[0] = 0x18;
8282 spec->autocfg.speaker_pins[1] = 0x1a;
8285 static struct hda_verb alc882_targa_verbs[] = {
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8292 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8293 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8294 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8296 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8297 { } /* end */
8300 /* toggle speaker-output according to the hp-jack state */
8301 static void alc882_targa_automute(struct hda_codec *codec)
8303 struct alc_spec *spec = codec->spec;
8304 alc_automute_amp(codec);
8305 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8306 spec->jack_present ? 1 : 3);
8309 static void alc882_targa_setup(struct hda_codec *codec)
8311 struct alc_spec *spec = codec->spec;
8313 spec->autocfg.hp_pins[0] = 0x14;
8314 spec->autocfg.speaker_pins[0] = 0x1b;
8317 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8319 if ((res >> 26) == ALC880_HP_EVENT)
8320 alc882_targa_automute(codec);
8323 static struct hda_verb alc882_asus_a7j_verbs[] = {
8324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8333 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8335 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8337 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8338 { } /* end */
8341 static struct hda_verb alc882_asus_a7m_verbs[] = {
8342 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8343 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8345 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8347 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8349 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8351 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8353 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8354 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8355 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8356 { } /* end */
8359 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8361 unsigned int gpiostate, gpiomask, gpiodir;
8363 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8364 AC_VERB_GET_GPIO_DATA, 0);
8366 if (!muted)
8367 gpiostate |= (1 << pin);
8368 else
8369 gpiostate &= ~(1 << pin);
8371 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8372 AC_VERB_GET_GPIO_MASK, 0);
8373 gpiomask |= (1 << pin);
8375 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8376 AC_VERB_GET_GPIO_DIRECTION, 0);
8377 gpiodir |= (1 << pin);
8380 snd_hda_codec_write(codec, codec->afg, 0,
8381 AC_VERB_SET_GPIO_MASK, gpiomask);
8382 snd_hda_codec_write(codec, codec->afg, 0,
8383 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8385 msleep(1);
8387 snd_hda_codec_write(codec, codec->afg, 0,
8388 AC_VERB_SET_GPIO_DATA, gpiostate);
8391 /* set up GPIO at initialization */
8392 static void alc885_macpro_init_hook(struct hda_codec *codec)
8394 alc882_gpio_mute(codec, 0, 0);
8395 alc882_gpio_mute(codec, 1, 0);
8398 /* set up GPIO and update auto-muting at initialization */
8399 static void alc885_imac24_init_hook(struct hda_codec *codec)
8401 alc885_macpro_init_hook(codec);
8402 alc_automute_amp(codec);
8406 * generic initialization of ADC, input mixers and output mixers
8408 static struct hda_verb alc883_auto_init_verbs[] = {
8410 * Unmute ADC0-2 and set the default input to mic-in
8412 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8418 * Set up output mixers (0x0c - 0x0f)
8420 /* set vol=0 to output mixers */
8421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 /* set up input amps for analog loopback */
8426 /* Amp Indices: DAC = 0, mixer = 1 */
8427 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8433 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8434 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8435 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8436 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8438 /* FIXME: use matrix-type input source selection */
8439 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8440 /* Input mixer2 */
8441 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8442 /* Input mixer3 */
8443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8447 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8448 static struct hda_verb alc889A_mb31_ch2_init[] = {
8449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8451 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8453 { } /* end */
8456 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8457 static struct hda_verb alc889A_mb31_ch4_init[] = {
8458 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8459 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8460 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8462 { } /* end */
8465 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8466 static struct hda_verb alc889A_mb31_ch5_init[] = {
8467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8468 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8470 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8471 { } /* end */
8474 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8475 static struct hda_verb alc889A_mb31_ch6_init[] = {
8476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8478 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8480 { } /* end */
8483 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8484 { 2, alc889A_mb31_ch2_init },
8485 { 4, alc889A_mb31_ch4_init },
8486 { 5, alc889A_mb31_ch5_init },
8487 { 6, alc889A_mb31_ch6_init },
8490 static struct hda_verb alc883_medion_eapd_verbs[] = {
8491 /* eanable EAPD on medion laptop */
8492 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8493 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8497 #define alc883_base_mixer alc882_base_mixer
8499 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8503 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8505 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8507 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8508 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8510 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8511 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8512 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8513 { } /* end */
8516 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8517 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8518 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8519 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8520 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8522 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8524 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8525 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8526 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8527 { } /* end */
8530 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8531 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8532 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8533 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8534 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8536 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8537 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8538 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8540 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8541 { } /* end */
8544 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8545 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8546 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8547 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8555 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8556 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8558 { } /* end */
8561 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8562 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8563 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8564 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8565 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8566 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8567 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8568 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8569 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8570 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8571 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8572 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8573 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8574 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8575 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8576 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8578 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8579 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8580 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8581 { } /* end */
8584 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8585 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8586 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8588 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8589 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8590 HDA_OUTPUT),
8591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8592 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8593 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8599 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8602 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8603 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8605 { } /* end */
8608 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8610 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8612 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8614 HDA_OUTPUT),
8615 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8616 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8617 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8618 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8619 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8620 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8624 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8628 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8629 { } /* end */
8632 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8633 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8634 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8635 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8636 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8637 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8638 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8639 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8640 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8642 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8643 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8647 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8649 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8650 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8652 { } /* end */
8655 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8656 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8657 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8659 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8660 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8661 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8664 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8665 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8666 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8667 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8670 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8671 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8673 { } /* end */
8676 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8677 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8678 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8679 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8680 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8681 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8682 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8684 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8686 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8687 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8688 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8689 { } /* end */
8692 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8693 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8694 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8695 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8696 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8697 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8698 { } /* end */
8701 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8702 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8703 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8704 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8705 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8708 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8709 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8710 { } /* end */
8713 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8714 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8715 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8716 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8717 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8718 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8721 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8722 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8723 { } /* end */
8726 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8727 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8729 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8734 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8735 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8736 { } /* end */
8739 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
8740 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8741 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8742 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8743 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
8744 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
8745 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
8746 { } /* end */
8749 static struct hda_verb alc883_medion_wim2160_verbs[] = {
8750 /* Unmute front mixer */
8751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8754 /* Set speaker pin to front mixer */
8755 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8757 /* Init headphone pin */
8758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8760 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8761 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8763 { } /* end */
8766 /* toggle speaker-output according to the hp-jack state */
8767 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
8769 struct alc_spec *spec = codec->spec;
8771 spec->autocfg.hp_pins[0] = 0x1a;
8772 spec->autocfg.speaker_pins[0] = 0x15;
8775 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8776 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8784 { } /* end */
8787 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8788 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8789 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8797 { } /* end */
8800 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8801 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8802 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8803 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8804 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8805 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8806 0x0d, 1, 0x0, HDA_OUTPUT),
8807 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8808 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8809 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8811 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8817 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8818 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8820 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8822 { } /* end */
8825 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8826 /* Output mixers */
8827 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8828 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8829 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8830 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8831 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8832 HDA_OUTPUT),
8833 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8834 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8835 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8836 /* Output switches */
8837 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8838 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8839 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8840 /* Boost mixers */
8841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8842 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8843 /* Input mixers */
8844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8846 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8847 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8848 { } /* end */
8851 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8852 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8853 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8858 { } /* end */
8861 static struct hda_bind_ctls alc883_bind_cap_vol = {
8862 .ops = &snd_hda_bind_vol,
8863 .values = {
8864 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8865 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8870 static struct hda_bind_ctls alc883_bind_cap_switch = {
8871 .ops = &snd_hda_bind_sw,
8872 .values = {
8873 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8874 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8879 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8883 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8884 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8886 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8888 { } /* end */
8891 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8892 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8893 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8896 /* .name = "Capture Source", */
8897 .name = "Input Source",
8898 .count = 1,
8899 .info = alc_mux_enum_info,
8900 .get = alc_mux_enum_get,
8901 .put = alc_mux_enum_put,
8903 { } /* end */
8906 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8908 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8909 .name = "Channel Mode",
8910 .info = alc_ch_mode_info,
8911 .get = alc_ch_mode_get,
8912 .put = alc_ch_mode_put,
8914 { } /* end */
8917 /* toggle speaker-output according to the hp-jack state */
8918 static void alc883_mitac_setup(struct hda_codec *codec)
8920 struct alc_spec *spec = codec->spec;
8922 spec->autocfg.hp_pins[0] = 0x15;
8923 spec->autocfg.speaker_pins[0] = 0x14;
8924 spec->autocfg.speaker_pins[1] = 0x17;
8927 /* auto-toggle front mic */
8929 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8931 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8933 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8937 static struct hda_verb alc883_mitac_verbs[] = {
8938 /* HP */
8939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8941 /* Subwoofer */
8942 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8943 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8945 /* enable unsolicited event */
8946 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8947 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8949 { } /* end */
8952 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8953 /* HP */
8954 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8955 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8956 /* Int speaker */
8957 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8959 /* enable unsolicited event */
8961 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8965 { } /* end */
8968 static struct hda_verb alc883_clevo_m720_verbs[] = {
8969 /* HP */
8970 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8971 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8972 /* Int speaker */
8973 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8976 /* enable unsolicited event */
8977 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8980 { } /* end */
8983 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8984 /* HP */
8985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8986 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8987 /* Subwoofer */
8988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8989 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8991 /* enable unsolicited event */
8992 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8994 { } /* end */
8997 static struct hda_verb alc883_targa_verbs[] = {
8998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8999 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9002 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9004 /* Connect Line-Out side jack (SPDIF) to Side */
9005 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9006 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9007 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9008 /* Connect Mic jack to CLFE */
9009 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9010 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9011 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9012 /* Connect Line-in jack to Surround */
9013 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9014 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9015 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9016 /* Connect HP out jack to Front */
9017 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9018 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9019 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9023 { } /* end */
9026 static struct hda_verb alc883_lenovo_101e_verbs[] = {
9027 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9030 { } /* end */
9033 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9036 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9038 { } /* end */
9041 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9042 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9043 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9045 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9046 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9047 { } /* end */
9050 static struct hda_verb alc883_haier_w66_verbs[] = {
9051 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9052 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9056 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9057 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9058 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9059 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9060 { } /* end */
9063 static struct hda_verb alc888_lenovo_sky_verbs[] = {
9064 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9070 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9071 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9072 { } /* end */
9075 static struct hda_verb alc888_6st_dell_verbs[] = {
9076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9080 static struct hda_verb alc883_vaiott_verbs[] = {
9081 /* HP */
9082 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9085 /* enable unsolicited event */
9086 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9088 { } /* end */
9091 static void alc888_3st_hp_setup(struct hda_codec *codec)
9093 struct alc_spec *spec = codec->spec;
9095 spec->autocfg.hp_pins[0] = 0x1b;
9096 spec->autocfg.speaker_pins[0] = 0x14;
9097 spec->autocfg.speaker_pins[1] = 0x16;
9098 spec->autocfg.speaker_pins[2] = 0x18;
9101 static struct hda_verb alc888_3st_hp_verbs[] = {
9102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9103 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9104 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9105 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9106 { } /* end */
9110 * 2ch mode
9112 static struct hda_verb alc888_3st_hp_2ch_init[] = {
9113 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9114 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9115 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9116 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9117 { } /* end */
9121 * 4ch mode
9123 static struct hda_verb alc888_3st_hp_4ch_init[] = {
9124 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9125 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9126 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9127 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9128 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9129 { } /* end */
9133 * 6ch mode
9135 static struct hda_verb alc888_3st_hp_6ch_init[] = {
9136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9139 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9140 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9141 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9142 { } /* end */
9145 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9146 { 2, alc888_3st_hp_2ch_init },
9147 { 4, alc888_3st_hp_4ch_init },
9148 { 6, alc888_3st_hp_6ch_init },
9151 /* toggle front-jack and RCA according to the hp-jack state */
9152 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9154 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9156 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9157 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9158 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9159 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9162 /* toggle RCA according to the front-jack state */
9163 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9165 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9167 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9168 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9171 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9172 unsigned int res)
9174 if ((res >> 26) == ALC880_HP_EVENT)
9175 alc888_lenovo_ms7195_front_automute(codec);
9176 if ((res >> 26) == ALC880_FRONT_EVENT)
9177 alc888_lenovo_ms7195_rca_automute(codec);
9180 static struct hda_verb alc883_medion_md2_verbs[] = {
9181 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9186 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9187 { } /* end */
9190 /* toggle speaker-output according to the hp-jack state */
9191 static void alc883_medion_md2_setup(struct hda_codec *codec)
9193 struct alc_spec *spec = codec->spec;
9195 spec->autocfg.hp_pins[0] = 0x14;
9196 spec->autocfg.speaker_pins[0] = 0x15;
9199 /* toggle speaker-output according to the hp-jack state */
9200 #define alc883_targa_init_hook alc882_targa_init_hook
9201 #define alc883_targa_unsol_event alc882_targa_unsol_event
9203 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9205 unsigned int present;
9207 present = snd_hda_jack_detect(codec, 0x18);
9208 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9209 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9212 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9214 struct alc_spec *spec = codec->spec;
9216 spec->autocfg.hp_pins[0] = 0x15;
9217 spec->autocfg.speaker_pins[0] = 0x14;
9220 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9222 alc_automute_amp(codec);
9223 alc883_clevo_m720_mic_automute(codec);
9226 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9227 unsigned int res)
9229 switch (res >> 26) {
9230 case ALC880_MIC_EVENT:
9231 alc883_clevo_m720_mic_automute(codec);
9232 break;
9233 default:
9234 alc_automute_amp_unsol_event(codec, res);
9235 break;
9239 /* toggle speaker-output according to the hp-jack state */
9240 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9242 struct alc_spec *spec = codec->spec;
9244 spec->autocfg.hp_pins[0] = 0x14;
9245 spec->autocfg.speaker_pins[0] = 0x15;
9248 static void alc883_haier_w66_setup(struct hda_codec *codec)
9250 struct alc_spec *spec = codec->spec;
9252 spec->autocfg.hp_pins[0] = 0x1b;
9253 spec->autocfg.speaker_pins[0] = 0x14;
9256 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9258 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9260 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9261 HDA_AMP_MUTE, bits);
9264 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9266 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9268 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9269 HDA_AMP_MUTE, bits);
9270 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9271 HDA_AMP_MUTE, bits);
9274 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9275 unsigned int res)
9277 if ((res >> 26) == ALC880_HP_EVENT)
9278 alc883_lenovo_101e_all_automute(codec);
9279 if ((res >> 26) == ALC880_FRONT_EVENT)
9280 alc883_lenovo_101e_ispeaker_automute(codec);
9283 /* toggle speaker-output according to the hp-jack state */
9284 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9286 struct alc_spec *spec = codec->spec;
9288 spec->autocfg.hp_pins[0] = 0x14;
9289 spec->autocfg.speaker_pins[0] = 0x15;
9290 spec->autocfg.speaker_pins[1] = 0x16;
9293 static struct hda_verb alc883_acer_eapd_verbs[] = {
9294 /* HP Pin: output 0 (0x0c) */
9295 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9296 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9297 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 /* Front Pin: output 0 (0x0c) */
9299 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9300 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9302 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9303 /* eanable EAPD on medion laptop */
9304 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9305 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9306 /* enable unsolicited event */
9307 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9311 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9315 { } /* end */
9318 static void alc888_6st_dell_setup(struct hda_codec *codec)
9320 struct alc_spec *spec = codec->spec;
9322 spec->autocfg.hp_pins[0] = 0x1b;
9323 spec->autocfg.speaker_pins[0] = 0x14;
9324 spec->autocfg.speaker_pins[1] = 0x15;
9325 spec->autocfg.speaker_pins[2] = 0x16;
9326 spec->autocfg.speaker_pins[3] = 0x17;
9329 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9331 struct alc_spec *spec = codec->spec;
9333 spec->autocfg.hp_pins[0] = 0x1b;
9334 spec->autocfg.speaker_pins[0] = 0x14;
9335 spec->autocfg.speaker_pins[1] = 0x15;
9336 spec->autocfg.speaker_pins[2] = 0x16;
9337 spec->autocfg.speaker_pins[3] = 0x17;
9338 spec->autocfg.speaker_pins[4] = 0x1a;
9341 static void alc883_vaiott_setup(struct hda_codec *codec)
9343 struct alc_spec *spec = codec->spec;
9345 spec->autocfg.hp_pins[0] = 0x15;
9346 spec->autocfg.speaker_pins[0] = 0x14;
9347 spec->autocfg.speaker_pins[1] = 0x17;
9350 static struct hda_verb alc888_asus_m90v_verbs[] = {
9351 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9352 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9353 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 /* enable unsolicited event */
9355 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9356 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9357 { } /* end */
9360 static void alc883_mode2_setup(struct hda_codec *codec)
9362 struct alc_spec *spec = codec->spec;
9364 spec->autocfg.hp_pins[0] = 0x1b;
9365 spec->autocfg.speaker_pins[0] = 0x14;
9366 spec->autocfg.speaker_pins[1] = 0x15;
9367 spec->autocfg.speaker_pins[2] = 0x16;
9368 spec->ext_mic.pin = 0x18;
9369 spec->int_mic.pin = 0x19;
9370 spec->ext_mic.mux_idx = 0;
9371 spec->int_mic.mux_idx = 1;
9372 spec->auto_mic = 1;
9375 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9377 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9379 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9381 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9382 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9383 /* enable unsolicited event */
9384 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9385 { } /* end */
9388 static void alc883_eee1601_inithook(struct hda_codec *codec)
9390 struct alc_spec *spec = codec->spec;
9392 spec->autocfg.hp_pins[0] = 0x14;
9393 spec->autocfg.speaker_pins[0] = 0x1b;
9394 alc_automute_pin(codec);
9397 static struct hda_verb alc889A_mb31_verbs[] = {
9398 /* Init rear pin (used as headphone output) */
9399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9400 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9402 /* Init line pin (used as output in 4ch and 6ch mode) */
9403 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9404 /* Init line 2 pin (used as headphone out by default) */
9405 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9406 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9407 { } /* end */
9410 /* Mute speakers according to the headphone jack state */
9411 static void alc889A_mb31_automute(struct hda_codec *codec)
9413 unsigned int present;
9415 /* Mute only in 2ch or 4ch mode */
9416 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9417 == 0x00) {
9418 present = snd_hda_jack_detect(codec, 0x15);
9419 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9420 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9421 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9422 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9426 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9428 if ((res >> 26) == ALC880_HP_EVENT)
9429 alc889A_mb31_automute(codec);
9433 #ifdef CONFIG_SND_HDA_POWER_SAVE
9434 #define alc882_loopbacks alc880_loopbacks
9435 #endif
9437 /* pcm configuration: identical with ALC880 */
9438 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9439 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9440 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9441 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9443 static hda_nid_t alc883_slave_dig_outs[] = {
9444 ALC1200_DIGOUT_NID, 0,
9447 static hda_nid_t alc1200_slave_dig_outs[] = {
9448 ALC883_DIGOUT_NID, 0,
9452 * configuration and preset
9454 static const char *alc882_models[ALC882_MODEL_LAST] = {
9455 [ALC882_3ST_DIG] = "3stack-dig",
9456 [ALC882_6ST_DIG] = "6stack-dig",
9457 [ALC882_ARIMA] = "arima",
9458 [ALC882_W2JC] = "w2jc",
9459 [ALC882_TARGA] = "targa",
9460 [ALC882_ASUS_A7J] = "asus-a7j",
9461 [ALC882_ASUS_A7M] = "asus-a7m",
9462 [ALC885_MACPRO] = "macpro",
9463 [ALC885_MB5] = "mb5",
9464 [ALC885_MACMINI3] = "macmini3",
9465 [ALC885_MBA21] = "mba21",
9466 [ALC885_MBP3] = "mbp3",
9467 [ALC885_IMAC24] = "imac24",
9468 [ALC885_IMAC91] = "imac91",
9469 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9470 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9471 [ALC883_3ST_6ch] = "3stack-6ch",
9472 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9473 [ALC883_TARGA_DIG] = "targa-dig",
9474 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9475 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9476 [ALC883_ACER] = "acer",
9477 [ALC883_ACER_ASPIRE] = "acer-aspire",
9478 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9479 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9480 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9481 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9482 [ALC883_MEDION] = "medion",
9483 [ALC883_MEDION_MD2] = "medion-md2",
9484 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9485 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9486 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9487 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9488 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9489 [ALC888_LENOVO_SKY] = "lenovo-sky",
9490 [ALC883_HAIER_W66] = "haier-w66",
9491 [ALC888_3ST_HP] = "3stack-hp",
9492 [ALC888_6ST_DELL] = "6stack-dell",
9493 [ALC883_MITAC] = "mitac",
9494 [ALC883_CLEVO_M540R] = "clevo-m540r",
9495 [ALC883_CLEVO_M720] = "clevo-m720",
9496 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9497 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9498 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9499 [ALC889A_INTEL] = "intel-alc889a",
9500 [ALC889_INTEL] = "intel-x58",
9501 [ALC1200_ASUS_P5Q] = "asus-p5q",
9502 [ALC889A_MB31] = "mb31",
9503 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9504 [ALC882_AUTO] = "auto",
9507 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9508 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9510 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9511 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9512 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9513 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9514 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9515 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9516 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9517 ALC888_ACER_ASPIRE_4930G),
9518 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9519 ALC888_ACER_ASPIRE_4930G),
9520 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9521 ALC888_ACER_ASPIRE_8930G),
9522 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9523 ALC888_ACER_ASPIRE_8930G),
9524 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9525 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9526 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9527 ALC888_ACER_ASPIRE_6530G),
9528 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9529 ALC888_ACER_ASPIRE_6530G),
9530 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9531 ALC888_ACER_ASPIRE_7730G),
9532 /* default Acer -- disabled as it causes more problems.
9533 * model=auto should work fine now
9535 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9537 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9539 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9540 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9541 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9542 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9543 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9544 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9546 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9547 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9548 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9549 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9550 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9551 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9552 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9553 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9554 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9555 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9556 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9558 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9559 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9560 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9561 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9562 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9563 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9564 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9565 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9566 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9568 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9569 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9570 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9571 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9572 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9573 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9574 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9575 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9576 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9577 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9578 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9579 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9580 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9581 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9582 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9583 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9584 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9585 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9586 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9587 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9588 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9589 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9590 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9591 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9592 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9593 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9594 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9595 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9596 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9597 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9598 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9600 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9601 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9602 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9603 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9604 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9605 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9606 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9607 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9608 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9609 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9610 ALC883_FUJITSU_PI2515),
9611 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9612 ALC888_FUJITSU_XA3530),
9613 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9614 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9615 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9616 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9617 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9618 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9619 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9620 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9621 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9623 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9624 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9625 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9626 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9627 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9628 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9629 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9634 /* codec SSID table for Intel Mac */
9635 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9636 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9637 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9638 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9639 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9640 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9641 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9642 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9643 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9644 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9645 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9646 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9647 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9648 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9649 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9650 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9651 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9652 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9653 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9654 * so apparently no perfect solution yet
9656 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9657 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9658 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9659 {} /* terminator */
9662 static struct alc_config_preset alc882_presets[] = {
9663 [ALC882_3ST_DIG] = {
9664 .mixers = { alc882_base_mixer },
9665 .init_verbs = { alc882_base_init_verbs,
9666 alc882_adc1_init_verbs },
9667 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9668 .dac_nids = alc882_dac_nids,
9669 .dig_out_nid = ALC882_DIGOUT_NID,
9670 .dig_in_nid = ALC882_DIGIN_NID,
9671 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9672 .channel_mode = alc882_ch_modes,
9673 .need_dac_fix = 1,
9674 .input_mux = &alc882_capture_source,
9676 [ALC882_6ST_DIG] = {
9677 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9678 .init_verbs = { alc882_base_init_verbs,
9679 alc882_adc1_init_verbs },
9680 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9681 .dac_nids = alc882_dac_nids,
9682 .dig_out_nid = ALC882_DIGOUT_NID,
9683 .dig_in_nid = ALC882_DIGIN_NID,
9684 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9685 .channel_mode = alc882_sixstack_modes,
9686 .input_mux = &alc882_capture_source,
9688 [ALC882_ARIMA] = {
9689 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9690 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9691 alc882_eapd_verbs },
9692 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9693 .dac_nids = alc882_dac_nids,
9694 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9695 .channel_mode = alc882_sixstack_modes,
9696 .input_mux = &alc882_capture_source,
9698 [ALC882_W2JC] = {
9699 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
9700 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9701 alc882_eapd_verbs, alc880_gpio1_init_verbs },
9702 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9703 .dac_nids = alc882_dac_nids,
9704 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9705 .channel_mode = alc880_threestack_modes,
9706 .need_dac_fix = 1,
9707 .input_mux = &alc882_capture_source,
9708 .dig_out_nid = ALC882_DIGOUT_NID,
9710 [ALC885_MBA21] = {
9711 .mixers = { alc885_mba21_mixer },
9712 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9713 .num_dacs = 2,
9714 .dac_nids = alc882_dac_nids,
9715 .channel_mode = alc885_mba21_ch_modes,
9716 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9717 .input_mux = &alc882_capture_source,
9718 .unsol_event = alc_automute_amp_unsol_event,
9719 .setup = alc885_mba21_setup,
9720 .init_hook = alc_automute_amp,
9722 [ALC885_MBP3] = {
9723 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9724 .init_verbs = { alc885_mbp3_init_verbs,
9725 alc880_gpio1_init_verbs },
9726 .num_dacs = 2,
9727 .dac_nids = alc882_dac_nids,
9728 .hp_nid = 0x04,
9729 .channel_mode = alc885_mbp_4ch_modes,
9730 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9731 .input_mux = &alc882_capture_source,
9732 .dig_out_nid = ALC882_DIGOUT_NID,
9733 .dig_in_nid = ALC882_DIGIN_NID,
9734 .unsol_event = alc_automute_amp_unsol_event,
9735 .setup = alc885_mbp3_setup,
9736 .init_hook = alc_automute_amp,
9738 [ALC885_MB5] = {
9739 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9740 .init_verbs = { alc885_mb5_init_verbs,
9741 alc880_gpio1_init_verbs },
9742 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9743 .dac_nids = alc882_dac_nids,
9744 .channel_mode = alc885_mb5_6ch_modes,
9745 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9746 .input_mux = &mb5_capture_source,
9747 .dig_out_nid = ALC882_DIGOUT_NID,
9748 .dig_in_nid = ALC882_DIGIN_NID,
9749 .unsol_event = alc_automute_amp_unsol_event,
9750 .setup = alc885_mb5_setup,
9751 .init_hook = alc_automute_amp,
9753 [ALC885_MACMINI3] = {
9754 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9755 .init_verbs = { alc885_macmini3_init_verbs,
9756 alc880_gpio1_init_verbs },
9757 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9758 .dac_nids = alc882_dac_nids,
9759 .channel_mode = alc885_macmini3_6ch_modes,
9760 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9761 .input_mux = &macmini3_capture_source,
9762 .dig_out_nid = ALC882_DIGOUT_NID,
9763 .dig_in_nid = ALC882_DIGIN_NID,
9764 .unsol_event = alc_automute_amp_unsol_event,
9765 .setup = alc885_macmini3_setup,
9766 .init_hook = alc_automute_amp,
9768 [ALC885_MACPRO] = {
9769 .mixers = { alc882_macpro_mixer },
9770 .init_verbs = { alc882_macpro_init_verbs },
9771 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9772 .dac_nids = alc882_dac_nids,
9773 .dig_out_nid = ALC882_DIGOUT_NID,
9774 .dig_in_nid = ALC882_DIGIN_NID,
9775 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9776 .channel_mode = alc882_ch_modes,
9777 .input_mux = &alc882_capture_source,
9778 .init_hook = alc885_macpro_init_hook,
9780 [ALC885_IMAC24] = {
9781 .mixers = { alc885_imac24_mixer },
9782 .init_verbs = { alc885_imac24_init_verbs },
9783 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9784 .dac_nids = alc882_dac_nids,
9785 .dig_out_nid = ALC882_DIGOUT_NID,
9786 .dig_in_nid = ALC882_DIGIN_NID,
9787 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9788 .channel_mode = alc882_ch_modes,
9789 .input_mux = &alc882_capture_source,
9790 .unsol_event = alc_automute_amp_unsol_event,
9791 .setup = alc885_imac24_setup,
9792 .init_hook = alc885_imac24_init_hook,
9794 [ALC885_IMAC91] = {
9795 .mixers = {alc885_imac91_mixer},
9796 .init_verbs = { alc885_imac91_init_verbs,
9797 alc880_gpio1_init_verbs },
9798 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9799 .dac_nids = alc882_dac_nids,
9800 .channel_mode = alc885_mba21_ch_modes,
9801 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9802 .input_mux = &alc889A_imac91_capture_source,
9803 .dig_out_nid = ALC882_DIGOUT_NID,
9804 .dig_in_nid = ALC882_DIGIN_NID,
9805 .unsol_event = alc_automute_amp_unsol_event,
9806 .setup = alc885_imac91_setup,
9807 .init_hook = alc_automute_amp,
9809 [ALC882_TARGA] = {
9810 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9811 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9812 alc880_gpio3_init_verbs, alc882_targa_verbs},
9813 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9814 .dac_nids = alc882_dac_nids,
9815 .dig_out_nid = ALC882_DIGOUT_NID,
9816 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9817 .adc_nids = alc882_adc_nids,
9818 .capsrc_nids = alc882_capsrc_nids,
9819 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9820 .channel_mode = alc882_3ST_6ch_modes,
9821 .need_dac_fix = 1,
9822 .input_mux = &alc882_capture_source,
9823 .unsol_event = alc882_targa_unsol_event,
9824 .setup = alc882_targa_setup,
9825 .init_hook = alc882_targa_automute,
9827 [ALC882_ASUS_A7J] = {
9828 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9829 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9830 alc882_asus_a7j_verbs},
9831 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9832 .dac_nids = alc882_dac_nids,
9833 .dig_out_nid = ALC882_DIGOUT_NID,
9834 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9835 .adc_nids = alc882_adc_nids,
9836 .capsrc_nids = alc882_capsrc_nids,
9837 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9838 .channel_mode = alc882_3ST_6ch_modes,
9839 .need_dac_fix = 1,
9840 .input_mux = &alc882_capture_source,
9842 [ALC882_ASUS_A7M] = {
9843 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9844 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9845 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9846 alc882_asus_a7m_verbs },
9847 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9848 .dac_nids = alc882_dac_nids,
9849 .dig_out_nid = ALC882_DIGOUT_NID,
9850 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9851 .channel_mode = alc880_threestack_modes,
9852 .need_dac_fix = 1,
9853 .input_mux = &alc882_capture_source,
9855 [ALC883_3ST_2ch_DIG] = {
9856 .mixers = { alc883_3ST_2ch_mixer },
9857 .init_verbs = { alc883_init_verbs },
9858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9859 .dac_nids = alc883_dac_nids,
9860 .dig_out_nid = ALC883_DIGOUT_NID,
9861 .dig_in_nid = ALC883_DIGIN_NID,
9862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9863 .channel_mode = alc883_3ST_2ch_modes,
9864 .input_mux = &alc883_capture_source,
9866 [ALC883_3ST_6ch_DIG] = {
9867 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9868 .init_verbs = { alc883_init_verbs },
9869 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9870 .dac_nids = alc883_dac_nids,
9871 .dig_out_nid = ALC883_DIGOUT_NID,
9872 .dig_in_nid = ALC883_DIGIN_NID,
9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9874 .channel_mode = alc883_3ST_6ch_modes,
9875 .need_dac_fix = 1,
9876 .input_mux = &alc883_capture_source,
9878 [ALC883_3ST_6ch] = {
9879 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9880 .init_verbs = { alc883_init_verbs },
9881 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9882 .dac_nids = alc883_dac_nids,
9883 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9884 .channel_mode = alc883_3ST_6ch_modes,
9885 .need_dac_fix = 1,
9886 .input_mux = &alc883_capture_source,
9888 [ALC883_3ST_6ch_INTEL] = {
9889 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9890 .init_verbs = { alc883_init_verbs },
9891 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9892 .dac_nids = alc883_dac_nids,
9893 .dig_out_nid = ALC883_DIGOUT_NID,
9894 .dig_in_nid = ALC883_DIGIN_NID,
9895 .slave_dig_outs = alc883_slave_dig_outs,
9896 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9897 .channel_mode = alc883_3ST_6ch_intel_modes,
9898 .need_dac_fix = 1,
9899 .input_mux = &alc883_3stack_6ch_intel,
9901 [ALC889A_INTEL] = {
9902 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9903 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9904 alc_hp15_unsol_verbs },
9905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9906 .dac_nids = alc883_dac_nids,
9907 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9908 .adc_nids = alc889_adc_nids,
9909 .dig_out_nid = ALC883_DIGOUT_NID,
9910 .dig_in_nid = ALC883_DIGIN_NID,
9911 .slave_dig_outs = alc883_slave_dig_outs,
9912 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9913 .channel_mode = alc889_8ch_intel_modes,
9914 .capsrc_nids = alc889_capsrc_nids,
9915 .input_mux = &alc889_capture_source,
9916 .setup = alc889_automute_setup,
9917 .init_hook = alc_automute_amp,
9918 .unsol_event = alc_automute_amp_unsol_event,
9919 .need_dac_fix = 1,
9921 [ALC889_INTEL] = {
9922 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9923 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9924 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9925 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9926 .dac_nids = alc883_dac_nids,
9927 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9928 .adc_nids = alc889_adc_nids,
9929 .dig_out_nid = ALC883_DIGOUT_NID,
9930 .dig_in_nid = ALC883_DIGIN_NID,
9931 .slave_dig_outs = alc883_slave_dig_outs,
9932 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9933 .channel_mode = alc889_8ch_intel_modes,
9934 .capsrc_nids = alc889_capsrc_nids,
9935 .input_mux = &alc889_capture_source,
9936 .setup = alc889_automute_setup,
9937 .init_hook = alc889_intel_init_hook,
9938 .unsol_event = alc_automute_amp_unsol_event,
9939 .need_dac_fix = 1,
9941 [ALC883_6ST_DIG] = {
9942 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9943 .init_verbs = { alc883_init_verbs },
9944 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9945 .dac_nids = alc883_dac_nids,
9946 .dig_out_nid = ALC883_DIGOUT_NID,
9947 .dig_in_nid = ALC883_DIGIN_NID,
9948 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9949 .channel_mode = alc883_sixstack_modes,
9950 .input_mux = &alc883_capture_source,
9952 [ALC883_TARGA_DIG] = {
9953 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9954 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9955 alc883_targa_verbs},
9956 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9957 .dac_nids = alc883_dac_nids,
9958 .dig_out_nid = ALC883_DIGOUT_NID,
9959 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9960 .channel_mode = alc883_3ST_6ch_modes,
9961 .need_dac_fix = 1,
9962 .input_mux = &alc883_capture_source,
9963 .unsol_event = alc883_targa_unsol_event,
9964 .setup = alc882_targa_setup,
9965 .init_hook = alc882_targa_automute,
9967 [ALC883_TARGA_2ch_DIG] = {
9968 .mixers = { alc883_targa_2ch_mixer},
9969 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9970 alc883_targa_verbs},
9971 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9972 .dac_nids = alc883_dac_nids,
9973 .adc_nids = alc883_adc_nids_alt,
9974 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9975 .capsrc_nids = alc883_capsrc_nids,
9976 .dig_out_nid = ALC883_DIGOUT_NID,
9977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9978 .channel_mode = alc883_3ST_2ch_modes,
9979 .input_mux = &alc883_capture_source,
9980 .unsol_event = alc883_targa_unsol_event,
9981 .setup = alc882_targa_setup,
9982 .init_hook = alc882_targa_automute,
9984 [ALC883_TARGA_8ch_DIG] = {
9985 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9986 alc883_chmode_mixer },
9987 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9988 alc883_targa_verbs },
9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9990 .dac_nids = alc883_dac_nids,
9991 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9992 .adc_nids = alc883_adc_nids_rev,
9993 .capsrc_nids = alc883_capsrc_nids_rev,
9994 .dig_out_nid = ALC883_DIGOUT_NID,
9995 .dig_in_nid = ALC883_DIGIN_NID,
9996 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9997 .channel_mode = alc883_4ST_8ch_modes,
9998 .need_dac_fix = 1,
9999 .input_mux = &alc883_capture_source,
10000 .unsol_event = alc883_targa_unsol_event,
10001 .setup = alc882_targa_setup,
10002 .init_hook = alc882_targa_automute,
10004 [ALC883_ACER] = {
10005 .mixers = { alc883_base_mixer },
10006 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10007 * and the headphone jack. Turn this on and rely on the
10008 * standard mute methods whenever the user wants to turn
10009 * these outputs off.
10011 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10012 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10013 .dac_nids = alc883_dac_nids,
10014 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10015 .channel_mode = alc883_3ST_2ch_modes,
10016 .input_mux = &alc883_capture_source,
10018 [ALC883_ACER_ASPIRE] = {
10019 .mixers = { alc883_acer_aspire_mixer },
10020 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10021 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10022 .dac_nids = alc883_dac_nids,
10023 .dig_out_nid = ALC883_DIGOUT_NID,
10024 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10025 .channel_mode = alc883_3ST_2ch_modes,
10026 .input_mux = &alc883_capture_source,
10027 .unsol_event = alc_automute_amp_unsol_event,
10028 .setup = alc883_acer_aspire_setup,
10029 .init_hook = alc_automute_amp,
10031 [ALC888_ACER_ASPIRE_4930G] = {
10032 .mixers = { alc888_base_mixer,
10033 alc883_chmode_mixer },
10034 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10035 alc888_acer_aspire_4930g_verbs },
10036 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10037 .dac_nids = alc883_dac_nids,
10038 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10039 .adc_nids = alc883_adc_nids_rev,
10040 .capsrc_nids = alc883_capsrc_nids_rev,
10041 .dig_out_nid = ALC883_DIGOUT_NID,
10042 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10043 .channel_mode = alc883_3ST_6ch_modes,
10044 .need_dac_fix = 1,
10045 .const_channel_count = 6,
10046 .num_mux_defs =
10047 ARRAY_SIZE(alc888_2_capture_sources),
10048 .input_mux = alc888_2_capture_sources,
10049 .unsol_event = alc_automute_amp_unsol_event,
10050 .setup = alc888_acer_aspire_4930g_setup,
10051 .init_hook = alc_automute_amp,
10053 [ALC888_ACER_ASPIRE_6530G] = {
10054 .mixers = { alc888_acer_aspire_6530_mixer },
10055 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10056 alc888_acer_aspire_6530g_verbs },
10057 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10058 .dac_nids = alc883_dac_nids,
10059 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10060 .adc_nids = alc883_adc_nids_rev,
10061 .capsrc_nids = alc883_capsrc_nids_rev,
10062 .dig_out_nid = ALC883_DIGOUT_NID,
10063 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10064 .channel_mode = alc883_3ST_2ch_modes,
10065 .num_mux_defs =
10066 ARRAY_SIZE(alc888_2_capture_sources),
10067 .input_mux = alc888_acer_aspire_6530_sources,
10068 .unsol_event = alc_automute_amp_unsol_event,
10069 .setup = alc888_acer_aspire_6530g_setup,
10070 .init_hook = alc_automute_amp,
10072 [ALC888_ACER_ASPIRE_8930G] = {
10073 .mixers = { alc889_acer_aspire_8930g_mixer,
10074 alc883_chmode_mixer },
10075 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10076 alc889_acer_aspire_8930g_verbs,
10077 alc889_eapd_verbs},
10078 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10079 .dac_nids = alc883_dac_nids,
10080 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10081 .adc_nids = alc889_adc_nids,
10082 .capsrc_nids = alc889_capsrc_nids,
10083 .dig_out_nid = ALC883_DIGOUT_NID,
10084 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10085 .channel_mode = alc883_3ST_6ch_modes,
10086 .need_dac_fix = 1,
10087 .const_channel_count = 6,
10088 .num_mux_defs =
10089 ARRAY_SIZE(alc889_capture_sources),
10090 .input_mux = alc889_capture_sources,
10091 .unsol_event = alc_automute_amp_unsol_event,
10092 .setup = alc889_acer_aspire_8930g_setup,
10093 .init_hook = alc_automute_amp,
10094 #ifdef CONFIG_SND_HDA_POWER_SAVE
10095 .power_hook = alc_power_eapd,
10096 #endif
10098 [ALC888_ACER_ASPIRE_7730G] = {
10099 .mixers = { alc883_3ST_6ch_mixer,
10100 alc883_chmode_mixer },
10101 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10102 alc888_acer_aspire_7730G_verbs },
10103 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10104 .dac_nids = alc883_dac_nids,
10105 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10106 .adc_nids = alc883_adc_nids_rev,
10107 .capsrc_nids = alc883_capsrc_nids_rev,
10108 .dig_out_nid = ALC883_DIGOUT_NID,
10109 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10110 .channel_mode = alc883_3ST_6ch_modes,
10111 .need_dac_fix = 1,
10112 .const_channel_count = 6,
10113 .input_mux = &alc883_capture_source,
10114 .unsol_event = alc_automute_amp_unsol_event,
10115 .setup = alc888_acer_aspire_6530g_setup,
10116 .init_hook = alc_automute_amp,
10118 [ALC883_MEDION] = {
10119 .mixers = { alc883_fivestack_mixer,
10120 alc883_chmode_mixer },
10121 .init_verbs = { alc883_init_verbs,
10122 alc883_medion_eapd_verbs },
10123 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10124 .dac_nids = alc883_dac_nids,
10125 .adc_nids = alc883_adc_nids_alt,
10126 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10127 .capsrc_nids = alc883_capsrc_nids,
10128 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10129 .channel_mode = alc883_sixstack_modes,
10130 .input_mux = &alc883_capture_source,
10132 [ALC883_MEDION_MD2] = {
10133 .mixers = { alc883_medion_md2_mixer},
10134 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10136 .dac_nids = alc883_dac_nids,
10137 .dig_out_nid = ALC883_DIGOUT_NID,
10138 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10139 .channel_mode = alc883_3ST_2ch_modes,
10140 .input_mux = &alc883_capture_source,
10141 .unsol_event = alc_automute_amp_unsol_event,
10142 .setup = alc883_medion_md2_setup,
10143 .init_hook = alc_automute_amp,
10145 [ALC883_MEDION_WIM2160] = {
10146 .mixers = { alc883_medion_wim2160_mixer },
10147 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10148 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10149 .dac_nids = alc883_dac_nids,
10150 .dig_out_nid = ALC883_DIGOUT_NID,
10151 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10152 .adc_nids = alc883_adc_nids,
10153 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10154 .channel_mode = alc883_3ST_2ch_modes,
10155 .input_mux = &alc883_capture_source,
10156 .unsol_event = alc_automute_amp_unsol_event,
10157 .setup = alc883_medion_wim2160_setup,
10158 .init_hook = alc_automute_amp,
10160 [ALC883_LAPTOP_EAPD] = {
10161 .mixers = { alc883_base_mixer },
10162 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10163 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10164 .dac_nids = alc883_dac_nids,
10165 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10166 .channel_mode = alc883_3ST_2ch_modes,
10167 .input_mux = &alc883_capture_source,
10169 [ALC883_CLEVO_M540R] = {
10170 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10171 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10172 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10173 .dac_nids = alc883_dac_nids,
10174 .dig_out_nid = ALC883_DIGOUT_NID,
10175 .dig_in_nid = ALC883_DIGIN_NID,
10176 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10177 .channel_mode = alc883_3ST_6ch_clevo_modes,
10178 .need_dac_fix = 1,
10179 .input_mux = &alc883_capture_source,
10180 /* This machine has the hardware HP auto-muting, thus
10181 * we need no software mute via unsol event
10184 [ALC883_CLEVO_M720] = {
10185 .mixers = { alc883_clevo_m720_mixer },
10186 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10187 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10188 .dac_nids = alc883_dac_nids,
10189 .dig_out_nid = ALC883_DIGOUT_NID,
10190 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10191 .channel_mode = alc883_3ST_2ch_modes,
10192 .input_mux = &alc883_capture_source,
10193 .unsol_event = alc883_clevo_m720_unsol_event,
10194 .setup = alc883_clevo_m720_setup,
10195 .init_hook = alc883_clevo_m720_init_hook,
10197 [ALC883_LENOVO_101E_2ch] = {
10198 .mixers = { alc883_lenovo_101e_2ch_mixer},
10199 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10200 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10201 .dac_nids = alc883_dac_nids,
10202 .adc_nids = alc883_adc_nids_alt,
10203 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10204 .capsrc_nids = alc883_capsrc_nids,
10205 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10206 .channel_mode = alc883_3ST_2ch_modes,
10207 .input_mux = &alc883_lenovo_101e_capture_source,
10208 .unsol_event = alc883_lenovo_101e_unsol_event,
10209 .init_hook = alc883_lenovo_101e_all_automute,
10211 [ALC883_LENOVO_NB0763] = {
10212 .mixers = { alc883_lenovo_nb0763_mixer },
10213 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10214 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10215 .dac_nids = alc883_dac_nids,
10216 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10217 .channel_mode = alc883_3ST_2ch_modes,
10218 .need_dac_fix = 1,
10219 .input_mux = &alc883_lenovo_nb0763_capture_source,
10220 .unsol_event = alc_automute_amp_unsol_event,
10221 .setup = alc883_medion_md2_setup,
10222 .init_hook = alc_automute_amp,
10224 [ALC888_LENOVO_MS7195_DIG] = {
10225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10226 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10228 .dac_nids = alc883_dac_nids,
10229 .dig_out_nid = ALC883_DIGOUT_NID,
10230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10231 .channel_mode = alc883_3ST_6ch_modes,
10232 .need_dac_fix = 1,
10233 .input_mux = &alc883_capture_source,
10234 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10235 .init_hook = alc888_lenovo_ms7195_front_automute,
10237 [ALC883_HAIER_W66] = {
10238 .mixers = { alc883_targa_2ch_mixer},
10239 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10240 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10241 .dac_nids = alc883_dac_nids,
10242 .dig_out_nid = ALC883_DIGOUT_NID,
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10244 .channel_mode = alc883_3ST_2ch_modes,
10245 .input_mux = &alc883_capture_source,
10246 .unsol_event = alc_automute_amp_unsol_event,
10247 .setup = alc883_haier_w66_setup,
10248 .init_hook = alc_automute_amp,
10250 [ALC888_3ST_HP] = {
10251 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10252 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10253 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10254 .dac_nids = alc883_dac_nids,
10255 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10256 .channel_mode = alc888_3st_hp_modes,
10257 .need_dac_fix = 1,
10258 .input_mux = &alc883_capture_source,
10259 .unsol_event = alc_automute_amp_unsol_event,
10260 .setup = alc888_3st_hp_setup,
10261 .init_hook = alc_automute_amp,
10263 [ALC888_6ST_DELL] = {
10264 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10265 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10266 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10267 .dac_nids = alc883_dac_nids,
10268 .dig_out_nid = ALC883_DIGOUT_NID,
10269 .dig_in_nid = ALC883_DIGIN_NID,
10270 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10271 .channel_mode = alc883_sixstack_modes,
10272 .input_mux = &alc883_capture_source,
10273 .unsol_event = alc_automute_amp_unsol_event,
10274 .setup = alc888_6st_dell_setup,
10275 .init_hook = alc_automute_amp,
10277 [ALC883_MITAC] = {
10278 .mixers = { alc883_mitac_mixer },
10279 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10280 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10281 .dac_nids = alc883_dac_nids,
10282 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10283 .channel_mode = alc883_3ST_2ch_modes,
10284 .input_mux = &alc883_capture_source,
10285 .unsol_event = alc_automute_amp_unsol_event,
10286 .setup = alc883_mitac_setup,
10287 .init_hook = alc_automute_amp,
10289 [ALC883_FUJITSU_PI2515] = {
10290 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10291 .init_verbs = { alc883_init_verbs,
10292 alc883_2ch_fujitsu_pi2515_verbs},
10293 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10294 .dac_nids = alc883_dac_nids,
10295 .dig_out_nid = ALC883_DIGOUT_NID,
10296 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10297 .channel_mode = alc883_3ST_2ch_modes,
10298 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10299 .unsol_event = alc_automute_amp_unsol_event,
10300 .setup = alc883_2ch_fujitsu_pi2515_setup,
10301 .init_hook = alc_automute_amp,
10303 [ALC888_FUJITSU_XA3530] = {
10304 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10305 .init_verbs = { alc883_init_verbs,
10306 alc888_fujitsu_xa3530_verbs },
10307 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10308 .dac_nids = alc883_dac_nids,
10309 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10310 .adc_nids = alc883_adc_nids_rev,
10311 .capsrc_nids = alc883_capsrc_nids_rev,
10312 .dig_out_nid = ALC883_DIGOUT_NID,
10313 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10314 .channel_mode = alc888_4ST_8ch_intel_modes,
10315 .num_mux_defs =
10316 ARRAY_SIZE(alc888_2_capture_sources),
10317 .input_mux = alc888_2_capture_sources,
10318 .unsol_event = alc_automute_amp_unsol_event,
10319 .setup = alc888_fujitsu_xa3530_setup,
10320 .init_hook = alc_automute_amp,
10322 [ALC888_LENOVO_SKY] = {
10323 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10324 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10325 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10326 .dac_nids = alc883_dac_nids,
10327 .dig_out_nid = ALC883_DIGOUT_NID,
10328 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10329 .channel_mode = alc883_sixstack_modes,
10330 .need_dac_fix = 1,
10331 .input_mux = &alc883_lenovo_sky_capture_source,
10332 .unsol_event = alc_automute_amp_unsol_event,
10333 .setup = alc888_lenovo_sky_setup,
10334 .init_hook = alc_automute_amp,
10336 [ALC888_ASUS_M90V] = {
10337 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10338 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10339 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10340 .dac_nids = alc883_dac_nids,
10341 .dig_out_nid = ALC883_DIGOUT_NID,
10342 .dig_in_nid = ALC883_DIGIN_NID,
10343 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10344 .channel_mode = alc883_3ST_6ch_modes,
10345 .need_dac_fix = 1,
10346 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10347 .unsol_event = alc_sku_unsol_event,
10348 .setup = alc883_mode2_setup,
10349 .init_hook = alc_inithook,
10351 [ALC888_ASUS_EEE1601] = {
10352 .mixers = { alc883_asus_eee1601_mixer },
10353 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10354 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10355 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10356 .dac_nids = alc883_dac_nids,
10357 .dig_out_nid = ALC883_DIGOUT_NID,
10358 .dig_in_nid = ALC883_DIGIN_NID,
10359 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10360 .channel_mode = alc883_3ST_2ch_modes,
10361 .need_dac_fix = 1,
10362 .input_mux = &alc883_asus_eee1601_capture_source,
10363 .unsol_event = alc_sku_unsol_event,
10364 .init_hook = alc883_eee1601_inithook,
10366 [ALC1200_ASUS_P5Q] = {
10367 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10368 .init_verbs = { alc883_init_verbs },
10369 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10370 .dac_nids = alc883_dac_nids,
10371 .dig_out_nid = ALC1200_DIGOUT_NID,
10372 .dig_in_nid = ALC883_DIGIN_NID,
10373 .slave_dig_outs = alc1200_slave_dig_outs,
10374 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10375 .channel_mode = alc883_sixstack_modes,
10376 .input_mux = &alc883_capture_source,
10378 [ALC889A_MB31] = {
10379 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10380 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10381 alc880_gpio1_init_verbs },
10382 .adc_nids = alc883_adc_nids,
10383 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10384 .capsrc_nids = alc883_capsrc_nids,
10385 .dac_nids = alc883_dac_nids,
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .channel_mode = alc889A_mb31_6ch_modes,
10388 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10389 .input_mux = &alc889A_mb31_capture_source,
10390 .dig_out_nid = ALC883_DIGOUT_NID,
10391 .unsol_event = alc889A_mb31_unsol_event,
10392 .init_hook = alc889A_mb31_automute,
10394 [ALC883_SONY_VAIO_TT] = {
10395 .mixers = { alc883_vaiott_mixer },
10396 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
10399 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10400 .channel_mode = alc883_3ST_2ch_modes,
10401 .input_mux = &alc883_capture_source,
10402 .unsol_event = alc_automute_amp_unsol_event,
10403 .setup = alc883_vaiott_setup,
10404 .init_hook = alc_automute_amp,
10410 * Pin config fixes
10412 enum {
10413 PINFIX_ABIT_AW9D_MAX,
10414 PINFIX_PB_M5210,
10417 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10418 { 0x15, 0x01080104 }, /* side */
10419 { 0x16, 0x01011012 }, /* rear */
10420 { 0x17, 0x01016011 }, /* clfe */
10424 static const struct hda_verb pb_m5210_verbs[] = {
10425 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10429 static const struct alc_fixup alc882_fixups[] = {
10430 [PINFIX_ABIT_AW9D_MAX] = {
10431 .pins = alc882_abit_aw9d_pinfix
10433 [PINFIX_PB_M5210] = {
10434 .verbs = pb_m5210_verbs
10438 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10439 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10440 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10445 * BIOS auto configuration
10447 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10448 const struct auto_pin_cfg *cfg)
10450 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10453 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10454 hda_nid_t nid, int pin_type,
10455 hda_nid_t dac)
10457 int idx;
10459 /* set as output */
10460 alc_set_pin_output(codec, nid, pin_type);
10462 if (dac == 0x25)
10463 idx = 4;
10464 else if (dac >= 0x02 && dac <= 0x05)
10465 idx = dac - 2;
10466 else
10467 return;
10468 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10471 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10473 struct alc_spec *spec = codec->spec;
10474 int i;
10476 for (i = 0; i <= HDA_SIDE; i++) {
10477 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10478 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10479 if (nid)
10480 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10481 spec->multiout.dac_nids[i]);
10485 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10487 struct alc_spec *spec = codec->spec;
10488 hda_nid_t pin, dac;
10490 pin = spec->autocfg.hp_pins[0];
10491 if (pin) {
10492 dac = spec->multiout.hp_nid;
10493 if (!dac)
10494 dac = spec->multiout.dac_nids[0]; /* to front */
10495 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10497 pin = spec->autocfg.speaker_pins[0];
10498 if (pin) {
10499 dac = spec->multiout.extra_out_nid[0];
10500 if (!dac)
10501 dac = spec->multiout.dac_nids[0]; /* to front */
10502 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10506 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10508 struct alc_spec *spec = codec->spec;
10509 int i;
10511 for (i = 0; i < AUTO_PIN_LAST; i++) {
10512 hda_nid_t nid = spec->autocfg.input_pins[i];
10513 if (!nid)
10514 continue;
10515 alc_set_input_pin(codec, nid, i);
10516 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10517 snd_hda_codec_write(codec, nid, 0,
10518 AC_VERB_SET_AMP_GAIN_MUTE,
10519 AMP_OUT_MUTE);
10523 static void alc882_auto_init_input_src(struct hda_codec *codec)
10525 struct alc_spec *spec = codec->spec;
10526 int c;
10528 for (c = 0; c < spec->num_adc_nids; c++) {
10529 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10530 hda_nid_t nid = spec->capsrc_nids[c];
10531 unsigned int mux_idx;
10532 const struct hda_input_mux *imux;
10533 int conns, mute, idx, item;
10535 conns = snd_hda_get_connections(codec, nid, conn_list,
10536 ARRAY_SIZE(conn_list));
10537 if (conns < 0)
10538 continue;
10539 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10540 imux = &spec->input_mux[mux_idx];
10541 if (!imux->num_items && mux_idx > 0)
10542 imux = &spec->input_mux[0];
10543 for (idx = 0; idx < conns; idx++) {
10544 /* if the current connection is the selected one,
10545 * unmute it as default - otherwise mute it
10547 mute = AMP_IN_MUTE(idx);
10548 for (item = 0; item < imux->num_items; item++) {
10549 if (imux->items[item].index == idx) {
10550 if (spec->cur_mux[c] == item)
10551 mute = AMP_IN_UNMUTE(idx);
10552 break;
10555 /* check if we have a selector or mixer
10556 * we could check for the widget type instead, but
10557 * just check for Amp-In presence (in case of mixer
10558 * without amp-in there is something wrong, this
10559 * function shouldn't be used or capsrc nid is wrong)
10561 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10562 snd_hda_codec_write(codec, nid, 0,
10563 AC_VERB_SET_AMP_GAIN_MUTE,
10564 mute);
10565 else if (mute != AMP_IN_MUTE(idx))
10566 snd_hda_codec_write(codec, nid, 0,
10567 AC_VERB_SET_CONNECT_SEL,
10568 idx);
10573 /* add mic boosts if needed */
10574 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10576 struct alc_spec *spec = codec->spec;
10577 int err;
10578 hda_nid_t nid;
10580 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10581 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10582 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10583 "Mic Boost",
10584 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10585 if (err < 0)
10586 return err;
10588 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10589 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10590 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10591 "Front Mic Boost",
10592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10593 if (err < 0)
10594 return err;
10596 return 0;
10599 /* almost identical with ALC880 parser... */
10600 static int alc882_parse_auto_config(struct hda_codec *codec)
10602 struct alc_spec *spec = codec->spec;
10603 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10604 int err;
10606 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10607 alc882_ignore);
10608 if (err < 0)
10609 return err;
10610 if (!spec->autocfg.line_outs)
10611 return 0; /* can't find valid BIOS pin config */
10613 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10614 if (err < 0)
10615 return err;
10616 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10617 if (err < 0)
10618 return err;
10619 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10620 "Headphone");
10621 if (err < 0)
10622 return err;
10623 err = alc880_auto_create_extra_out(spec,
10624 spec->autocfg.speaker_pins[0],
10625 "Speaker");
10626 if (err < 0)
10627 return err;
10628 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10629 if (err < 0)
10630 return err;
10632 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10634 alc_auto_parse_digital(codec);
10636 if (spec->kctls.list)
10637 add_mixer(spec, spec->kctls.list);
10639 add_verb(spec, alc883_auto_init_verbs);
10640 /* if ADC 0x07 is available, initialize it, too */
10641 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10642 add_verb(spec, alc882_adc1_init_verbs);
10644 spec->num_mux_defs = 1;
10645 spec->input_mux = &spec->private_imux[0];
10647 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10649 err = alc_auto_add_mic_boost(codec);
10650 if (err < 0)
10651 return err;
10653 return 1; /* config found */
10656 /* additional initialization for auto-configuration model */
10657 static void alc882_auto_init(struct hda_codec *codec)
10659 struct alc_spec *spec = codec->spec;
10660 alc882_auto_init_multi_out(codec);
10661 alc882_auto_init_hp_out(codec);
10662 alc882_auto_init_analog_input(codec);
10663 alc882_auto_init_input_src(codec);
10664 alc_auto_init_digital(codec);
10665 if (spec->unsol_event)
10666 alc_inithook(codec);
10669 static int patch_alc882(struct hda_codec *codec)
10671 struct alc_spec *spec;
10672 int err, board_config;
10674 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10675 if (spec == NULL)
10676 return -ENOMEM;
10678 codec->spec = spec;
10680 alc_auto_parse_customize_define(codec);
10682 switch (codec->vendor_id) {
10683 case 0x10ec0882:
10684 case 0x10ec0885:
10685 break;
10686 default:
10687 /* ALC883 and variants */
10688 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10689 break;
10692 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10693 alc882_models,
10694 alc882_cfg_tbl);
10696 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10697 board_config = snd_hda_check_board_codec_sid_config(codec,
10698 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10700 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10701 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10702 codec->chip_name);
10703 board_config = ALC882_AUTO;
10706 if (board_config == ALC882_AUTO)
10707 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1);
10709 if (board_config == ALC882_AUTO) {
10710 /* automatic parse from the BIOS config */
10711 err = alc882_parse_auto_config(codec);
10712 if (err < 0) {
10713 alc_free(codec);
10714 return err;
10715 } else if (!err) {
10716 printk(KERN_INFO
10717 "hda_codec: Cannot set up configuration "
10718 "from BIOS. Using base mode...\n");
10719 board_config = ALC882_3ST_DIG;
10723 if (has_cdefine_beep(codec)) {
10724 err = snd_hda_attach_beep_device(codec, 0x1);
10725 if (err < 0) {
10726 alc_free(codec);
10727 return err;
10731 if (board_config != ALC882_AUTO)
10732 setup_preset(codec, &alc882_presets[board_config]);
10734 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10735 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10736 /* FIXME: setup DAC5 */
10737 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10738 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10740 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10741 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10743 if (!spec->adc_nids && spec->input_mux) {
10744 int i, j;
10745 spec->num_adc_nids = 0;
10746 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10747 const struct hda_input_mux *imux = spec->input_mux;
10748 hda_nid_t cap;
10749 hda_nid_t items[16];
10750 hda_nid_t nid = alc882_adc_nids[i];
10751 unsigned int wcap = get_wcaps(codec, nid);
10752 /* get type */
10753 wcap = get_wcaps_type(wcap);
10754 if (wcap != AC_WID_AUD_IN)
10755 continue;
10756 spec->private_adc_nids[spec->num_adc_nids] = nid;
10757 err = snd_hda_get_connections(codec, nid, &cap, 1);
10758 if (err < 0)
10759 continue;
10760 err = snd_hda_get_connections(codec, cap, items,
10761 ARRAY_SIZE(items));
10762 if (err < 0)
10763 continue;
10764 for (j = 0; j < imux->num_items; j++)
10765 if (imux->items[j].index >= err)
10766 break;
10767 if (j < imux->num_items)
10768 continue;
10769 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10770 spec->num_adc_nids++;
10772 spec->adc_nids = spec->private_adc_nids;
10773 spec->capsrc_nids = spec->private_capsrc_nids;
10776 set_capture_mixer(codec);
10778 if (has_cdefine_beep(codec))
10779 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10781 if (board_config == ALC882_AUTO)
10782 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
10784 spec->vmaster_nid = 0x0c;
10786 codec->patch_ops = alc_patch_ops;
10787 if (board_config == ALC882_AUTO)
10788 spec->init_hook = alc882_auto_init;
10789 #ifdef CONFIG_SND_HDA_POWER_SAVE
10790 if (!spec->loopback.amplist)
10791 spec->loopback.amplist = alc882_loopbacks;
10792 #endif
10794 return 0;
10799 * ALC262 support
10802 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10803 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10805 #define alc262_dac_nids alc260_dac_nids
10806 #define alc262_adc_nids alc882_adc_nids
10807 #define alc262_adc_nids_alt alc882_adc_nids_alt
10808 #define alc262_capsrc_nids alc882_capsrc_nids
10809 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10811 #define alc262_modes alc260_modes
10812 #define alc262_capture_source alc882_capture_source
10814 static hda_nid_t alc262_dmic_adc_nids[1] = {
10815 /* ADC0 */
10816 0x09
10819 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10821 static struct snd_kcontrol_new alc262_base_mixer[] = {
10822 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10823 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10824 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10825 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10830 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10831 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10832 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10833 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10836 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10837 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10838 { } /* end */
10841 /* update HP, line and mono-out pins according to the master switch */
10842 static void alc262_hp_master_update(struct hda_codec *codec)
10844 struct alc_spec *spec = codec->spec;
10845 int val = spec->master_sw;
10847 /* HP & line-out */
10848 snd_hda_codec_write_cache(codec, 0x1b, 0,
10849 AC_VERB_SET_PIN_WIDGET_CONTROL,
10850 val ? PIN_HP : 0);
10851 snd_hda_codec_write_cache(codec, 0x15, 0,
10852 AC_VERB_SET_PIN_WIDGET_CONTROL,
10853 val ? PIN_HP : 0);
10854 /* mono (speaker) depending on the HP jack sense */
10855 val = val && !spec->jack_present;
10856 snd_hda_codec_write_cache(codec, 0x16, 0,
10857 AC_VERB_SET_PIN_WIDGET_CONTROL,
10858 val ? PIN_OUT : 0);
10861 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10863 struct alc_spec *spec = codec->spec;
10865 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10866 alc262_hp_master_update(codec);
10869 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10871 if ((res >> 26) != ALC880_HP_EVENT)
10872 return;
10873 alc262_hp_bpc_automute(codec);
10876 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10878 struct alc_spec *spec = codec->spec;
10880 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10881 alc262_hp_master_update(codec);
10884 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10885 unsigned int res)
10887 if ((res >> 26) != ALC880_HP_EVENT)
10888 return;
10889 alc262_hp_wildwest_automute(codec);
10892 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10894 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10895 struct snd_ctl_elem_value *ucontrol)
10897 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10898 struct alc_spec *spec = codec->spec;
10899 int val = !!*ucontrol->value.integer.value;
10901 if (val == spec->master_sw)
10902 return 0;
10903 spec->master_sw = val;
10904 alc262_hp_master_update(codec);
10905 return 1;
10908 #define ALC262_HP_MASTER_SWITCH \
10910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10911 .name = "Master Playback Switch", \
10912 .info = snd_ctl_boolean_mono_info, \
10913 .get = alc262_hp_master_sw_get, \
10914 .put = alc262_hp_master_sw_put, \
10915 }, \
10917 .iface = NID_MAPPING, \
10918 .name = "Master Playback Switch", \
10919 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10923 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10924 ALC262_HP_MASTER_SWITCH,
10925 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10926 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10927 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10928 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10929 HDA_OUTPUT),
10930 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10931 HDA_OUTPUT),
10932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10937 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10938 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10939 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10942 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10943 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10944 { } /* end */
10947 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10948 ALC262_HP_MASTER_SWITCH,
10949 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10950 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10951 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10952 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10953 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10954 HDA_OUTPUT),
10955 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10956 HDA_OUTPUT),
10957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10959 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10960 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10961 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10964 { } /* end */
10967 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10968 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10969 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10970 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10971 { } /* end */
10974 /* mute/unmute internal speaker according to the hp jack and mute state */
10975 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10977 struct alc_spec *spec = codec->spec;
10979 spec->autocfg.hp_pins[0] = 0x15;
10980 spec->autocfg.speaker_pins[0] = 0x14;
10983 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10984 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10985 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10986 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10989 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10991 { } /* end */
10994 static struct hda_verb alc262_hp_t5735_verbs[] = {
10995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10996 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10998 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11002 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11006 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11009 { } /* end */
11012 static struct hda_verb alc262_hp_rp5700_verbs[] = {
11013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11014 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11015 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11016 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11017 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11018 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11020 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11022 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11026 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11027 .num_items = 1,
11028 .items = {
11029 { "Line", 0x1 },
11033 /* bind hp and internal speaker mute (with plug check) as master switch */
11034 static void alc262_hippo_master_update(struct hda_codec *codec)
11036 struct alc_spec *spec = codec->spec;
11037 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11038 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11039 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11040 unsigned int mute;
11042 /* HP */
11043 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11044 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11045 HDA_AMP_MUTE, mute);
11046 /* mute internal speaker per jack sense */
11047 if (spec->jack_present)
11048 mute = HDA_AMP_MUTE;
11049 if (line_nid)
11050 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11051 HDA_AMP_MUTE, mute);
11052 if (speaker_nid && speaker_nid != line_nid)
11053 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11054 HDA_AMP_MUTE, mute);
11057 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11059 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11060 struct snd_ctl_elem_value *ucontrol)
11062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11063 struct alc_spec *spec = codec->spec;
11064 int val = !!*ucontrol->value.integer.value;
11066 if (val == spec->master_sw)
11067 return 0;
11068 spec->master_sw = val;
11069 alc262_hippo_master_update(codec);
11070 return 1;
11073 #define ALC262_HIPPO_MASTER_SWITCH \
11075 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11076 .name = "Master Playback Switch", \
11077 .info = snd_ctl_boolean_mono_info, \
11078 .get = alc262_hippo_master_sw_get, \
11079 .put = alc262_hippo_master_sw_put, \
11080 }, \
11082 .iface = NID_MAPPING, \
11083 .name = "Master Playback Switch", \
11084 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11085 (SUBDEV_SPEAKER(0) << 16), \
11088 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11089 ALC262_HIPPO_MASTER_SWITCH,
11090 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11094 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11095 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11098 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11099 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11100 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11102 { } /* end */
11105 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11106 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11107 ALC262_HIPPO_MASTER_SWITCH,
11108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11118 { } /* end */
11121 /* mute/unmute internal speaker according to the hp jack and mute state */
11122 static void alc262_hippo_automute(struct hda_codec *codec)
11124 struct alc_spec *spec = codec->spec;
11125 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11127 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11128 alc262_hippo_master_update(codec);
11131 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11133 if ((res >> 26) != ALC880_HP_EVENT)
11134 return;
11135 alc262_hippo_automute(codec);
11138 static void alc262_hippo_setup(struct hda_codec *codec)
11140 struct alc_spec *spec = codec->spec;
11142 spec->autocfg.hp_pins[0] = 0x15;
11143 spec->autocfg.speaker_pins[0] = 0x14;
11146 static void alc262_hippo1_setup(struct hda_codec *codec)
11148 struct alc_spec *spec = codec->spec;
11150 spec->autocfg.hp_pins[0] = 0x1b;
11151 spec->autocfg.speaker_pins[0] = 0x14;
11155 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11156 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11157 ALC262_HIPPO_MASTER_SWITCH,
11158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11160 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11161 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11162 { } /* end */
11165 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11166 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11167 ALC262_HIPPO_MASTER_SWITCH,
11168 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11171 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11172 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11173 { } /* end */
11176 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11177 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11178 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11179 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11180 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11184 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11185 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11186 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11188 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11189 { } /* end */
11192 static struct hda_verb alc262_tyan_verbs[] = {
11193 /* Headphone automute */
11194 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11198 /* P11 AUX_IN, white 4-pin connector */
11199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11200 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11201 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11202 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11207 /* unsolicited event for HP jack sensing */
11208 static void alc262_tyan_setup(struct hda_codec *codec)
11210 struct alc_spec *spec = codec->spec;
11212 spec->autocfg.hp_pins[0] = 0x1b;
11213 spec->autocfg.speaker_pins[0] = 0x15;
11217 #define alc262_capture_mixer alc882_capture_mixer
11218 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11221 * generic initialization of ADC, input mixers and output mixers
11223 static struct hda_verb alc262_init_verbs[] = {
11225 * Unmute ADC0-2 and set the default input to mic-in
11227 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11228 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11229 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11230 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11231 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11232 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11234 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11235 * mixer widget
11236 * Note: PASD motherboards uses the Line In 2 as the input for
11237 * front panel mic (mic 2)
11239 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11244 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11247 * Set up output mixers (0x0c - 0x0e)
11249 /* set vol=0 to output mixers */
11250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11253 /* set up input amps for analog loopback */
11254 /* Amp Indices: DAC = 0, mixer = 1 */
11255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11263 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11264 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11265 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11266 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11267 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11272 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11278 /* FIXME: use matrix-type input source selection */
11279 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11280 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11284 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11285 /* Input mixer2 */
11286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11288 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11289 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11290 /* Input mixer3 */
11291 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11292 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11293 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11294 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11299 static struct hda_verb alc262_eapd_verbs[] = {
11300 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11301 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11305 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11306 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11310 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11315 static struct hda_verb alc262_sony_unsol_verbs[] = {
11316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11317 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11320 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11325 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11329 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11331 { } /* end */
11334 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11335 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11336 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11339 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11340 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11341 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11342 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11346 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11348 struct alc_spec *spec = codec->spec;
11350 spec->autocfg.hp_pins[0] = 0x15;
11351 spec->autocfg.speaker_pins[0] = 0x14;
11352 spec->ext_mic.pin = 0x18;
11353 spec->ext_mic.mux_idx = 0;
11354 spec->int_mic.pin = 0x12;
11355 spec->int_mic.mux_idx = 9;
11356 spec->auto_mic = 1;
11360 * nec model
11361 * 0x15 = headphone
11362 * 0x16 = internal speaker
11363 * 0x18 = external mic
11366 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11367 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11368 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11374 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11375 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11376 { } /* end */
11379 static struct hda_verb alc262_nec_verbs[] = {
11380 /* Unmute Speaker */
11381 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11383 /* Headphone */
11384 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11385 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11387 /* External mic to headphone */
11388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11389 /* External mic to speaker */
11390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11395 * fujitsu model
11396 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11397 * 0x1b = port replicator headphone out
11400 #define ALC_HP_EVENT 0x37
11402 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11405 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11410 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11416 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11417 /* Front Mic pin: input vref at 50% */
11418 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11419 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11423 static struct hda_input_mux alc262_fujitsu_capture_source = {
11424 .num_items = 3,
11425 .items = {
11426 { "Mic", 0x0 },
11427 { "Int Mic", 0x1 },
11428 { "CD", 0x4 },
11432 static struct hda_input_mux alc262_HP_capture_source = {
11433 .num_items = 5,
11434 .items = {
11435 { "Mic", 0x0 },
11436 { "Front Mic", 0x1 },
11437 { "Line", 0x2 },
11438 { "CD", 0x4 },
11439 { "AUX IN", 0x6 },
11443 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11444 .num_items = 4,
11445 .items = {
11446 { "Mic", 0x0 },
11447 { "Front Mic", 0x2 },
11448 { "Line", 0x1 },
11449 { "CD", 0x4 },
11453 /* mute/unmute internal speaker according to the hp jacks and mute state */
11454 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11456 struct alc_spec *spec = codec->spec;
11457 unsigned int mute;
11459 if (force || !spec->sense_updated) {
11460 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11461 snd_hda_jack_detect(codec, 0x1b);
11462 spec->sense_updated = 1;
11464 /* unmute internal speaker only if both HPs are unplugged and
11465 * master switch is on
11467 if (spec->jack_present)
11468 mute = HDA_AMP_MUTE;
11469 else
11470 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11471 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11472 HDA_AMP_MUTE, mute);
11475 /* unsolicited event for HP jack sensing */
11476 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11477 unsigned int res)
11479 if ((res >> 26) != ALC_HP_EVENT)
11480 return;
11481 alc262_fujitsu_automute(codec, 1);
11484 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11486 alc262_fujitsu_automute(codec, 1);
11489 /* bind volumes of both NID 0x0c and 0x0d */
11490 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11491 .ops = &snd_hda_bind_vol,
11492 .values = {
11493 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11494 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11499 /* mute/unmute internal speaker according to the hp jack and mute state */
11500 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11502 struct alc_spec *spec = codec->spec;
11503 unsigned int mute;
11505 if (force || !spec->sense_updated) {
11506 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11507 spec->sense_updated = 1;
11509 if (spec->jack_present) {
11510 /* mute internal speaker */
11511 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11512 HDA_AMP_MUTE, HDA_AMP_MUTE);
11513 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11514 HDA_AMP_MUTE, HDA_AMP_MUTE);
11515 } else {
11516 /* unmute internal speaker if necessary */
11517 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11518 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11519 HDA_AMP_MUTE, mute);
11520 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11521 HDA_AMP_MUTE, mute);
11525 /* unsolicited event for HP jack sensing */
11526 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11527 unsigned int res)
11529 if ((res >> 26) != ALC_HP_EVENT)
11530 return;
11531 alc262_lenovo_3000_automute(codec, 1);
11534 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11535 int dir, int idx, long *valp)
11537 int i, change = 0;
11539 for (i = 0; i < 2; i++, valp++)
11540 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11541 HDA_AMP_MUTE,
11542 *valp ? 0 : HDA_AMP_MUTE);
11543 return change;
11546 /* bind hp and internal speaker mute (with plug check) */
11547 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11548 struct snd_ctl_elem_value *ucontrol)
11550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11551 long *valp = ucontrol->value.integer.value;
11552 int change;
11554 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11555 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11556 if (change)
11557 alc262_fujitsu_automute(codec, 0);
11558 return change;
11561 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11562 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11565 .name = "Master Playback Switch",
11566 .subdevice = HDA_SUBDEV_AMP_FLAG,
11567 .info = snd_hda_mixer_amp_switch_info,
11568 .get = snd_hda_mixer_amp_switch_get,
11569 .put = alc262_fujitsu_master_sw_put,
11570 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11573 .iface = NID_MAPPING,
11574 .name = "Master Playback Switch",
11575 .private_value = 0x1b,
11577 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11578 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11580 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11581 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11582 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11584 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11585 { } /* end */
11588 /* bind hp and internal speaker mute (with plug check) */
11589 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11590 struct snd_ctl_elem_value *ucontrol)
11592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11593 long *valp = ucontrol->value.integer.value;
11594 int change;
11596 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11597 if (change)
11598 alc262_lenovo_3000_automute(codec, 0);
11599 return change;
11602 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11603 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11605 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11606 .name = "Master Playback Switch",
11607 .subdevice = HDA_SUBDEV_AMP_FLAG,
11608 .info = snd_hda_mixer_amp_switch_info,
11609 .get = snd_hda_mixer_amp_switch_get,
11610 .put = alc262_lenovo_3000_master_sw_put,
11611 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11613 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11614 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11618 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11619 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11620 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11621 { } /* end */
11624 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11625 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11626 ALC262_HIPPO_MASTER_SWITCH,
11627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11631 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11632 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11633 { } /* end */
11636 /* additional init verbs for Benq laptops */
11637 static struct hda_verb alc262_EAPD_verbs[] = {
11638 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11639 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11643 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11644 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11645 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11647 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11648 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11652 /* Samsung Q1 Ultra Vista model setup */
11653 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11654 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11655 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11658 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
11660 { } /* end */
11663 static struct hda_verb alc262_ultra_verbs[] = {
11664 /* output mixer */
11665 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11668 /* speaker */
11669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11670 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11671 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11673 /* HP */
11674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11676 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11678 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11679 /* internal mic */
11680 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11681 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11682 /* ADC, choose mic */
11683 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11684 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11685 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11686 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11687 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11696 /* mute/unmute internal speaker according to the hp jack and mute state */
11697 static void alc262_ultra_automute(struct hda_codec *codec)
11699 struct alc_spec *spec = codec->spec;
11700 unsigned int mute;
11702 mute = 0;
11703 /* auto-mute only when HP is used as HP */
11704 if (!spec->cur_mux[0]) {
11705 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11706 if (spec->jack_present)
11707 mute = HDA_AMP_MUTE;
11709 /* mute/unmute internal speaker */
11710 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11711 HDA_AMP_MUTE, mute);
11712 /* mute/unmute HP */
11713 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11714 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11717 /* unsolicited event for HP jack sensing */
11718 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11719 unsigned int res)
11721 if ((res >> 26) != ALC880_HP_EVENT)
11722 return;
11723 alc262_ultra_automute(codec);
11726 static struct hda_input_mux alc262_ultra_capture_source = {
11727 .num_items = 2,
11728 .items = {
11729 { "Mic", 0x1 },
11730 { "Headphone", 0x7 },
11734 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11735 struct snd_ctl_elem_value *ucontrol)
11737 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11738 struct alc_spec *spec = codec->spec;
11739 int ret;
11741 ret = alc_mux_enum_put(kcontrol, ucontrol);
11742 if (!ret)
11743 return 0;
11744 /* reprogram the HP pin as mic or HP according to the input source */
11745 snd_hda_codec_write_cache(codec, 0x15, 0,
11746 AC_VERB_SET_PIN_WIDGET_CONTROL,
11747 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11748 alc262_ultra_automute(codec); /* mute/unmute HP */
11749 return ret;
11752 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11753 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11754 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11757 .name = "Capture Source",
11758 .info = alc_mux_enum_info,
11759 .get = alc_mux_enum_get,
11760 .put = alc262_ultra_mux_enum_put,
11763 .iface = NID_MAPPING,
11764 .name = "Capture Source",
11765 .private_value = 0x15,
11767 { } /* end */
11770 /* We use two mixers depending on the output pin; 0x16 is a mono output
11771 * and thus it's bound with a different mixer.
11772 * This function returns which mixer amp should be used.
11774 static int alc262_check_volbit(hda_nid_t nid)
11776 if (!nid)
11777 return 0;
11778 else if (nid == 0x16)
11779 return 2;
11780 else
11781 return 1;
11784 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11785 const char *pfx, int *vbits)
11787 unsigned long val;
11788 int vbit;
11790 vbit = alc262_check_volbit(nid);
11791 if (!vbit)
11792 return 0;
11793 if (*vbits & vbit) /* a volume control for this mixer already there */
11794 return 0;
11795 *vbits |= vbit;
11796 if (vbit == 2)
11797 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11798 else
11799 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11800 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
11803 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11804 const char *pfx)
11806 unsigned long val;
11808 if (!nid)
11809 return 0;
11810 if (nid == 0x16)
11811 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11812 else
11813 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11814 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
11817 /* add playback controls from the parsed DAC table */
11818 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11819 const struct auto_pin_cfg *cfg)
11821 const char *pfx;
11822 int vbits;
11823 int err;
11825 spec->multiout.num_dacs = 1; /* only use one dac */
11826 spec->multiout.dac_nids = spec->private_dac_nids;
11827 spec->multiout.dac_nids[0] = 2;
11829 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11830 pfx = "Master";
11831 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11832 pfx = "Speaker";
11833 else
11834 pfx = "Front";
11835 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11836 if (err < 0)
11837 return err;
11838 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11839 if (err < 0)
11840 return err;
11841 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11842 if (err < 0)
11843 return err;
11845 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11846 alc262_check_volbit(cfg->speaker_pins[0]) |
11847 alc262_check_volbit(cfg->hp_pins[0]);
11848 if (vbits == 1 || vbits == 2)
11849 pfx = "Master"; /* only one mixer is used */
11850 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11851 pfx = "Speaker";
11852 else
11853 pfx = "Front";
11854 vbits = 0;
11855 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11856 if (err < 0)
11857 return err;
11858 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11859 &vbits);
11860 if (err < 0)
11861 return err;
11862 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11863 &vbits);
11864 if (err < 0)
11865 return err;
11866 return 0;
11869 #define alc262_auto_create_input_ctls \
11870 alc882_auto_create_input_ctls
11873 * generic initialization of ADC, input mixers and output mixers
11875 static struct hda_verb alc262_volume_init_verbs[] = {
11877 * Unmute ADC0-2 and set the default input to mic-in
11879 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11880 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11881 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11882 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11883 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11884 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11886 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11887 * mixer widget
11888 * Note: PASD motherboards uses the Line In 2 as the input for
11889 * front panel mic (mic 2)
11891 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11892 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11893 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11894 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11895 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11896 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11899 * Set up output mixers (0x0c - 0x0f)
11901 /* set vol=0 to output mixers */
11902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11903 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11904 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11906 /* set up input amps for analog loopback */
11907 /* Amp Indices: DAC = 0, mixer = 1 */
11908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11909 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11911 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11913 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11915 /* FIXME: use matrix-type input source selection */
11916 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11917 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11918 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11919 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11920 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11921 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11922 /* Input mixer2 */
11923 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11924 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11925 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11926 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11927 /* Input mixer3 */
11928 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11929 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11931 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11936 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11938 * Unmute ADC0-2 and set the default input to mic-in
11940 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11941 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11942 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11947 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11948 * mixer widget
11949 * Note: PASD motherboards uses the Line In 2 as the input for
11950 * front panel mic (mic 2)
11952 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11953 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11954 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11955 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11956 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11957 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11958 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11959 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11962 * Set up output mixers (0x0c - 0x0e)
11964 /* set vol=0 to output mixers */
11965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11966 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11969 /* set up input amps for analog loopback */
11970 /* Amp Indices: DAC = 0, mixer = 1 */
11971 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11973 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11975 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11978 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11980 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11985 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11988 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11989 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11990 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11991 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11992 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11994 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11995 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11997 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11998 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11999 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12002 /* FIXME: use matrix-type input source selection */
12003 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12004 /* Input mixer1: only unmute Mic */
12005 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12006 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12007 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12008 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12009 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12010 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12011 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12012 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12013 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12014 /* Input mixer2 */
12015 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12017 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12018 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12019 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12020 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12021 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12022 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12023 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12024 /* Input mixer3 */
12025 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12026 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12027 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12028 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12029 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12033 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12040 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12042 * Unmute ADC0-2 and set the default input to mic-in
12044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12051 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12052 * mixer widget
12053 * Note: PASD motherboards uses the Line In 2 as the input for front
12054 * panel mic (mic 2)
12056 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12057 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12058 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12059 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12060 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12061 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12062 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12063 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12064 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12066 * Set up output mixers (0x0c - 0x0e)
12068 /* set vol=0 to output mixers */
12069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12073 /* set up input amps for analog loopback */
12074 /* Amp Indices: DAC = 0, mixer = 1 */
12075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12084 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12085 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12086 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12087 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12088 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12089 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12092 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12094 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12097 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12098 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12099 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12101 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12102 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12104 /* FIXME: use matrix-type input source selection */
12105 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12106 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12107 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12108 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12109 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12110 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12111 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12112 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12113 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12114 /* Input mixer2 */
12115 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12118 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12119 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12120 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12121 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12122 /* Input mixer3 */
12123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12124 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12126 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12127 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12128 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12129 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12131 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12136 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12142 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12143 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12145 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12148 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12154 #ifdef CONFIG_SND_HDA_POWER_SAVE
12155 #define alc262_loopbacks alc880_loopbacks
12156 #endif
12158 /* pcm configuration: identical with ALC880 */
12159 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12160 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12161 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12162 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12165 * BIOS auto configuration
12167 static int alc262_parse_auto_config(struct hda_codec *codec)
12169 struct alc_spec *spec = codec->spec;
12170 int err;
12171 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12174 alc262_ignore);
12175 if (err < 0)
12176 return err;
12177 if (!spec->autocfg.line_outs) {
12178 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12179 spec->multiout.max_channels = 2;
12180 spec->no_analog = 1;
12181 goto dig_only;
12183 return 0; /* can't find valid BIOS pin config */
12185 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12186 if (err < 0)
12187 return err;
12188 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12189 if (err < 0)
12190 return err;
12192 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12194 dig_only:
12195 alc_auto_parse_digital(codec);
12197 if (spec->kctls.list)
12198 add_mixer(spec, spec->kctls.list);
12200 add_verb(spec, alc262_volume_init_verbs);
12201 spec->num_mux_defs = 1;
12202 spec->input_mux = &spec->private_imux[0];
12204 err = alc_auto_add_mic_boost(codec);
12205 if (err < 0)
12206 return err;
12208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12210 return 1;
12213 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12214 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12215 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12216 #define alc262_auto_init_input_src alc882_auto_init_input_src
12219 /* init callback for auto-configuration model -- overriding the default init */
12220 static void alc262_auto_init(struct hda_codec *codec)
12222 struct alc_spec *spec = codec->spec;
12223 alc262_auto_init_multi_out(codec);
12224 alc262_auto_init_hp_out(codec);
12225 alc262_auto_init_analog_input(codec);
12226 alc262_auto_init_input_src(codec);
12227 alc_auto_init_digital(codec);
12228 if (spec->unsol_event)
12229 alc_inithook(codec);
12233 * configuration and preset
12235 static const char *alc262_models[ALC262_MODEL_LAST] = {
12236 [ALC262_BASIC] = "basic",
12237 [ALC262_HIPPO] = "hippo",
12238 [ALC262_HIPPO_1] = "hippo_1",
12239 [ALC262_FUJITSU] = "fujitsu",
12240 [ALC262_HP_BPC] = "hp-bpc",
12241 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12242 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12243 [ALC262_HP_RP5700] = "hp-rp5700",
12244 [ALC262_BENQ_ED8] = "benq",
12245 [ALC262_BENQ_T31] = "benq-t31",
12246 [ALC262_SONY_ASSAMD] = "sony-assamd",
12247 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12248 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12249 [ALC262_ULTRA] = "ultra",
12250 [ALC262_LENOVO_3000] = "lenovo-3000",
12251 [ALC262_NEC] = "nec",
12252 [ALC262_TYAN] = "tyan",
12253 [ALC262_AUTO] = "auto",
12256 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12257 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12258 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12259 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12260 ALC262_HP_BPC),
12261 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12262 ALC262_HP_BPC),
12263 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12264 ALC262_HP_BPC),
12265 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12266 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12267 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12268 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12269 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12270 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12271 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12272 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12273 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12274 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12275 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12276 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12277 ALC262_HP_TC_T5735),
12278 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12279 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12280 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12281 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12282 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12283 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12284 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12285 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12286 #if 0 /* disable the quirk since model=auto works better in recent versions */
12287 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12288 ALC262_SONY_ASSAMD),
12289 #endif
12290 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12291 ALC262_TOSHIBA_RX1),
12292 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12293 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12294 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12295 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12296 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12297 ALC262_ULTRA),
12298 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12299 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12300 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12301 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12302 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12306 static struct alc_config_preset alc262_presets[] = {
12307 [ALC262_BASIC] = {
12308 .mixers = { alc262_base_mixer },
12309 .init_verbs = { alc262_init_verbs },
12310 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12311 .dac_nids = alc262_dac_nids,
12312 .hp_nid = 0x03,
12313 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12314 .channel_mode = alc262_modes,
12315 .input_mux = &alc262_capture_source,
12317 [ALC262_HIPPO] = {
12318 .mixers = { alc262_hippo_mixer },
12319 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12320 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12321 .dac_nids = alc262_dac_nids,
12322 .hp_nid = 0x03,
12323 .dig_out_nid = ALC262_DIGOUT_NID,
12324 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12325 .channel_mode = alc262_modes,
12326 .input_mux = &alc262_capture_source,
12327 .unsol_event = alc262_hippo_unsol_event,
12328 .setup = alc262_hippo_setup,
12329 .init_hook = alc262_hippo_automute,
12331 [ALC262_HIPPO_1] = {
12332 .mixers = { alc262_hippo1_mixer },
12333 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12334 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12335 .dac_nids = alc262_dac_nids,
12336 .hp_nid = 0x02,
12337 .dig_out_nid = ALC262_DIGOUT_NID,
12338 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12339 .channel_mode = alc262_modes,
12340 .input_mux = &alc262_capture_source,
12341 .unsol_event = alc262_hippo_unsol_event,
12342 .setup = alc262_hippo1_setup,
12343 .init_hook = alc262_hippo_automute,
12345 [ALC262_FUJITSU] = {
12346 .mixers = { alc262_fujitsu_mixer },
12347 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12348 alc262_fujitsu_unsol_verbs },
12349 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12350 .dac_nids = alc262_dac_nids,
12351 .hp_nid = 0x03,
12352 .dig_out_nid = ALC262_DIGOUT_NID,
12353 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12354 .channel_mode = alc262_modes,
12355 .input_mux = &alc262_fujitsu_capture_source,
12356 .unsol_event = alc262_fujitsu_unsol_event,
12357 .init_hook = alc262_fujitsu_init_hook,
12359 [ALC262_HP_BPC] = {
12360 .mixers = { alc262_HP_BPC_mixer },
12361 .init_verbs = { alc262_HP_BPC_init_verbs },
12362 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12363 .dac_nids = alc262_dac_nids,
12364 .hp_nid = 0x03,
12365 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12366 .channel_mode = alc262_modes,
12367 .input_mux = &alc262_HP_capture_source,
12368 .unsol_event = alc262_hp_bpc_unsol_event,
12369 .init_hook = alc262_hp_bpc_automute,
12371 [ALC262_HP_BPC_D7000_WF] = {
12372 .mixers = { alc262_HP_BPC_WildWest_mixer },
12373 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12374 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12375 .dac_nids = alc262_dac_nids,
12376 .hp_nid = 0x03,
12377 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12378 .channel_mode = alc262_modes,
12379 .input_mux = &alc262_HP_D7000_capture_source,
12380 .unsol_event = alc262_hp_wildwest_unsol_event,
12381 .init_hook = alc262_hp_wildwest_automute,
12383 [ALC262_HP_BPC_D7000_WL] = {
12384 .mixers = { alc262_HP_BPC_WildWest_mixer,
12385 alc262_HP_BPC_WildWest_option_mixer },
12386 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12387 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12388 .dac_nids = alc262_dac_nids,
12389 .hp_nid = 0x03,
12390 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12391 .channel_mode = alc262_modes,
12392 .input_mux = &alc262_HP_D7000_capture_source,
12393 .unsol_event = alc262_hp_wildwest_unsol_event,
12394 .init_hook = alc262_hp_wildwest_automute,
12396 [ALC262_HP_TC_T5735] = {
12397 .mixers = { alc262_hp_t5735_mixer },
12398 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12399 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12400 .dac_nids = alc262_dac_nids,
12401 .hp_nid = 0x03,
12402 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12403 .channel_mode = alc262_modes,
12404 .input_mux = &alc262_capture_source,
12405 .unsol_event = alc_sku_unsol_event,
12406 .setup = alc262_hp_t5735_setup,
12407 .init_hook = alc_inithook,
12409 [ALC262_HP_RP5700] = {
12410 .mixers = { alc262_hp_rp5700_mixer },
12411 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12412 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12413 .dac_nids = alc262_dac_nids,
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_hp_rp5700_capture_source,
12418 [ALC262_BENQ_ED8] = {
12419 .mixers = { alc262_base_mixer },
12420 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12421 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12422 .dac_nids = alc262_dac_nids,
12423 .hp_nid = 0x03,
12424 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12425 .channel_mode = alc262_modes,
12426 .input_mux = &alc262_capture_source,
12428 [ALC262_SONY_ASSAMD] = {
12429 .mixers = { alc262_sony_mixer },
12430 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x02,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
12436 .input_mux = &alc262_capture_source,
12437 .unsol_event = alc262_hippo_unsol_event,
12438 .setup = alc262_hippo_setup,
12439 .init_hook = alc262_hippo_automute,
12441 [ALC262_BENQ_T31] = {
12442 .mixers = { alc262_benq_t31_mixer },
12443 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12444 alc_hp15_unsol_verbs },
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
12450 .input_mux = &alc262_capture_source,
12451 .unsol_event = alc262_hippo_unsol_event,
12452 .setup = alc262_hippo_setup,
12453 .init_hook = alc262_hippo_automute,
12455 [ALC262_ULTRA] = {
12456 .mixers = { alc262_ultra_mixer },
12457 .cap_mixer = alc262_ultra_capture_mixer,
12458 .init_verbs = { alc262_ultra_verbs },
12459 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12460 .dac_nids = alc262_dac_nids,
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_ultra_capture_source,
12464 .adc_nids = alc262_adc_nids, /* ADC0 */
12465 .capsrc_nids = alc262_capsrc_nids,
12466 .num_adc_nids = 1, /* single ADC */
12467 .unsol_event = alc262_ultra_unsol_event,
12468 .init_hook = alc262_ultra_automute,
12470 [ALC262_LENOVO_3000] = {
12471 .mixers = { alc262_lenovo_3000_mixer },
12472 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12473 alc262_lenovo_3000_unsol_verbs,
12474 alc262_lenovo_3000_init_verbs },
12475 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12476 .dac_nids = alc262_dac_nids,
12477 .hp_nid = 0x03,
12478 .dig_out_nid = ALC262_DIGOUT_NID,
12479 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12480 .channel_mode = alc262_modes,
12481 .input_mux = &alc262_fujitsu_capture_source,
12482 .unsol_event = alc262_lenovo_3000_unsol_event,
12484 [ALC262_NEC] = {
12485 .mixers = { alc262_nec_mixer },
12486 .init_verbs = { alc262_nec_verbs },
12487 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12488 .dac_nids = alc262_dac_nids,
12489 .hp_nid = 0x03,
12490 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12491 .channel_mode = alc262_modes,
12492 .input_mux = &alc262_capture_source,
12494 [ALC262_TOSHIBA_S06] = {
12495 .mixers = { alc262_toshiba_s06_mixer },
12496 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12497 alc262_eapd_verbs },
12498 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12499 .capsrc_nids = alc262_dmic_capsrc_nids,
12500 .dac_nids = alc262_dac_nids,
12501 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12502 .num_adc_nids = 1, /* single ADC */
12503 .dig_out_nid = ALC262_DIGOUT_NID,
12504 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12505 .channel_mode = alc262_modes,
12506 .unsol_event = alc_sku_unsol_event,
12507 .setup = alc262_toshiba_s06_setup,
12508 .init_hook = alc_inithook,
12510 [ALC262_TOSHIBA_RX1] = {
12511 .mixers = { alc262_toshiba_rx1_mixer },
12512 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12513 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12514 .dac_nids = alc262_dac_nids,
12515 .hp_nid = 0x03,
12516 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12517 .channel_mode = alc262_modes,
12518 .input_mux = &alc262_capture_source,
12519 .unsol_event = alc262_hippo_unsol_event,
12520 .setup = alc262_hippo_setup,
12521 .init_hook = alc262_hippo_automute,
12523 [ALC262_TYAN] = {
12524 .mixers = { alc262_tyan_mixer },
12525 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12527 .dac_nids = alc262_dac_nids,
12528 .hp_nid = 0x02,
12529 .dig_out_nid = ALC262_DIGOUT_NID,
12530 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12531 .channel_mode = alc262_modes,
12532 .input_mux = &alc262_capture_source,
12533 .unsol_event = alc_automute_amp_unsol_event,
12534 .setup = alc262_tyan_setup,
12535 .init_hook = alc_automute_amp,
12539 static int patch_alc262(struct hda_codec *codec)
12541 struct alc_spec *spec;
12542 int board_config;
12543 int err;
12545 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12546 if (spec == NULL)
12547 return -ENOMEM;
12549 codec->spec = spec;
12550 #if 0
12551 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12552 * under-run
12555 int tmp;
12556 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12557 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12558 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12559 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12561 #endif
12562 alc_auto_parse_customize_define(codec);
12564 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12566 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12567 alc262_models,
12568 alc262_cfg_tbl);
12570 if (board_config < 0) {
12571 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12572 codec->chip_name);
12573 board_config = ALC262_AUTO;
12576 if (board_config == ALC262_AUTO) {
12577 /* automatic parse from the BIOS config */
12578 err = alc262_parse_auto_config(codec);
12579 if (err < 0) {
12580 alc_free(codec);
12581 return err;
12582 } else if (!err) {
12583 printk(KERN_INFO
12584 "hda_codec: Cannot set up configuration "
12585 "from BIOS. Using base mode...\n");
12586 board_config = ALC262_BASIC;
12590 if (!spec->no_analog && has_cdefine_beep(codec)) {
12591 err = snd_hda_attach_beep_device(codec, 0x1);
12592 if (err < 0) {
12593 alc_free(codec);
12594 return err;
12598 if (board_config != ALC262_AUTO)
12599 setup_preset(codec, &alc262_presets[board_config]);
12601 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12602 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12604 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12605 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12607 if (!spec->adc_nids && spec->input_mux) {
12608 int i;
12609 /* check whether the digital-mic has to be supported */
12610 for (i = 0; i < spec->input_mux->num_items; i++) {
12611 if (spec->input_mux->items[i].index >= 9)
12612 break;
12614 if (i < spec->input_mux->num_items) {
12615 /* use only ADC0 */
12616 spec->adc_nids = alc262_dmic_adc_nids;
12617 spec->num_adc_nids = 1;
12618 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12619 } else {
12620 /* all analog inputs */
12621 /* check whether NID 0x07 is valid */
12622 unsigned int wcap = get_wcaps(codec, 0x07);
12624 /* get type */
12625 wcap = get_wcaps_type(wcap);
12626 if (wcap != AC_WID_AUD_IN) {
12627 spec->adc_nids = alc262_adc_nids_alt;
12628 spec->num_adc_nids =
12629 ARRAY_SIZE(alc262_adc_nids_alt);
12630 spec->capsrc_nids = alc262_capsrc_nids_alt;
12631 } else {
12632 spec->adc_nids = alc262_adc_nids;
12633 spec->num_adc_nids =
12634 ARRAY_SIZE(alc262_adc_nids);
12635 spec->capsrc_nids = alc262_capsrc_nids;
12639 if (!spec->cap_mixer && !spec->no_analog)
12640 set_capture_mixer(codec);
12641 if (!spec->no_analog && has_cdefine_beep(codec))
12642 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12644 spec->vmaster_nid = 0x0c;
12646 codec->patch_ops = alc_patch_ops;
12647 if (board_config == ALC262_AUTO)
12648 spec->init_hook = alc262_auto_init;
12649 #ifdef CONFIG_SND_HDA_POWER_SAVE
12650 if (!spec->loopback.amplist)
12651 spec->loopback.amplist = alc262_loopbacks;
12652 #endif
12654 return 0;
12658 * ALC268 channel source setting (2 channel)
12660 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12661 #define alc268_modes alc260_modes
12663 static hda_nid_t alc268_dac_nids[2] = {
12664 /* front, hp */
12665 0x02, 0x03
12668 static hda_nid_t alc268_adc_nids[2] = {
12669 /* ADC0-1 */
12670 0x08, 0x07
12673 static hda_nid_t alc268_adc_nids_alt[1] = {
12674 /* ADC0 */
12675 0x08
12678 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12680 static struct snd_kcontrol_new alc268_base_mixer[] = {
12681 /* output mixer control */
12682 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12683 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12684 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12687 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12688 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12692 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12693 /* output mixer control */
12694 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12695 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12696 ALC262_HIPPO_MASTER_SWITCH,
12697 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12698 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12699 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12703 /* bind Beep switches of both NID 0x0f and 0x10 */
12704 static struct hda_bind_ctls alc268_bind_beep_sw = {
12705 .ops = &snd_hda_bind_sw,
12706 .values = {
12707 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12708 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12713 static struct snd_kcontrol_new alc268_beep_mixer[] = {
12714 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12715 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12719 static struct hda_verb alc268_eapd_verbs[] = {
12720 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12721 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12725 /* Toshiba specific */
12726 static struct hda_verb alc268_toshiba_verbs[] = {
12727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12728 { } /* end */
12731 /* Acer specific */
12732 /* bind volumes of both NID 0x02 and 0x03 */
12733 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12734 .ops = &snd_hda_bind_vol,
12735 .values = {
12736 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12737 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12742 /* mute/unmute internal speaker according to the hp jack and mute state */
12743 static void alc268_acer_automute(struct hda_codec *codec, int force)
12745 struct alc_spec *spec = codec->spec;
12746 unsigned int mute;
12748 if (force || !spec->sense_updated) {
12749 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
12750 spec->sense_updated = 1;
12752 if (spec->jack_present)
12753 mute = HDA_AMP_MUTE; /* mute internal speaker */
12754 else /* unmute internal speaker if necessary */
12755 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12756 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12757 HDA_AMP_MUTE, mute);
12761 /* bind hp and internal speaker mute (with plug check) */
12762 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12763 struct snd_ctl_elem_value *ucontrol)
12765 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12766 long *valp = ucontrol->value.integer.value;
12767 int change;
12769 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
12770 if (change)
12771 alc268_acer_automute(codec, 0);
12772 return change;
12775 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12776 /* output mixer control */
12777 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12779 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12780 .name = "Master Playback Switch",
12781 .subdevice = HDA_SUBDEV_AMP_FLAG,
12782 .info = snd_hda_mixer_amp_switch_info,
12783 .get = snd_hda_mixer_amp_switch_get,
12784 .put = alc268_acer_master_sw_put,
12785 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12787 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12791 static struct snd_kcontrol_new alc268_acer_mixer[] = {
12792 /* output mixer control */
12793 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12796 .name = "Master Playback Switch",
12797 .subdevice = HDA_SUBDEV_AMP_FLAG,
12798 .info = snd_hda_mixer_amp_switch_info,
12799 .get = snd_hda_mixer_amp_switch_get,
12800 .put = alc268_acer_master_sw_put,
12801 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12803 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12804 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12805 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12809 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12810 /* output mixer control */
12811 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12813 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12814 .name = "Master Playback Switch",
12815 .subdevice = HDA_SUBDEV_AMP_FLAG,
12816 .info = snd_hda_mixer_amp_switch_info,
12817 .get = snd_hda_mixer_amp_switch_get,
12818 .put = alc268_acer_master_sw_put,
12819 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12822 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12826 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12827 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12829 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12830 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12831 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12832 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12836 static struct hda_verb alc268_acer_verbs[] = {
12837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12838 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12839 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12841 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12842 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12843 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12847 /* unsolicited event for HP jack sensing */
12848 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12849 #define alc268_toshiba_setup alc262_hippo_setup
12850 #define alc268_toshiba_automute alc262_hippo_automute
12852 static void alc268_acer_unsol_event(struct hda_codec *codec,
12853 unsigned int res)
12855 if ((res >> 26) != ALC880_HP_EVENT)
12856 return;
12857 alc268_acer_automute(codec, 1);
12860 static void alc268_acer_init_hook(struct hda_codec *codec)
12862 alc268_acer_automute(codec, 1);
12865 /* toggle speaker-output according to the hp-jack state */
12866 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12868 unsigned int present;
12869 unsigned char bits;
12871 present = snd_hda_jack_detect(codec, 0x15);
12872 bits = present ? HDA_AMP_MUTE : 0;
12873 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12874 HDA_AMP_MUTE, bits);
12875 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12876 HDA_AMP_MUTE, bits);
12879 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12880 unsigned int res)
12882 switch (res >> 26) {
12883 case ALC880_HP_EVENT:
12884 alc268_aspire_one_speaker_automute(codec);
12885 break;
12886 case ALC880_MIC_EVENT:
12887 alc_mic_automute(codec);
12888 break;
12892 static void alc268_acer_lc_setup(struct hda_codec *codec)
12894 struct alc_spec *spec = codec->spec;
12895 spec->ext_mic.pin = 0x18;
12896 spec->ext_mic.mux_idx = 0;
12897 spec->int_mic.pin = 0x12;
12898 spec->int_mic.mux_idx = 6;
12899 spec->auto_mic = 1;
12902 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12904 alc268_aspire_one_speaker_automute(codec);
12905 alc_mic_automute(codec);
12908 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12909 /* output mixer control */
12910 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12914 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12919 static struct hda_verb alc268_dell_verbs[] = {
12920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12927 /* mute/unmute internal speaker according to the hp jack and mute state */
12928 static void alc268_dell_setup(struct hda_codec *codec)
12930 struct alc_spec *spec = codec->spec;
12932 spec->autocfg.hp_pins[0] = 0x15;
12933 spec->autocfg.speaker_pins[0] = 0x14;
12934 spec->ext_mic.pin = 0x18;
12935 spec->ext_mic.mux_idx = 0;
12936 spec->int_mic.pin = 0x19;
12937 spec->int_mic.mux_idx = 1;
12938 spec->auto_mic = 1;
12941 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12942 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12943 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12946 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12947 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12948 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12949 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12953 static struct hda_verb alc267_quanta_il1_verbs[] = {
12954 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12959 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12961 struct alc_spec *spec = codec->spec;
12962 spec->autocfg.hp_pins[0] = 0x15;
12963 spec->autocfg.speaker_pins[0] = 0x14;
12964 spec->ext_mic.pin = 0x18;
12965 spec->ext_mic.mux_idx = 0;
12966 spec->int_mic.pin = 0x19;
12967 spec->int_mic.mux_idx = 1;
12968 spec->auto_mic = 1;
12972 * generic initialization of ADC, input mixers and output mixers
12974 static struct hda_verb alc268_base_init_verbs[] = {
12975 /* Unmute DAC0-1 and set vol = 0 */
12976 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12977 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12980 * Set up output mixers (0x0c - 0x0e)
12982 /* set vol=0 to output mixers */
12983 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12984 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12986 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12987 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12991 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12992 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12993 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12994 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12995 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12996 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12998 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13000 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13002 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13004 /* set PCBEEP vol = 0, mute connections */
13005 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13006 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13007 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13009 /* Unmute Selector 23h,24h and set the default input to mic-in */
13011 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13012 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13013 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13014 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13020 * generic initialization of ADC, input mixers and output mixers
13022 static struct hda_verb alc268_volume_init_verbs[] = {
13023 /* set output DAC */
13024 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13025 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13027 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13028 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13030 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13031 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13034 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13035 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13040 /* set PCBEEP vol = 0, mute connections */
13041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13048 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13049 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13050 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13051 { } /* end */
13054 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13055 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13056 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13057 _DEFINE_CAPSRC(1),
13058 { } /* end */
13061 static struct snd_kcontrol_new alc268_capture_mixer[] = {
13062 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13063 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13064 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13066 _DEFINE_CAPSRC(2),
13067 { } /* end */
13070 static struct hda_input_mux alc268_capture_source = {
13071 .num_items = 4,
13072 .items = {
13073 { "Mic", 0x0 },
13074 { "Front Mic", 0x1 },
13075 { "Line", 0x2 },
13076 { "CD", 0x3 },
13080 static struct hda_input_mux alc268_acer_capture_source = {
13081 .num_items = 3,
13082 .items = {
13083 { "Mic", 0x0 },
13084 { "Internal Mic", 0x1 },
13085 { "Line", 0x2 },
13089 static struct hda_input_mux alc268_acer_dmic_capture_source = {
13090 .num_items = 3,
13091 .items = {
13092 { "Mic", 0x0 },
13093 { "Internal Mic", 0x6 },
13094 { "Line", 0x2 },
13098 #ifdef CONFIG_SND_DEBUG
13099 static struct snd_kcontrol_new alc268_test_mixer[] = {
13100 /* Volume widgets */
13101 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13102 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13103 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13104 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13105 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13106 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13107 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13108 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13109 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13110 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13111 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13112 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13113 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13114 /* The below appears problematic on some hardwares */
13115 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13116 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13117 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13118 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13119 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13121 /* Modes for retasking pin widgets */
13122 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13123 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13124 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13125 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13127 /* Controls for GPIO pins, assuming they are configured as outputs */
13128 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13129 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13130 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13131 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13133 /* Switches to allow the digital SPDIF output pin to be enabled.
13134 * The ALC268 does not have an SPDIF input.
13136 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13138 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13139 * this output to turn on an external amplifier.
13141 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13142 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13144 { } /* end */
13146 #endif
13148 /* create input playback/capture controls for the given pin */
13149 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13150 const char *ctlname, int idx)
13152 hda_nid_t dac;
13153 int err;
13155 switch (nid) {
13156 case 0x14:
13157 case 0x16:
13158 dac = 0x02;
13159 break;
13160 case 0x15:
13161 case 0x1b:
13162 case 0x21: /* ALC269vb has this pin, too */
13163 dac = 0x03;
13164 break;
13165 default:
13166 return 0;
13168 if (spec->multiout.dac_nids[0] != dac &&
13169 spec->multiout.dac_nids[1] != dac) {
13170 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13171 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13172 HDA_OUTPUT));
13173 if (err < 0)
13174 return err;
13175 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13178 if (nid != 0x16)
13179 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13180 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13181 else /* mono */
13182 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13183 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13184 if (err < 0)
13185 return err;
13186 return 0;
13189 /* add playback controls from the parsed DAC table */
13190 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13191 const struct auto_pin_cfg *cfg)
13193 hda_nid_t nid;
13194 int err;
13196 spec->multiout.dac_nids = spec->private_dac_nids;
13198 nid = cfg->line_out_pins[0];
13199 if (nid) {
13200 const char *name;
13201 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13202 name = "Speaker";
13203 else
13204 name = "Front";
13205 err = alc268_new_analog_output(spec, nid, name, 0);
13206 if (err < 0)
13207 return err;
13210 nid = cfg->speaker_pins[0];
13211 if (nid == 0x1d) {
13212 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13213 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13214 if (err < 0)
13215 return err;
13216 } else {
13217 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13218 if (err < 0)
13219 return err;
13221 nid = cfg->hp_pins[0];
13222 if (nid) {
13223 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13224 if (err < 0)
13225 return err;
13228 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13229 if (nid == 0x16) {
13230 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13231 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13232 if (err < 0)
13233 return err;
13235 return 0;
13238 /* create playback/capture controls for input pins */
13239 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13240 const struct auto_pin_cfg *cfg)
13242 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13245 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13246 hda_nid_t nid, int pin_type)
13248 int idx;
13250 alc_set_pin_output(codec, nid, pin_type);
13251 if (nid == 0x14 || nid == 0x16)
13252 idx = 0;
13253 else
13254 idx = 1;
13255 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13258 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13260 struct alc_spec *spec = codec->spec;
13261 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13262 if (nid) {
13263 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13264 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13268 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13270 struct alc_spec *spec = codec->spec;
13271 hda_nid_t pin;
13273 pin = spec->autocfg.hp_pins[0];
13274 if (pin)
13275 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13276 pin = spec->autocfg.speaker_pins[0];
13277 if (pin)
13278 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13281 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13283 struct alc_spec *spec = codec->spec;
13284 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13285 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13286 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13287 unsigned int dac_vol1, dac_vol2;
13289 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13290 snd_hda_codec_write(codec, speaker_nid, 0,
13291 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13292 /* mute mixer inputs from 0x1d */
13293 snd_hda_codec_write(codec, 0x0f, 0,
13294 AC_VERB_SET_AMP_GAIN_MUTE,
13295 AMP_IN_UNMUTE(1));
13296 snd_hda_codec_write(codec, 0x10, 0,
13297 AC_VERB_SET_AMP_GAIN_MUTE,
13298 AMP_IN_UNMUTE(1));
13299 } else {
13300 /* unmute mixer inputs from 0x1d */
13301 snd_hda_codec_write(codec, 0x0f, 0,
13302 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13303 snd_hda_codec_write(codec, 0x10, 0,
13304 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13307 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13308 if (line_nid == 0x14)
13309 dac_vol2 = AMP_OUT_ZERO;
13310 else if (line_nid == 0x15)
13311 dac_vol1 = AMP_OUT_ZERO;
13312 if (hp_nid == 0x14)
13313 dac_vol2 = AMP_OUT_ZERO;
13314 else if (hp_nid == 0x15)
13315 dac_vol1 = AMP_OUT_ZERO;
13316 if (line_nid != 0x16 || hp_nid != 0x16 ||
13317 spec->autocfg.line_out_pins[1] != 0x16 ||
13318 spec->autocfg.line_out_pins[2] != 0x16)
13319 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13321 snd_hda_codec_write(codec, 0x02, 0,
13322 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13323 snd_hda_codec_write(codec, 0x03, 0,
13324 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13327 /* pcm configuration: identical with ALC880 */
13328 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13329 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13330 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13331 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13334 * BIOS auto configuration
13336 static int alc268_parse_auto_config(struct hda_codec *codec)
13338 struct alc_spec *spec = codec->spec;
13339 int err;
13340 static hda_nid_t alc268_ignore[] = { 0 };
13342 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13343 alc268_ignore);
13344 if (err < 0)
13345 return err;
13346 if (!spec->autocfg.line_outs) {
13347 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13348 spec->multiout.max_channels = 2;
13349 spec->no_analog = 1;
13350 goto dig_only;
13352 return 0; /* can't find valid BIOS pin config */
13354 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13355 if (err < 0)
13356 return err;
13357 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13358 if (err < 0)
13359 return err;
13361 spec->multiout.max_channels = 2;
13363 dig_only:
13364 /* digital only support output */
13365 alc_auto_parse_digital(codec);
13366 if (spec->kctls.list)
13367 add_mixer(spec, spec->kctls.list);
13369 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13370 add_mixer(spec, alc268_beep_mixer);
13372 add_verb(spec, alc268_volume_init_verbs);
13373 spec->num_mux_defs = 2;
13374 spec->input_mux = &spec->private_imux[0];
13376 err = alc_auto_add_mic_boost(codec);
13377 if (err < 0)
13378 return err;
13380 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13382 return 1;
13385 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13387 /* init callback for auto-configuration model -- overriding the default init */
13388 static void alc268_auto_init(struct hda_codec *codec)
13390 struct alc_spec *spec = codec->spec;
13391 alc268_auto_init_multi_out(codec);
13392 alc268_auto_init_hp_out(codec);
13393 alc268_auto_init_mono_speaker_out(codec);
13394 alc268_auto_init_analog_input(codec);
13395 alc_auto_init_digital(codec);
13396 if (spec->unsol_event)
13397 alc_inithook(codec);
13401 * configuration and preset
13403 static const char *alc268_models[ALC268_MODEL_LAST] = {
13404 [ALC267_QUANTA_IL1] = "quanta-il1",
13405 [ALC268_3ST] = "3stack",
13406 [ALC268_TOSHIBA] = "toshiba",
13407 [ALC268_ACER] = "acer",
13408 [ALC268_ACER_DMIC] = "acer-dmic",
13409 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13410 [ALC268_DELL] = "dell",
13411 [ALC268_ZEPTO] = "zepto",
13412 #ifdef CONFIG_SND_DEBUG
13413 [ALC268_TEST] = "test",
13414 #endif
13415 [ALC268_AUTO] = "auto",
13418 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13419 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13420 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13421 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13422 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13423 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13424 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13425 ALC268_ACER_ASPIRE_ONE),
13426 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13427 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13428 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13429 /* almost compatible with toshiba but with optional digital outs;
13430 * auto-probing seems working fine
13432 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13433 ALC268_AUTO),
13434 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13435 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13436 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13437 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13438 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13439 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
13443 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13444 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13445 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13446 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13447 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13448 ALC268_TOSHIBA),
13452 static struct alc_config_preset alc268_presets[] = {
13453 [ALC267_QUANTA_IL1] = {
13454 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13455 alc268_capture_nosrc_mixer },
13456 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13457 alc267_quanta_il1_verbs },
13458 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13459 .dac_nids = alc268_dac_nids,
13460 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13461 .adc_nids = alc268_adc_nids_alt,
13462 .hp_nid = 0x03,
13463 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13464 .channel_mode = alc268_modes,
13465 .unsol_event = alc_sku_unsol_event,
13466 .setup = alc267_quanta_il1_setup,
13467 .init_hook = alc_inithook,
13469 [ALC268_3ST] = {
13470 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13471 alc268_beep_mixer },
13472 .init_verbs = { alc268_base_init_verbs },
13473 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13474 .dac_nids = alc268_dac_nids,
13475 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13476 .adc_nids = alc268_adc_nids_alt,
13477 .capsrc_nids = alc268_capsrc_nids,
13478 .hp_nid = 0x03,
13479 .dig_out_nid = ALC268_DIGOUT_NID,
13480 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13481 .channel_mode = alc268_modes,
13482 .input_mux = &alc268_capture_source,
13484 [ALC268_TOSHIBA] = {
13485 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13486 alc268_beep_mixer },
13487 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13488 alc268_toshiba_verbs },
13489 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13490 .dac_nids = alc268_dac_nids,
13491 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13492 .adc_nids = alc268_adc_nids_alt,
13493 .capsrc_nids = alc268_capsrc_nids,
13494 .hp_nid = 0x03,
13495 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13496 .channel_mode = alc268_modes,
13497 .input_mux = &alc268_capture_source,
13498 .unsol_event = alc268_toshiba_unsol_event,
13499 .setup = alc268_toshiba_setup,
13500 .init_hook = alc268_toshiba_automute,
13502 [ALC268_ACER] = {
13503 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13504 alc268_beep_mixer },
13505 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13506 alc268_acer_verbs },
13507 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13508 .dac_nids = alc268_dac_nids,
13509 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13510 .adc_nids = alc268_adc_nids_alt,
13511 .capsrc_nids = alc268_capsrc_nids,
13512 .hp_nid = 0x02,
13513 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13514 .channel_mode = alc268_modes,
13515 .input_mux = &alc268_acer_capture_source,
13516 .unsol_event = alc268_acer_unsol_event,
13517 .init_hook = alc268_acer_init_hook,
13519 [ALC268_ACER_DMIC] = {
13520 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13521 alc268_beep_mixer },
13522 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13523 alc268_acer_verbs },
13524 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13525 .dac_nids = alc268_dac_nids,
13526 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13527 .adc_nids = alc268_adc_nids_alt,
13528 .capsrc_nids = alc268_capsrc_nids,
13529 .hp_nid = 0x02,
13530 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13531 .channel_mode = alc268_modes,
13532 .input_mux = &alc268_acer_dmic_capture_source,
13533 .unsol_event = alc268_acer_unsol_event,
13534 .init_hook = alc268_acer_init_hook,
13536 [ALC268_ACER_ASPIRE_ONE] = {
13537 .mixers = { alc268_acer_aspire_one_mixer,
13538 alc268_beep_mixer,
13539 alc268_capture_nosrc_mixer },
13540 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13541 alc268_acer_aspire_one_verbs },
13542 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13543 .dac_nids = alc268_dac_nids,
13544 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13545 .adc_nids = alc268_adc_nids_alt,
13546 .capsrc_nids = alc268_capsrc_nids,
13547 .hp_nid = 0x03,
13548 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13549 .channel_mode = alc268_modes,
13550 .unsol_event = alc268_acer_lc_unsol_event,
13551 .setup = alc268_acer_lc_setup,
13552 .init_hook = alc268_acer_lc_init_hook,
13554 [ALC268_DELL] = {
13555 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13556 alc268_capture_nosrc_mixer },
13557 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13558 alc268_dell_verbs },
13559 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13560 .dac_nids = alc268_dac_nids,
13561 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13562 .adc_nids = alc268_adc_nids_alt,
13563 .capsrc_nids = alc268_capsrc_nids,
13564 .hp_nid = 0x02,
13565 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13566 .channel_mode = alc268_modes,
13567 .unsol_event = alc_sku_unsol_event,
13568 .setup = alc268_dell_setup,
13569 .init_hook = alc_inithook,
13571 [ALC268_ZEPTO] = {
13572 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13573 alc268_beep_mixer },
13574 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13575 alc268_toshiba_verbs },
13576 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13577 .dac_nids = alc268_dac_nids,
13578 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13579 .adc_nids = alc268_adc_nids_alt,
13580 .capsrc_nids = alc268_capsrc_nids,
13581 .hp_nid = 0x03,
13582 .dig_out_nid = ALC268_DIGOUT_NID,
13583 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13584 .channel_mode = alc268_modes,
13585 .input_mux = &alc268_capture_source,
13586 .setup = alc268_toshiba_setup,
13587 .init_hook = alc268_toshiba_automute,
13589 #ifdef CONFIG_SND_DEBUG
13590 [ALC268_TEST] = {
13591 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13592 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13593 alc268_volume_init_verbs },
13594 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13595 .dac_nids = alc268_dac_nids,
13596 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13597 .adc_nids = alc268_adc_nids_alt,
13598 .capsrc_nids = alc268_capsrc_nids,
13599 .hp_nid = 0x03,
13600 .dig_out_nid = ALC268_DIGOUT_NID,
13601 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13602 .channel_mode = alc268_modes,
13603 .input_mux = &alc268_capture_source,
13605 #endif
13608 static int patch_alc268(struct hda_codec *codec)
13610 struct alc_spec *spec;
13611 int board_config;
13612 int i, has_beep, err;
13614 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13615 if (spec == NULL)
13616 return -ENOMEM;
13618 codec->spec = spec;
13620 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13621 alc268_models,
13622 alc268_cfg_tbl);
13624 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13625 board_config = snd_hda_check_board_codec_sid_config(codec,
13626 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13628 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13629 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13630 codec->chip_name);
13631 board_config = ALC268_AUTO;
13634 if (board_config == ALC268_AUTO) {
13635 /* automatic parse from the BIOS config */
13636 err = alc268_parse_auto_config(codec);
13637 if (err < 0) {
13638 alc_free(codec);
13639 return err;
13640 } else if (!err) {
13641 printk(KERN_INFO
13642 "hda_codec: Cannot set up configuration "
13643 "from BIOS. Using base mode...\n");
13644 board_config = ALC268_3ST;
13648 if (board_config != ALC268_AUTO)
13649 setup_preset(codec, &alc268_presets[board_config]);
13651 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13652 spec->stream_analog_capture = &alc268_pcm_analog_capture;
13653 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
13655 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13657 has_beep = 0;
13658 for (i = 0; i < spec->num_mixers; i++) {
13659 if (spec->mixers[i] == alc268_beep_mixer) {
13660 has_beep = 1;
13661 break;
13665 if (has_beep) {
13666 err = snd_hda_attach_beep_device(codec, 0x1);
13667 if (err < 0) {
13668 alc_free(codec);
13669 return err;
13671 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13672 /* override the amp caps for beep generator */
13673 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13674 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13675 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13676 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13677 (0 << AC_AMPCAP_MUTE_SHIFT));
13680 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13681 /* check whether NID 0x07 is valid */
13682 unsigned int wcap = get_wcaps(codec, 0x07);
13683 int i;
13685 spec->capsrc_nids = alc268_capsrc_nids;
13686 /* get type */
13687 wcap = get_wcaps_type(wcap);
13688 if (spec->auto_mic ||
13689 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
13690 spec->adc_nids = alc268_adc_nids_alt;
13691 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
13692 if (spec->auto_mic)
13693 fixup_automic_adc(codec);
13694 if (spec->auto_mic || spec->input_mux->num_items == 1)
13695 add_mixer(spec, alc268_capture_nosrc_mixer);
13696 else
13697 add_mixer(spec, alc268_capture_alt_mixer);
13698 } else {
13699 spec->adc_nids = alc268_adc_nids;
13700 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13701 add_mixer(spec, alc268_capture_mixer);
13703 /* set default input source */
13704 for (i = 0; i < spec->num_adc_nids; i++)
13705 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13706 0, AC_VERB_SET_CONNECT_SEL,
13707 i < spec->num_mux_defs ?
13708 spec->input_mux[i].items[0].index :
13709 spec->input_mux->items[0].index);
13712 spec->vmaster_nid = 0x02;
13714 codec->patch_ops = alc_patch_ops;
13715 if (board_config == ALC268_AUTO)
13716 spec->init_hook = alc268_auto_init;
13718 return 0;
13722 * ALC269 channel source setting (2 channel)
13724 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13726 #define alc269_dac_nids alc260_dac_nids
13728 static hda_nid_t alc269_adc_nids[1] = {
13729 /* ADC1 */
13730 0x08,
13733 static hda_nid_t alc269_capsrc_nids[1] = {
13734 0x23,
13737 static hda_nid_t alc269vb_adc_nids[1] = {
13738 /* ADC1 */
13739 0x09,
13742 static hda_nid_t alc269vb_capsrc_nids[1] = {
13743 0x22,
13746 static hda_nid_t alc269_adc_candidates[] = {
13747 0x08, 0x09, 0x07,
13750 #define alc269_modes alc260_modes
13751 #define alc269_capture_source alc880_lg_lw_capture_source
13753 static struct snd_kcontrol_new alc269_base_mixer[] = {
13754 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13755 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13756 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13757 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13760 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13761 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13762 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13763 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13765 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13766 { } /* end */
13769 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13770 /* output mixer control */
13771 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13773 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13774 .name = "Master Playback Switch",
13775 .subdevice = HDA_SUBDEV_AMP_FLAG,
13776 .info = snd_hda_mixer_amp_switch_info,
13777 .get = snd_hda_mixer_amp_switch_get,
13778 .put = alc268_acer_master_sw_put,
13779 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13782 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13783 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13784 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13785 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13786 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13790 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13791 /* output mixer control */
13792 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13795 .name = "Master Playback Switch",
13796 .subdevice = HDA_SUBDEV_AMP_FLAG,
13797 .info = snd_hda_mixer_amp_switch_info,
13798 .get = snd_hda_mixer_amp_switch_get,
13799 .put = alc268_acer_master_sw_put,
13800 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13802 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13803 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13804 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13806 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13807 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13808 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13809 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13810 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
13814 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13815 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13818 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13819 { } /* end */
13822 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13823 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13824 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13826 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13827 { } /* end */
13830 /* capture mixer elements */
13831 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13832 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13833 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13834 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13835 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13836 { } /* end */
13839 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13840 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13841 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13842 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13843 { } /* end */
13846 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13847 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13848 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13849 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13850 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13851 { } /* end */
13854 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13855 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13856 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13857 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13858 { } /* end */
13861 /* FSC amilo */
13862 #define alc269_fujitsu_mixer alc269_laptop_mixer
13864 static struct hda_verb alc269_quanta_fl1_verbs[] = {
13865 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13866 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13869 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13870 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13874 static struct hda_verb alc269_lifebook_verbs[] = {
13875 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13876 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13877 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13878 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13879 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13881 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13882 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13883 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13884 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13888 /* toggle speaker-output according to the hp-jack state */
13889 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13891 unsigned int present;
13892 unsigned char bits;
13894 present = snd_hda_jack_detect(codec, 0x15);
13895 bits = present ? HDA_AMP_MUTE : 0;
13896 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13897 HDA_AMP_MUTE, bits);
13898 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13899 HDA_AMP_MUTE, bits);
13901 snd_hda_codec_write(codec, 0x20, 0,
13902 AC_VERB_SET_COEF_INDEX, 0x0c);
13903 snd_hda_codec_write(codec, 0x20, 0,
13904 AC_VERB_SET_PROC_COEF, 0x680);
13906 snd_hda_codec_write(codec, 0x20, 0,
13907 AC_VERB_SET_COEF_INDEX, 0x0c);
13908 snd_hda_codec_write(codec, 0x20, 0,
13909 AC_VERB_SET_PROC_COEF, 0x480);
13912 /* toggle speaker-output according to the hp-jacks state */
13913 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13915 unsigned int present;
13916 unsigned char bits;
13918 /* Check laptop headphone socket */
13919 present = snd_hda_jack_detect(codec, 0x15);
13921 /* Check port replicator headphone socket */
13922 present |= snd_hda_jack_detect(codec, 0x1a);
13924 bits = present ? HDA_AMP_MUTE : 0;
13925 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13926 HDA_AMP_MUTE, bits);
13927 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13928 HDA_AMP_MUTE, bits);
13930 snd_hda_codec_write(codec, 0x20, 0,
13931 AC_VERB_SET_COEF_INDEX, 0x0c);
13932 snd_hda_codec_write(codec, 0x20, 0,
13933 AC_VERB_SET_PROC_COEF, 0x680);
13935 snd_hda_codec_write(codec, 0x20, 0,
13936 AC_VERB_SET_COEF_INDEX, 0x0c);
13937 snd_hda_codec_write(codec, 0x20, 0,
13938 AC_VERB_SET_PROC_COEF, 0x480);
13941 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13943 unsigned int present_laptop;
13944 unsigned int present_dock;
13946 present_laptop = snd_hda_jack_detect(codec, 0x18);
13947 present_dock = snd_hda_jack_detect(codec, 0x1b);
13949 /* Laptop mic port overrides dock mic port, design decision */
13950 if (present_dock)
13951 snd_hda_codec_write(codec, 0x23, 0,
13952 AC_VERB_SET_CONNECT_SEL, 0x3);
13953 if (present_laptop)
13954 snd_hda_codec_write(codec, 0x23, 0,
13955 AC_VERB_SET_CONNECT_SEL, 0x0);
13956 if (!present_dock && !present_laptop)
13957 snd_hda_codec_write(codec, 0x23, 0,
13958 AC_VERB_SET_CONNECT_SEL, 0x1);
13961 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13962 unsigned int res)
13964 switch (res >> 26) {
13965 case ALC880_HP_EVENT:
13966 alc269_quanta_fl1_speaker_automute(codec);
13967 break;
13968 case ALC880_MIC_EVENT:
13969 alc_mic_automute(codec);
13970 break;
13974 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13975 unsigned int res)
13977 if ((res >> 26) == ALC880_HP_EVENT)
13978 alc269_lifebook_speaker_automute(codec);
13979 if ((res >> 26) == ALC880_MIC_EVENT)
13980 alc269_lifebook_mic_autoswitch(codec);
13983 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13985 struct alc_spec *spec = codec->spec;
13986 spec->autocfg.hp_pins[0] = 0x15;
13987 spec->autocfg.speaker_pins[0] = 0x14;
13988 spec->ext_mic.pin = 0x18;
13989 spec->ext_mic.mux_idx = 0;
13990 spec->int_mic.pin = 0x19;
13991 spec->int_mic.mux_idx = 1;
13992 spec->auto_mic = 1;
13995 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13997 alc269_quanta_fl1_speaker_automute(codec);
13998 alc_mic_automute(codec);
14001 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14003 alc269_lifebook_speaker_automute(codec);
14004 alc269_lifebook_mic_autoswitch(codec);
14007 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14009 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14010 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14012 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14018 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14020 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14021 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14022 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14023 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14024 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14028 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14029 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14030 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14031 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14033 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14034 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14035 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14039 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14040 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14041 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14042 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14044 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14045 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14046 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14050 /* toggle speaker-output according to the hp-jack state */
14051 static void alc269_speaker_automute(struct hda_codec *codec)
14053 struct alc_spec *spec = codec->spec;
14054 unsigned int nid = spec->autocfg.hp_pins[0];
14055 unsigned int present;
14056 unsigned char bits;
14058 present = snd_hda_jack_detect(codec, nid);
14059 bits = present ? HDA_AMP_MUTE : 0;
14060 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14061 HDA_AMP_MUTE, bits);
14062 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14063 HDA_AMP_MUTE, bits);
14066 /* unsolicited event for HP jack sensing */
14067 static void alc269_laptop_unsol_event(struct hda_codec *codec,
14068 unsigned int res)
14070 switch (res >> 26) {
14071 case ALC880_HP_EVENT:
14072 alc269_speaker_automute(codec);
14073 break;
14074 case ALC880_MIC_EVENT:
14075 alc_mic_automute(codec);
14076 break;
14080 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14082 struct alc_spec *spec = codec->spec;
14083 spec->autocfg.hp_pins[0] = 0x15;
14084 spec->autocfg.speaker_pins[0] = 0x14;
14085 spec->ext_mic.pin = 0x18;
14086 spec->ext_mic.mux_idx = 0;
14087 spec->int_mic.pin = 0x19;
14088 spec->int_mic.mux_idx = 1;
14089 spec->auto_mic = 1;
14092 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14094 struct alc_spec *spec = codec->spec;
14095 spec->autocfg.hp_pins[0] = 0x15;
14096 spec->autocfg.speaker_pins[0] = 0x14;
14097 spec->ext_mic.pin = 0x18;
14098 spec->ext_mic.mux_idx = 0;
14099 spec->int_mic.pin = 0x12;
14100 spec->int_mic.mux_idx = 5;
14101 spec->auto_mic = 1;
14104 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14106 struct alc_spec *spec = codec->spec;
14107 spec->autocfg.hp_pins[0] = 0x21;
14108 spec->autocfg.speaker_pins[0] = 0x14;
14109 spec->ext_mic.pin = 0x18;
14110 spec->ext_mic.mux_idx = 0;
14111 spec->int_mic.pin = 0x19;
14112 spec->int_mic.mux_idx = 1;
14113 spec->auto_mic = 1;
14116 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14118 struct alc_spec *spec = codec->spec;
14119 spec->autocfg.hp_pins[0] = 0x21;
14120 spec->autocfg.speaker_pins[0] = 0x14;
14121 spec->ext_mic.pin = 0x18;
14122 spec->ext_mic.mux_idx = 0;
14123 spec->int_mic.pin = 0x12;
14124 spec->int_mic.mux_idx = 6;
14125 spec->auto_mic = 1;
14128 static void alc269_laptop_inithook(struct hda_codec *codec)
14130 alc269_speaker_automute(codec);
14131 alc_mic_automute(codec);
14135 * generic initialization of ADC, input mixers and output mixers
14137 static struct hda_verb alc269_init_verbs[] = {
14139 * Unmute ADC0 and set the default input to mic-in
14141 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14144 * Set up output mixers (0x02 - 0x03)
14146 /* set vol=0 to output mixers */
14147 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14148 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14150 /* set up input amps for analog loopback */
14151 /* Amp Indices: DAC = 0, mixer = 1 */
14152 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14153 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14154 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14155 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14156 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14157 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14161 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14162 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14164 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14165 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14167 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14168 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14170 /* FIXME: use Mux-type input source selection */
14171 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14172 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14173 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14175 /* set EAPD */
14176 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14180 static struct hda_verb alc269vb_init_verbs[] = {
14182 * Unmute ADC0 and set the default input to mic-in
14184 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14187 * Set up output mixers (0x02 - 0x03)
14189 /* set vol=0 to output mixers */
14190 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14191 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14193 /* set up input amps for analog loopback */
14194 /* Amp Indices: DAC = 0, mixer = 1 */
14195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14197 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14198 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14199 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14203 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14205 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14207 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14208 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14210 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14211 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14213 /* FIXME: use Mux-type input source selection */
14214 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14215 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14216 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14218 /* set EAPD */
14219 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14223 #define alc269_auto_create_multi_out_ctls \
14224 alc268_auto_create_multi_out_ctls
14225 #define alc269_auto_create_input_ctls \
14226 alc268_auto_create_input_ctls
14228 #ifdef CONFIG_SND_HDA_POWER_SAVE
14229 #define alc269_loopbacks alc880_loopbacks
14230 #endif
14232 /* pcm configuration: identical with ALC880 */
14233 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14234 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14235 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14236 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14238 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14239 .substreams = 1,
14240 .channels_min = 2,
14241 .channels_max = 8,
14242 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14243 /* NID is set in alc_build_pcms */
14244 .ops = {
14245 .open = alc880_playback_pcm_open,
14246 .prepare = alc880_playback_pcm_prepare,
14247 .cleanup = alc880_playback_pcm_cleanup
14251 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14252 .substreams = 1,
14253 .channels_min = 2,
14254 .channels_max = 2,
14255 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14256 /* NID is set in alc_build_pcms */
14259 #ifdef CONFIG_SND_HDA_POWER_SAVE
14260 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14262 switch (codec->subsystem_id) {
14263 case 0x103c1586:
14264 return 1;
14266 return 0;
14269 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14271 /* update mute-LED according to the speaker mute state */
14272 if (nid == 0x01 || nid == 0x14) {
14273 int pinval;
14274 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14275 HDA_AMP_MUTE)
14276 pinval = 0x24;
14277 else
14278 pinval = 0x20;
14279 /* mic2 vref pin is used for mute LED control */
14280 snd_hda_codec_update_cache(codec, 0x19, 0,
14281 AC_VERB_SET_PIN_WIDGET_CONTROL,
14282 pinval);
14284 return alc_check_power_status(codec, nid);
14286 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14288 static int alc275_setup_dual_adc(struct hda_codec *codec)
14290 struct alc_spec *spec = codec->spec;
14292 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14293 return 0;
14294 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14295 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14296 if (spec->ext_mic.pin <= 0x12) {
14297 spec->private_adc_nids[0] = 0x08;
14298 spec->private_adc_nids[1] = 0x11;
14299 spec->private_capsrc_nids[0] = 0x23;
14300 spec->private_capsrc_nids[1] = 0x22;
14301 } else {
14302 spec->private_adc_nids[0] = 0x11;
14303 spec->private_adc_nids[1] = 0x08;
14304 spec->private_capsrc_nids[0] = 0x22;
14305 spec->private_capsrc_nids[1] = 0x23;
14307 spec->adc_nids = spec->private_adc_nids;
14308 spec->capsrc_nids = spec->private_capsrc_nids;
14309 spec->num_adc_nids = 2;
14310 spec->dual_adc_switch = 1;
14311 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14312 spec->adc_nids[0], spec->adc_nids[1]);
14313 return 1;
14315 return 0;
14319 * BIOS auto configuration
14321 static int alc269_parse_auto_config(struct hda_codec *codec)
14323 struct alc_spec *spec = codec->spec;
14324 int err;
14325 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14327 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14328 alc269_ignore);
14329 if (err < 0)
14330 return err;
14332 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14333 if (err < 0)
14334 return err;
14335 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14336 if (err < 0)
14337 return err;
14339 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14341 alc_auto_parse_digital(codec);
14343 if (spec->kctls.list)
14344 add_mixer(spec, spec->kctls.list);
14346 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14347 add_verb(spec, alc269vb_init_verbs);
14348 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14349 } else {
14350 add_verb(spec, alc269_init_verbs);
14351 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14354 spec->num_mux_defs = 1;
14355 spec->input_mux = &spec->private_imux[0];
14357 if (!alc275_setup_dual_adc(codec))
14358 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14359 sizeof(alc269_adc_candidates));
14361 /* set default input source */
14362 if (!spec->dual_adc_switch)
14363 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
14364 0, AC_VERB_SET_CONNECT_SEL,
14365 spec->input_mux->items[0].index);
14367 err = alc_auto_add_mic_boost(codec);
14368 if (err < 0)
14369 return err;
14371 if (!spec->cap_mixer && !spec->no_analog)
14372 set_capture_mixer(codec);
14374 return 1;
14377 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14378 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14379 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14382 /* init callback for auto-configuration model -- overriding the default init */
14383 static void alc269_auto_init(struct hda_codec *codec)
14385 struct alc_spec *spec = codec->spec;
14386 alc269_auto_init_multi_out(codec);
14387 alc269_auto_init_hp_out(codec);
14388 alc269_auto_init_analog_input(codec);
14389 alc_auto_init_digital(codec);
14390 if (spec->unsol_event)
14391 alc_inithook(codec);
14394 enum {
14395 ALC269_FIXUP_SONY_VAIO,
14398 static const struct hda_verb alc269_sony_vaio_fixup_verbs[] = {
14399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14403 static const struct alc_fixup alc269_fixups[] = {
14404 [ALC269_FIXUP_SONY_VAIO] = {
14405 .verbs = alc269_sony_vaio_fixup_verbs
14409 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14410 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14416 * configuration and preset
14418 static const char *alc269_models[ALC269_MODEL_LAST] = {
14419 [ALC269_BASIC] = "basic",
14420 [ALC269_QUANTA_FL1] = "quanta",
14421 [ALC269_AMIC] = "laptop-amic",
14422 [ALC269_DMIC] = "laptop-dmic",
14423 [ALC269_FUJITSU] = "fujitsu",
14424 [ALC269_LIFEBOOK] = "lifebook",
14425 [ALC269_AUTO] = "auto",
14428 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14429 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14430 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14431 ALC269_AMIC),
14432 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14433 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14434 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14435 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14436 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14437 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14438 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14439 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14440 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14441 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14442 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14443 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14444 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14445 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14446 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14447 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14448 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14449 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14450 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14451 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14452 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14453 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14454 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14455 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14456 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14457 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14458 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14464 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14469 ALC269_DMIC),
14470 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14471 ALC269_DMIC),
14472 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14473 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14474 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14475 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14476 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14477 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14478 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14479 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14480 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14481 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14485 static struct alc_config_preset alc269_presets[] = {
14486 [ALC269_BASIC] = {
14487 .mixers = { alc269_base_mixer },
14488 .init_verbs = { alc269_init_verbs },
14489 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14490 .dac_nids = alc269_dac_nids,
14491 .hp_nid = 0x03,
14492 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14493 .channel_mode = alc269_modes,
14494 .input_mux = &alc269_capture_source,
14496 [ALC269_QUANTA_FL1] = {
14497 .mixers = { alc269_quanta_fl1_mixer },
14498 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14499 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14500 .dac_nids = alc269_dac_nids,
14501 .hp_nid = 0x03,
14502 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14503 .channel_mode = alc269_modes,
14504 .input_mux = &alc269_capture_source,
14505 .unsol_event = alc269_quanta_fl1_unsol_event,
14506 .setup = alc269_quanta_fl1_setup,
14507 .init_hook = alc269_quanta_fl1_init_hook,
14509 [ALC269_AMIC] = {
14510 .mixers = { alc269_laptop_mixer },
14511 .cap_mixer = alc269_laptop_analog_capture_mixer,
14512 .init_verbs = { alc269_init_verbs,
14513 alc269_laptop_amic_init_verbs },
14514 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14515 .dac_nids = alc269_dac_nids,
14516 .hp_nid = 0x03,
14517 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14518 .channel_mode = alc269_modes,
14519 .unsol_event = alc269_laptop_unsol_event,
14520 .setup = alc269_laptop_amic_setup,
14521 .init_hook = alc269_laptop_inithook,
14523 [ALC269_DMIC] = {
14524 .mixers = { alc269_laptop_mixer },
14525 .cap_mixer = alc269_laptop_digital_capture_mixer,
14526 .init_verbs = { alc269_init_verbs,
14527 alc269_laptop_dmic_init_verbs },
14528 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14529 .dac_nids = alc269_dac_nids,
14530 .hp_nid = 0x03,
14531 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14532 .channel_mode = alc269_modes,
14533 .unsol_event = alc269_laptop_unsol_event,
14534 .setup = alc269_laptop_dmic_setup,
14535 .init_hook = alc269_laptop_inithook,
14537 [ALC269VB_AMIC] = {
14538 .mixers = { alc269vb_laptop_mixer },
14539 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14540 .init_verbs = { alc269vb_init_verbs,
14541 alc269vb_laptop_amic_init_verbs },
14542 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14543 .dac_nids = alc269_dac_nids,
14544 .hp_nid = 0x03,
14545 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14546 .channel_mode = alc269_modes,
14547 .unsol_event = alc269_laptop_unsol_event,
14548 .setup = alc269vb_laptop_amic_setup,
14549 .init_hook = alc269_laptop_inithook,
14551 [ALC269VB_DMIC] = {
14552 .mixers = { alc269vb_laptop_mixer },
14553 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14554 .init_verbs = { alc269vb_init_verbs,
14555 alc269vb_laptop_dmic_init_verbs },
14556 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14557 .dac_nids = alc269_dac_nids,
14558 .hp_nid = 0x03,
14559 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14560 .channel_mode = alc269_modes,
14561 .unsol_event = alc269_laptop_unsol_event,
14562 .setup = alc269vb_laptop_dmic_setup,
14563 .init_hook = alc269_laptop_inithook,
14565 [ALC269_FUJITSU] = {
14566 .mixers = { alc269_fujitsu_mixer },
14567 .cap_mixer = alc269_laptop_digital_capture_mixer,
14568 .init_verbs = { alc269_init_verbs,
14569 alc269_laptop_dmic_init_verbs },
14570 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14571 .dac_nids = alc269_dac_nids,
14572 .hp_nid = 0x03,
14573 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14574 .channel_mode = alc269_modes,
14575 .unsol_event = alc269_laptop_unsol_event,
14576 .setup = alc269_laptop_dmic_setup,
14577 .init_hook = alc269_laptop_inithook,
14579 [ALC269_LIFEBOOK] = {
14580 .mixers = { alc269_lifebook_mixer },
14581 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14582 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14583 .dac_nids = alc269_dac_nids,
14584 .hp_nid = 0x03,
14585 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14586 .channel_mode = alc269_modes,
14587 .input_mux = &alc269_capture_source,
14588 .unsol_event = alc269_lifebook_unsol_event,
14589 .init_hook = alc269_lifebook_init_hook,
14593 static int patch_alc269(struct hda_codec *codec)
14595 struct alc_spec *spec;
14596 int board_config;
14597 int err;
14598 int is_alc269vb = 0;
14600 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14601 if (spec == NULL)
14602 return -ENOMEM;
14604 codec->spec = spec;
14606 alc_auto_parse_customize_define(codec);
14608 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14609 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14610 spec->cdefine.platform_type == 1)
14611 alc_codec_rename(codec, "ALC271X");
14612 else
14613 alc_codec_rename(codec, "ALC259");
14614 is_alc269vb = 1;
14615 } else
14616 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14618 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14619 alc269_models,
14620 alc269_cfg_tbl);
14622 if (board_config < 0) {
14623 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14624 codec->chip_name);
14625 board_config = ALC269_AUTO;
14628 if (board_config == ALC269_AUTO)
14629 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1);
14631 if (board_config == ALC269_AUTO) {
14632 /* automatic parse from the BIOS config */
14633 err = alc269_parse_auto_config(codec);
14634 if (err < 0) {
14635 alc_free(codec);
14636 return err;
14637 } else if (!err) {
14638 printk(KERN_INFO
14639 "hda_codec: Cannot set up configuration "
14640 "from BIOS. Using base mode...\n");
14641 board_config = ALC269_BASIC;
14645 if (has_cdefine_beep(codec)) {
14646 err = snd_hda_attach_beep_device(codec, 0x1);
14647 if (err < 0) {
14648 alc_free(codec);
14649 return err;
14653 if (board_config != ALC269_AUTO)
14654 setup_preset(codec, &alc269_presets[board_config]);
14656 if (board_config == ALC269_QUANTA_FL1) {
14657 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14658 * fix the sample rate of analog I/O to 44.1kHz
14660 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14661 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14662 } else if (spec->dual_adc_switch) {
14663 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14664 /* switch ADC dynamically */
14665 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
14666 } else {
14667 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14668 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14670 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14671 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14673 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14674 if (!is_alc269vb) {
14675 spec->adc_nids = alc269_adc_nids;
14676 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14677 spec->capsrc_nids = alc269_capsrc_nids;
14678 } else {
14679 spec->adc_nids = alc269vb_adc_nids;
14680 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14681 spec->capsrc_nids = alc269vb_capsrc_nids;
14685 if (!spec->cap_mixer)
14686 set_capture_mixer(codec);
14687 if (has_cdefine_beep(codec))
14688 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14690 if (board_config == ALC269_AUTO)
14691 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
14693 spec->vmaster_nid = 0x02;
14695 codec->patch_ops = alc_patch_ops;
14696 if (board_config == ALC269_AUTO)
14697 spec->init_hook = alc269_auto_init;
14698 #ifdef CONFIG_SND_HDA_POWER_SAVE
14699 if (!spec->loopback.amplist)
14700 spec->loopback.amplist = alc269_loopbacks;
14701 if (alc269_mic2_for_mute_led(codec))
14702 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14703 #endif
14705 return 0;
14709 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14713 * set the path ways for 2 channel output
14714 * need to set the codec line out and mic 1 pin widgets to inputs
14716 static struct hda_verb alc861_threestack_ch2_init[] = {
14717 /* set pin widget 1Ah (line in) for input */
14718 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14719 /* set pin widget 18h (mic1/2) for input, for mic also enable
14720 * the vref
14722 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14724 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14725 #if 0
14726 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14727 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14728 #endif
14729 { } /* end */
14732 * 6ch mode
14733 * need to set the codec line out and mic 1 pin widgets to outputs
14735 static struct hda_verb alc861_threestack_ch6_init[] = {
14736 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14737 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14738 /* set pin widget 18h (mic1) for output (CLFE)*/
14739 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14741 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14742 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14744 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14745 #if 0
14746 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14747 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14748 #endif
14749 { } /* end */
14752 static struct hda_channel_mode alc861_threestack_modes[2] = {
14753 { 2, alc861_threestack_ch2_init },
14754 { 6, alc861_threestack_ch6_init },
14756 /* Set mic1 as input and unmute the mixer */
14757 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14758 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14759 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14760 { } /* end */
14762 /* Set mic1 as output and mute mixer */
14763 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14764 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14765 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14766 { } /* end */
14769 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14770 { 2, alc861_uniwill_m31_ch2_init },
14771 { 4, alc861_uniwill_m31_ch4_init },
14774 /* Set mic1 and line-in as input and unmute the mixer */
14775 static struct hda_verb alc861_asus_ch2_init[] = {
14776 /* set pin widget 1Ah (line in) for input */
14777 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14778 /* set pin widget 18h (mic1/2) for input, for mic also enable
14779 * the vref
14781 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14783 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14784 #if 0
14785 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14786 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14787 #endif
14788 { } /* end */
14790 /* Set mic1 nad line-in as output and mute mixer */
14791 static struct hda_verb alc861_asus_ch6_init[] = {
14792 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14793 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14794 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14795 /* set pin widget 18h (mic1) for output (CLFE)*/
14796 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14797 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14798 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14799 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14801 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14802 #if 0
14803 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14804 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14805 #endif
14806 { } /* end */
14809 static struct hda_channel_mode alc861_asus_modes[2] = {
14810 { 2, alc861_asus_ch2_init },
14811 { 6, alc861_asus_ch6_init },
14814 /* patch-ALC861 */
14816 static struct snd_kcontrol_new alc861_base_mixer[] = {
14817 /* output mixer control */
14818 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14819 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14820 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14821 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14822 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14824 /*Input mixer control */
14825 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14826 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14827 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14828 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14829 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14830 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14831 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14832 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14833 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14834 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14836 { } /* end */
14839 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14840 /* output mixer control */
14841 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14842 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14844 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14845 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14847 /* Input mixer control */
14848 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14849 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14850 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14851 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14852 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14853 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14855 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14856 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14857 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14861 .name = "Channel Mode",
14862 .info = alc_ch_mode_info,
14863 .get = alc_ch_mode_get,
14864 .put = alc_ch_mode_put,
14865 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14867 { } /* end */
14870 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14871 /* output mixer control */
14872 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14873 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14874 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14876 { } /* end */
14879 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14880 /* output mixer control */
14881 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14882 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14883 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14884 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14885 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14887 /* Input mixer control */
14888 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14889 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14890 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14891 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14892 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14893 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14894 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14895 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14896 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14901 .name = "Channel Mode",
14902 .info = alc_ch_mode_info,
14903 .get = alc_ch_mode_get,
14904 .put = alc_ch_mode_put,
14905 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14907 { } /* end */
14910 static struct snd_kcontrol_new alc861_asus_mixer[] = {
14911 /* output mixer control */
14912 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14913 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14914 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14915 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14916 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14918 /* Input mixer control */
14919 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14920 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14921 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14922 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14923 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14924 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14926 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14927 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14931 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14932 .name = "Channel Mode",
14933 .info = alc_ch_mode_info,
14934 .get = alc_ch_mode_get,
14935 .put = alc_ch_mode_put,
14936 .private_value = ARRAY_SIZE(alc861_asus_modes),
14941 /* additional mixer */
14942 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
14943 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14944 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14949 * generic initialization of ADC, input mixers and output mixers
14951 static struct hda_verb alc861_base_init_verbs[] = {
14953 * Unmute ADC0 and set the default input to mic-in
14955 /* port-A for surround (rear panel) */
14956 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14957 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14958 /* port-B for mic-in (rear panel) with vref */
14959 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14960 /* port-C for line-in (rear panel) */
14961 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14962 /* port-D for Front */
14963 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14964 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14965 /* port-E for HP out (front panel) */
14966 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14967 /* route front PCM to HP */
14968 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14969 /* port-F for mic-in (front panel) with vref */
14970 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14971 /* port-G for CLFE (rear panel) */
14972 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14973 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14974 /* port-H for side (rear panel) */
14975 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14976 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14977 /* CD-in */
14978 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14979 /* route front mic to ADC1*/
14980 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14981 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14983 /* Unmute DAC0~3 & spdif out*/
14984 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14985 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14986 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14987 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14988 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14990 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14991 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14992 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14993 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14994 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14996 /* Unmute Stereo Mixer 15 */
14997 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14998 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14999 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15002 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15003 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15004 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15005 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15006 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15007 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15008 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15009 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15010 /* hp used DAC 3 (Front) */
15011 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15012 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15017 static struct hda_verb alc861_threestack_init_verbs[] = {
15019 * Unmute ADC0 and set the default input to mic-in
15021 /* port-A for surround (rear panel) */
15022 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15023 /* port-B for mic-in (rear panel) with vref */
15024 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15025 /* port-C for line-in (rear panel) */
15026 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15027 /* port-D for Front */
15028 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15029 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15030 /* port-E for HP out (front panel) */
15031 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15032 /* route front PCM to HP */
15033 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15034 /* port-F for mic-in (front panel) with vref */
15035 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15036 /* port-G for CLFE (rear panel) */
15037 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15038 /* port-H for side (rear panel) */
15039 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15040 /* CD-in */
15041 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15042 /* route front mic to ADC1*/
15043 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15044 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15045 /* Unmute DAC0~3 & spdif out*/
15046 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15047 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15048 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15049 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15050 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15052 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15053 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15054 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15055 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15056 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15058 /* Unmute Stereo Mixer 15 */
15059 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15060 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15061 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15062 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15064 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15065 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15066 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15067 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15069 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15070 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15072 /* hp used DAC 3 (Front) */
15073 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15074 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15078 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15080 * Unmute ADC0 and set the default input to mic-in
15082 /* port-A for surround (rear panel) */
15083 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15084 /* port-B for mic-in (rear panel) with vref */
15085 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15086 /* port-C for line-in (rear panel) */
15087 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15088 /* port-D for Front */
15089 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15090 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15091 /* port-E for HP out (front panel) */
15092 /* this has to be set to VREF80 */
15093 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15094 /* route front PCM to HP */
15095 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15096 /* port-F for mic-in (front panel) with vref */
15097 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15098 /* port-G for CLFE (rear panel) */
15099 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15100 /* port-H for side (rear panel) */
15101 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15102 /* CD-in */
15103 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15104 /* route front mic to ADC1*/
15105 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15106 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15107 /* Unmute DAC0~3 & spdif out*/
15108 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15109 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15110 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15111 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15114 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15115 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15116 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15117 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15118 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15120 /* Unmute Stereo Mixer 15 */
15121 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15123 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15127 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15128 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15129 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15130 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15131 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15132 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15134 /* hp used DAC 3 (Front) */
15135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15140 static struct hda_verb alc861_asus_init_verbs[] = {
15142 * Unmute ADC0 and set the default input to mic-in
15144 /* port-A for surround (rear panel)
15145 * according to codec#0 this is the HP jack
15147 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15148 /* route front PCM to HP */
15149 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15150 /* port-B for mic-in (rear panel) with vref */
15151 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15152 /* port-C for line-in (rear panel) */
15153 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15154 /* port-D for Front */
15155 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15156 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15157 /* port-E for HP out (front panel) */
15158 /* this has to be set to VREF80 */
15159 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15160 /* route front PCM to HP */
15161 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15162 /* port-F for mic-in (front panel) with vref */
15163 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15164 /* port-G for CLFE (rear panel) */
15165 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15166 /* port-H for side (rear panel) */
15167 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15168 /* CD-in */
15169 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15170 /* route front mic to ADC1*/
15171 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15173 /* Unmute DAC0~3 & spdif out*/
15174 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15175 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15176 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15177 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15179 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15180 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15181 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15182 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15183 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15185 /* Unmute Stereo Mixer 15 */
15186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15188 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15191 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15192 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15194 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15195 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15196 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15197 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15199 /* hp used DAC 3 (Front) */
15200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15205 /* additional init verbs for ASUS laptops */
15206 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15207 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15208 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15213 * generic initialization of ADC, input mixers and output mixers
15215 static struct hda_verb alc861_auto_init_verbs[] = {
15217 * Unmute ADC0 and set the default input to mic-in
15219 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15222 /* Unmute DAC0~3 & spdif out*/
15223 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15224 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15225 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15226 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15229 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15230 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15231 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15232 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15233 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15235 /* Unmute Stereo Mixer 15 */
15236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15238 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15241 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15242 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15243 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15245 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15246 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15247 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15248 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15250 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15251 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15254 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15255 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15256 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15259 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15264 static struct hda_verb alc861_toshiba_init_verbs[] = {
15265 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15270 /* toggle speaker-output according to the hp-jack state */
15271 static void alc861_toshiba_automute(struct hda_codec *codec)
15273 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15275 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15276 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15277 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15278 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15281 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15282 unsigned int res)
15284 if ((res >> 26) == ALC880_HP_EVENT)
15285 alc861_toshiba_automute(codec);
15288 /* pcm configuration: identical with ALC880 */
15289 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15290 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15291 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15292 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15295 #define ALC861_DIGOUT_NID 0x07
15297 static struct hda_channel_mode alc861_8ch_modes[1] = {
15298 { 8, NULL }
15301 static hda_nid_t alc861_dac_nids[4] = {
15302 /* front, surround, clfe, side */
15303 0x03, 0x06, 0x05, 0x04
15306 static hda_nid_t alc660_dac_nids[3] = {
15307 /* front, clfe, surround */
15308 0x03, 0x05, 0x06
15311 static hda_nid_t alc861_adc_nids[1] = {
15312 /* ADC0-2 */
15313 0x08,
15316 static struct hda_input_mux alc861_capture_source = {
15317 .num_items = 5,
15318 .items = {
15319 { "Mic", 0x0 },
15320 { "Front Mic", 0x3 },
15321 { "Line", 0x1 },
15322 { "CD", 0x4 },
15323 { "Mixer", 0x5 },
15327 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15329 struct alc_spec *spec = codec->spec;
15330 hda_nid_t mix, srcs[5];
15331 int i, j, num;
15333 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15334 return 0;
15335 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15336 if (num < 0)
15337 return 0;
15338 for (i = 0; i < num; i++) {
15339 unsigned int type;
15340 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15341 if (type != AC_WID_AUD_OUT)
15342 continue;
15343 for (j = 0; j < spec->multiout.num_dacs; j++)
15344 if (spec->multiout.dac_nids[j] == srcs[i])
15345 break;
15346 if (j >= spec->multiout.num_dacs)
15347 return srcs[i];
15349 return 0;
15352 /* fill in the dac_nids table from the parsed pin configuration */
15353 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15354 const struct auto_pin_cfg *cfg)
15356 struct alc_spec *spec = codec->spec;
15357 int i;
15358 hda_nid_t nid, dac;
15360 spec->multiout.dac_nids = spec->private_dac_nids;
15361 for (i = 0; i < cfg->line_outs; i++) {
15362 nid = cfg->line_out_pins[i];
15363 dac = alc861_look_for_dac(codec, nid);
15364 if (!dac)
15365 continue;
15366 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15368 return 0;
15371 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15372 hda_nid_t nid, unsigned int chs)
15374 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
15375 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15378 /* add playback controls from the parsed DAC table */
15379 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15380 const struct auto_pin_cfg *cfg)
15382 struct alc_spec *spec = codec->spec;
15383 static const char *chname[4] = {
15384 "Front", "Surround", NULL /*CLFE*/, "Side"
15386 hda_nid_t nid;
15387 int i, err;
15389 if (cfg->line_outs == 1) {
15390 const char *pfx = NULL;
15391 if (!cfg->hp_outs)
15392 pfx = "Master";
15393 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15394 pfx = "Speaker";
15395 if (pfx) {
15396 nid = spec->multiout.dac_nids[0];
15397 return alc861_create_out_sw(codec, pfx, nid, 3);
15401 for (i = 0; i < cfg->line_outs; i++) {
15402 nid = spec->multiout.dac_nids[i];
15403 if (!nid)
15404 continue;
15405 if (i == 2) {
15406 /* Center/LFE */
15407 err = alc861_create_out_sw(codec, "Center", nid, 1);
15408 if (err < 0)
15409 return err;
15410 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15411 if (err < 0)
15412 return err;
15413 } else {
15414 err = alc861_create_out_sw(codec, chname[i], nid, 3);
15415 if (err < 0)
15416 return err;
15419 return 0;
15422 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15424 struct alc_spec *spec = codec->spec;
15425 int err;
15426 hda_nid_t nid;
15428 if (!pin)
15429 return 0;
15431 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15432 nid = alc861_look_for_dac(codec, pin);
15433 if (nid) {
15434 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15435 if (err < 0)
15436 return err;
15437 spec->multiout.hp_nid = nid;
15440 return 0;
15443 /* create playback/capture controls for input pins */
15444 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15445 const struct auto_pin_cfg *cfg)
15447 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15450 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15451 hda_nid_t nid,
15452 int pin_type, hda_nid_t dac)
15454 hda_nid_t mix, srcs[5];
15455 int i, num;
15457 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15458 pin_type);
15459 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15460 AMP_OUT_UNMUTE);
15461 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15462 return;
15463 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15464 if (num < 0)
15465 return;
15466 for (i = 0; i < num; i++) {
15467 unsigned int mute;
15468 if (srcs[i] == dac || srcs[i] == 0x15)
15469 mute = AMP_IN_UNMUTE(i);
15470 else
15471 mute = AMP_IN_MUTE(i);
15472 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15473 mute);
15477 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15479 struct alc_spec *spec = codec->spec;
15480 int i;
15482 for (i = 0; i < spec->autocfg.line_outs; i++) {
15483 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15484 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15485 if (nid)
15486 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15487 spec->multiout.dac_nids[i]);
15491 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15493 struct alc_spec *spec = codec->spec;
15495 if (spec->autocfg.hp_outs)
15496 alc861_auto_set_output_and_unmute(codec,
15497 spec->autocfg.hp_pins[0],
15498 PIN_HP,
15499 spec->multiout.hp_nid);
15500 if (spec->autocfg.speaker_outs)
15501 alc861_auto_set_output_and_unmute(codec,
15502 spec->autocfg.speaker_pins[0],
15503 PIN_OUT,
15504 spec->multiout.dac_nids[0]);
15507 static void alc861_auto_init_analog_input(struct hda_codec *codec)
15509 struct alc_spec *spec = codec->spec;
15510 int i;
15512 for (i = 0; i < AUTO_PIN_LAST; i++) {
15513 hda_nid_t nid = spec->autocfg.input_pins[i];
15514 if (nid >= 0x0c && nid <= 0x11)
15515 alc_set_input_pin(codec, nid, i);
15519 /* parse the BIOS configuration and set up the alc_spec */
15520 /* return 1 if successful, 0 if the proper config is not found,
15521 * or a negative error code
15523 static int alc861_parse_auto_config(struct hda_codec *codec)
15525 struct alc_spec *spec = codec->spec;
15526 int err;
15527 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15529 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15530 alc861_ignore);
15531 if (err < 0)
15532 return err;
15533 if (!spec->autocfg.line_outs)
15534 return 0; /* can't find valid BIOS pin config */
15536 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
15537 if (err < 0)
15538 return err;
15539 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15540 if (err < 0)
15541 return err;
15542 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15543 if (err < 0)
15544 return err;
15545 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
15546 if (err < 0)
15547 return err;
15549 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15551 alc_auto_parse_digital(codec);
15553 if (spec->kctls.list)
15554 add_mixer(spec, spec->kctls.list);
15556 add_verb(spec, alc861_auto_init_verbs);
15558 spec->num_mux_defs = 1;
15559 spec->input_mux = &spec->private_imux[0];
15561 spec->adc_nids = alc861_adc_nids;
15562 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
15563 set_capture_mixer(codec);
15565 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15567 return 1;
15570 /* additional initialization for auto-configuration model */
15571 static void alc861_auto_init(struct hda_codec *codec)
15573 struct alc_spec *spec = codec->spec;
15574 alc861_auto_init_multi_out(codec);
15575 alc861_auto_init_hp_out(codec);
15576 alc861_auto_init_analog_input(codec);
15577 alc_auto_init_digital(codec);
15578 if (spec->unsol_event)
15579 alc_inithook(codec);
15582 #ifdef CONFIG_SND_HDA_POWER_SAVE
15583 static struct hda_amp_list alc861_loopbacks[] = {
15584 { 0x15, HDA_INPUT, 0 },
15585 { 0x15, HDA_INPUT, 1 },
15586 { 0x15, HDA_INPUT, 2 },
15587 { 0x15, HDA_INPUT, 3 },
15588 { } /* end */
15590 #endif
15594 * configuration and preset
15596 static const char *alc861_models[ALC861_MODEL_LAST] = {
15597 [ALC861_3ST] = "3stack",
15598 [ALC660_3ST] = "3stack-660",
15599 [ALC861_3ST_DIG] = "3stack-dig",
15600 [ALC861_6ST_DIG] = "6stack-dig",
15601 [ALC861_UNIWILL_M31] = "uniwill-m31",
15602 [ALC861_TOSHIBA] = "toshiba",
15603 [ALC861_ASUS] = "asus",
15604 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15605 [ALC861_AUTO] = "auto",
15608 static struct snd_pci_quirk alc861_cfg_tbl[] = {
15609 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15610 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15611 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15612 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15613 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15614 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15615 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15616 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15617 * Any other models that need this preset?
15619 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15620 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15621 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15622 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15623 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15624 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15625 /* FIXME: the below seems conflict */
15626 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15627 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15628 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15632 static struct alc_config_preset alc861_presets[] = {
15633 [ALC861_3ST] = {
15634 .mixers = { alc861_3ST_mixer },
15635 .init_verbs = { alc861_threestack_init_verbs },
15636 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15637 .dac_nids = alc861_dac_nids,
15638 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15639 .channel_mode = alc861_threestack_modes,
15640 .need_dac_fix = 1,
15641 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15642 .adc_nids = alc861_adc_nids,
15643 .input_mux = &alc861_capture_source,
15645 [ALC861_3ST_DIG] = {
15646 .mixers = { alc861_base_mixer },
15647 .init_verbs = { alc861_threestack_init_verbs },
15648 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15649 .dac_nids = alc861_dac_nids,
15650 .dig_out_nid = ALC861_DIGOUT_NID,
15651 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15652 .channel_mode = alc861_threestack_modes,
15653 .need_dac_fix = 1,
15654 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15655 .adc_nids = alc861_adc_nids,
15656 .input_mux = &alc861_capture_source,
15658 [ALC861_6ST_DIG] = {
15659 .mixers = { alc861_base_mixer },
15660 .init_verbs = { alc861_base_init_verbs },
15661 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15662 .dac_nids = alc861_dac_nids,
15663 .dig_out_nid = ALC861_DIGOUT_NID,
15664 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15665 .channel_mode = alc861_8ch_modes,
15666 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15667 .adc_nids = alc861_adc_nids,
15668 .input_mux = &alc861_capture_source,
15670 [ALC660_3ST] = {
15671 .mixers = { alc861_3ST_mixer },
15672 .init_verbs = { alc861_threestack_init_verbs },
15673 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15674 .dac_nids = alc660_dac_nids,
15675 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15676 .channel_mode = alc861_threestack_modes,
15677 .need_dac_fix = 1,
15678 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15679 .adc_nids = alc861_adc_nids,
15680 .input_mux = &alc861_capture_source,
15682 [ALC861_UNIWILL_M31] = {
15683 .mixers = { alc861_uniwill_m31_mixer },
15684 .init_verbs = { alc861_uniwill_m31_init_verbs },
15685 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15686 .dac_nids = alc861_dac_nids,
15687 .dig_out_nid = ALC861_DIGOUT_NID,
15688 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15689 .channel_mode = alc861_uniwill_m31_modes,
15690 .need_dac_fix = 1,
15691 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15692 .adc_nids = alc861_adc_nids,
15693 .input_mux = &alc861_capture_source,
15695 [ALC861_TOSHIBA] = {
15696 .mixers = { alc861_toshiba_mixer },
15697 .init_verbs = { alc861_base_init_verbs,
15698 alc861_toshiba_init_verbs },
15699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15700 .dac_nids = alc861_dac_nids,
15701 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15702 .channel_mode = alc883_3ST_2ch_modes,
15703 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15704 .adc_nids = alc861_adc_nids,
15705 .input_mux = &alc861_capture_source,
15706 .unsol_event = alc861_toshiba_unsol_event,
15707 .init_hook = alc861_toshiba_automute,
15709 [ALC861_ASUS] = {
15710 .mixers = { alc861_asus_mixer },
15711 .init_verbs = { alc861_asus_init_verbs },
15712 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15713 .dac_nids = alc861_dac_nids,
15714 .dig_out_nid = ALC861_DIGOUT_NID,
15715 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15716 .channel_mode = alc861_asus_modes,
15717 .need_dac_fix = 1,
15718 .hp_nid = 0x06,
15719 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15720 .adc_nids = alc861_adc_nids,
15721 .input_mux = &alc861_capture_source,
15723 [ALC861_ASUS_LAPTOP] = {
15724 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15725 .init_verbs = { alc861_asus_init_verbs,
15726 alc861_asus_laptop_init_verbs },
15727 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15728 .dac_nids = alc861_dac_nids,
15729 .dig_out_nid = ALC861_DIGOUT_NID,
15730 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15731 .channel_mode = alc883_3ST_2ch_modes,
15732 .need_dac_fix = 1,
15733 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15734 .adc_nids = alc861_adc_nids,
15735 .input_mux = &alc861_capture_source,
15739 /* Pin config fixes */
15740 enum {
15741 PINFIX_FSC_AMILO_PI1505,
15744 static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15745 { 0x0b, 0x0221101f }, /* HP */
15746 { 0x0f, 0x90170310 }, /* speaker */
15750 static const struct alc_fixup alc861_fixups[] = {
15751 [PINFIX_FSC_AMILO_PI1505] = {
15752 .pins = alc861_fsc_amilo_pi1505_pinfix
15756 static struct snd_pci_quirk alc861_fixup_tbl[] = {
15757 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15761 static int patch_alc861(struct hda_codec *codec)
15763 struct alc_spec *spec;
15764 int board_config;
15765 int err;
15767 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15768 if (spec == NULL)
15769 return -ENOMEM;
15771 codec->spec = spec;
15773 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15774 alc861_models,
15775 alc861_cfg_tbl);
15777 if (board_config < 0) {
15778 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15779 codec->chip_name);
15780 board_config = ALC861_AUTO;
15783 if (board_config == ALC861_AUTO)
15784 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1);
15786 if (board_config == ALC861_AUTO) {
15787 /* automatic parse from the BIOS config */
15788 err = alc861_parse_auto_config(codec);
15789 if (err < 0) {
15790 alc_free(codec);
15791 return err;
15792 } else if (!err) {
15793 printk(KERN_INFO
15794 "hda_codec: Cannot set up configuration "
15795 "from BIOS. Using base mode...\n");
15796 board_config = ALC861_3ST_DIG;
15800 err = snd_hda_attach_beep_device(codec, 0x23);
15801 if (err < 0) {
15802 alc_free(codec);
15803 return err;
15806 if (board_config != ALC861_AUTO)
15807 setup_preset(codec, &alc861_presets[board_config]);
15809 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15810 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15812 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15813 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15815 if (!spec->cap_mixer)
15816 set_capture_mixer(codec);
15817 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15819 spec->vmaster_nid = 0x03;
15821 if (board_config == ALC861_AUTO)
15822 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
15824 codec->patch_ops = alc_patch_ops;
15825 if (board_config == ALC861_AUTO) {
15826 spec->init_hook = alc861_auto_init;
15827 #ifdef CONFIG_SND_HDA_POWER_SAVE
15828 spec->power_hook = alc_power_eapd;
15829 #endif
15831 #ifdef CONFIG_SND_HDA_POWER_SAVE
15832 if (!spec->loopback.amplist)
15833 spec->loopback.amplist = alc861_loopbacks;
15834 #endif
15836 return 0;
15840 * ALC861-VD support
15842 * Based on ALC882
15844 * In addition, an independent DAC
15846 #define ALC861VD_DIGOUT_NID 0x06
15848 static hda_nid_t alc861vd_dac_nids[4] = {
15849 /* front, surr, clfe, side surr */
15850 0x02, 0x03, 0x04, 0x05
15853 /* dac_nids for ALC660vd are in a different order - according to
15854 * Realtek's driver.
15855 * This should probably result in a different mixer for 6stack models
15856 * of ALC660vd codecs, but for now there is only 3stack mixer
15857 * - and it is the same as in 861vd.
15858 * adc_nids in ALC660vd are (is) the same as in 861vd
15860 static hda_nid_t alc660vd_dac_nids[3] = {
15861 /* front, rear, clfe, rear_surr */
15862 0x02, 0x04, 0x03
15865 static hda_nid_t alc861vd_adc_nids[1] = {
15866 /* ADC0 */
15867 0x09,
15870 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15872 /* input MUX */
15873 /* FIXME: should be a matrix-type input source selection */
15874 static struct hda_input_mux alc861vd_capture_source = {
15875 .num_items = 4,
15876 .items = {
15877 { "Mic", 0x0 },
15878 { "Front Mic", 0x1 },
15879 { "Line", 0x2 },
15880 { "CD", 0x4 },
15884 static struct hda_input_mux alc861vd_dallas_capture_source = {
15885 .num_items = 2,
15886 .items = {
15887 { "Ext Mic", 0x0 },
15888 { "Int Mic", 0x1 },
15892 static struct hda_input_mux alc861vd_hp_capture_source = {
15893 .num_items = 2,
15894 .items = {
15895 { "Front Mic", 0x0 },
15896 { "ATAPI Mic", 0x1 },
15901 * 2ch mode
15903 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15904 { 2, NULL }
15908 * 6ch mode
15910 static struct hda_verb alc861vd_6stack_ch6_init[] = {
15911 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15912 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15913 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15914 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15915 { } /* end */
15919 * 8ch mode
15921 static struct hda_verb alc861vd_6stack_ch8_init[] = {
15922 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15923 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15924 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15925 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15926 { } /* end */
15929 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15930 { 6, alc861vd_6stack_ch6_init },
15931 { 8, alc861vd_6stack_ch8_init },
15934 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15937 .name = "Channel Mode",
15938 .info = alc_ch_mode_info,
15939 .get = alc_ch_mode_get,
15940 .put = alc_ch_mode_put,
15942 { } /* end */
15945 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15946 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15948 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15949 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15950 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15952 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15953 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15955 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15956 HDA_OUTPUT),
15957 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15958 HDA_OUTPUT),
15959 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15960 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15962 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15963 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15965 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15967 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15968 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15969 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15971 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15972 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15973 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15975 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15976 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15981 { } /* end */
15984 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15985 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15986 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15991 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15992 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15994 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15995 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15996 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16004 { } /* end */
16007 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16008 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16009 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16010 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16012 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16014 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
16015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16018 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
16019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16020 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16022 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16023 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16025 { } /* end */
16028 /* Pin assignment: Speaker=0x14, HP = 0x15,
16029 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16031 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16032 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16033 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16034 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16035 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16036 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16037 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16038 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16039 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16040 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16041 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16042 { } /* end */
16045 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16046 * Front Mic=0x18, ATAPI Mic = 0x19,
16048 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16049 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16050 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16051 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16052 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16053 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16054 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16055 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16056 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16058 { } /* end */
16062 * generic initialization of ADC, input mixers and output mixers
16064 static struct hda_verb alc861vd_volume_init_verbs[] = {
16066 * Unmute ADC0 and set the default input to mic-in
16068 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16069 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16071 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16072 * the analog-loopback mixer widget
16074 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16075 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16076 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16077 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16078 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16079 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16081 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16088 * Set up output mixers (0x02 - 0x05)
16090 /* set vol=0 to output mixers */
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 /* set up input amps for analog loopback */
16097 /* Amp Indices: DAC = 0, mixer = 1 */
16098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16101 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16102 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16105 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16111 * 3-stack pin configuration:
16112 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16114 static struct hda_verb alc861vd_3stack_init_verbs[] = {
16116 * Set pin mode and muting
16118 /* set front pin widgets 0x14 for output */
16119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16121 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16123 /* Mic (rear) pin: input vref at 80% */
16124 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16125 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16126 /* Front Mic pin: input vref at 80% */
16127 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16128 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16129 /* Line In pin: input */
16130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16131 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16132 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16133 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16134 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16135 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16136 /* CD pin widget for input */
16137 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16143 * 6-stack pin configuration:
16145 static struct hda_verb alc861vd_6stack_init_verbs[] = {
16147 * Set pin mode and muting
16149 /* set front pin widgets 0x14 for output */
16150 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16151 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16152 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16154 /* Rear Pin: output 1 (0x0d) */
16155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16156 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16157 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16158 /* CLFE Pin: output 2 (0x0e) */
16159 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16161 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16162 /* Side Pin: output 3 (0x0f) */
16163 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16164 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16165 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16167 /* Mic (rear) pin: input vref at 80% */
16168 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16169 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16170 /* Front Mic pin: input vref at 80% */
16171 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16173 /* Line In pin: input */
16174 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16175 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16176 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16177 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16178 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16179 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16180 /* CD pin widget for input */
16181 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16186 static struct hda_verb alc861vd_eapd_verbs[] = {
16187 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16191 static struct hda_verb alc660vd_eapd_verbs[] = {
16192 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16193 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16197 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16198 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16199 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16200 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16201 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16202 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16206 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16208 unsigned int present;
16209 unsigned char bits;
16211 present = snd_hda_jack_detect(codec, 0x18);
16212 bits = present ? HDA_AMP_MUTE : 0;
16214 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16215 HDA_AMP_MUTE, bits);
16218 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16220 struct alc_spec *spec = codec->spec;
16221 spec->autocfg.hp_pins[0] = 0x1b;
16222 spec->autocfg.speaker_pins[0] = 0x14;
16225 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16227 alc_automute_amp(codec);
16228 alc861vd_lenovo_mic_automute(codec);
16231 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16232 unsigned int res)
16234 switch (res >> 26) {
16235 case ALC880_MIC_EVENT:
16236 alc861vd_lenovo_mic_automute(codec);
16237 break;
16238 default:
16239 alc_automute_amp_unsol_event(codec, res);
16240 break;
16244 static struct hda_verb alc861vd_dallas_verbs[] = {
16245 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16246 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16247 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16248 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16254 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16256 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16257 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16259 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16260 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16262 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16263 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16265 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16266 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16268 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16269 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16270 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16271 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16272 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16273 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16274 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16275 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16279 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16280 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16282 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16283 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16284 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16286 { } /* end */
16289 /* toggle speaker-output according to the hp-jack state */
16290 static void alc861vd_dallas_setup(struct hda_codec *codec)
16292 struct alc_spec *spec = codec->spec;
16294 spec->autocfg.hp_pins[0] = 0x15;
16295 spec->autocfg.speaker_pins[0] = 0x14;
16298 #ifdef CONFIG_SND_HDA_POWER_SAVE
16299 #define alc861vd_loopbacks alc880_loopbacks
16300 #endif
16302 /* pcm configuration: identical with ALC880 */
16303 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16304 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16305 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16306 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16309 * configuration and preset
16311 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
16312 [ALC660VD_3ST] = "3stack-660",
16313 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16314 [ALC660VD_ASUS_V1S] = "asus-v1s",
16315 [ALC861VD_3ST] = "3stack",
16316 [ALC861VD_3ST_DIG] = "3stack-digout",
16317 [ALC861VD_6ST_DIG] = "6stack-digout",
16318 [ALC861VD_LENOVO] = "lenovo",
16319 [ALC861VD_DALLAS] = "dallas",
16320 [ALC861VD_HP] = "hp",
16321 [ALC861VD_AUTO] = "auto",
16324 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16325 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16326 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16327 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16328 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16329 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16330 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16331 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16332 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16333 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16334 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16335 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16336 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16337 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16338 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16339 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16343 static struct alc_config_preset alc861vd_presets[] = {
16344 [ALC660VD_3ST] = {
16345 .mixers = { alc861vd_3st_mixer },
16346 .init_verbs = { alc861vd_volume_init_verbs,
16347 alc861vd_3stack_init_verbs },
16348 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16349 .dac_nids = alc660vd_dac_nids,
16350 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16351 .channel_mode = alc861vd_3stack_2ch_modes,
16352 .input_mux = &alc861vd_capture_source,
16354 [ALC660VD_3ST_DIG] = {
16355 .mixers = { alc861vd_3st_mixer },
16356 .init_verbs = { alc861vd_volume_init_verbs,
16357 alc861vd_3stack_init_verbs },
16358 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16359 .dac_nids = alc660vd_dac_nids,
16360 .dig_out_nid = ALC861VD_DIGOUT_NID,
16361 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16362 .channel_mode = alc861vd_3stack_2ch_modes,
16363 .input_mux = &alc861vd_capture_source,
16365 [ALC861VD_3ST] = {
16366 .mixers = { alc861vd_3st_mixer },
16367 .init_verbs = { alc861vd_volume_init_verbs,
16368 alc861vd_3stack_init_verbs },
16369 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16370 .dac_nids = alc861vd_dac_nids,
16371 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16372 .channel_mode = alc861vd_3stack_2ch_modes,
16373 .input_mux = &alc861vd_capture_source,
16375 [ALC861VD_3ST_DIG] = {
16376 .mixers = { alc861vd_3st_mixer },
16377 .init_verbs = { alc861vd_volume_init_verbs,
16378 alc861vd_3stack_init_verbs },
16379 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16380 .dac_nids = alc861vd_dac_nids,
16381 .dig_out_nid = ALC861VD_DIGOUT_NID,
16382 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16383 .channel_mode = alc861vd_3stack_2ch_modes,
16384 .input_mux = &alc861vd_capture_source,
16386 [ALC861VD_6ST_DIG] = {
16387 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16388 .init_verbs = { alc861vd_volume_init_verbs,
16389 alc861vd_6stack_init_verbs },
16390 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16391 .dac_nids = alc861vd_dac_nids,
16392 .dig_out_nid = ALC861VD_DIGOUT_NID,
16393 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16394 .channel_mode = alc861vd_6stack_modes,
16395 .input_mux = &alc861vd_capture_source,
16397 [ALC861VD_LENOVO] = {
16398 .mixers = { alc861vd_lenovo_mixer },
16399 .init_verbs = { alc861vd_volume_init_verbs,
16400 alc861vd_3stack_init_verbs,
16401 alc861vd_eapd_verbs,
16402 alc861vd_lenovo_unsol_verbs },
16403 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16404 .dac_nids = alc660vd_dac_nids,
16405 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16406 .channel_mode = alc861vd_3stack_2ch_modes,
16407 .input_mux = &alc861vd_capture_source,
16408 .unsol_event = alc861vd_lenovo_unsol_event,
16409 .setup = alc861vd_lenovo_setup,
16410 .init_hook = alc861vd_lenovo_init_hook,
16412 [ALC861VD_DALLAS] = {
16413 .mixers = { alc861vd_dallas_mixer },
16414 .init_verbs = { alc861vd_dallas_verbs },
16415 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16416 .dac_nids = alc861vd_dac_nids,
16417 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16418 .channel_mode = alc861vd_3stack_2ch_modes,
16419 .input_mux = &alc861vd_dallas_capture_source,
16420 .unsol_event = alc_automute_amp_unsol_event,
16421 .setup = alc861vd_dallas_setup,
16422 .init_hook = alc_automute_amp,
16424 [ALC861VD_HP] = {
16425 .mixers = { alc861vd_hp_mixer },
16426 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16427 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16428 .dac_nids = alc861vd_dac_nids,
16429 .dig_out_nid = ALC861VD_DIGOUT_NID,
16430 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16431 .channel_mode = alc861vd_3stack_2ch_modes,
16432 .input_mux = &alc861vd_hp_capture_source,
16433 .unsol_event = alc_automute_amp_unsol_event,
16434 .setup = alc861vd_dallas_setup,
16435 .init_hook = alc_automute_amp,
16437 [ALC660VD_ASUS_V1S] = {
16438 .mixers = { alc861vd_lenovo_mixer },
16439 .init_verbs = { alc861vd_volume_init_verbs,
16440 alc861vd_3stack_init_verbs,
16441 alc861vd_eapd_verbs,
16442 alc861vd_lenovo_unsol_verbs },
16443 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16444 .dac_nids = alc660vd_dac_nids,
16445 .dig_out_nid = ALC861VD_DIGOUT_NID,
16446 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16447 .channel_mode = alc861vd_3stack_2ch_modes,
16448 .input_mux = &alc861vd_capture_source,
16449 .unsol_event = alc861vd_lenovo_unsol_event,
16450 .setup = alc861vd_lenovo_setup,
16451 .init_hook = alc861vd_lenovo_init_hook,
16456 * BIOS auto configuration
16458 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16459 const struct auto_pin_cfg *cfg)
16461 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
16465 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16466 hda_nid_t nid, int pin_type, int dac_idx)
16468 alc_set_pin_output(codec, nid, pin_type);
16471 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16473 struct alc_spec *spec = codec->spec;
16474 int i;
16476 for (i = 0; i <= HDA_SIDE; i++) {
16477 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16478 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16479 if (nid)
16480 alc861vd_auto_set_output_and_unmute(codec, nid,
16481 pin_type, i);
16486 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16488 struct alc_spec *spec = codec->spec;
16489 hda_nid_t pin;
16491 pin = spec->autocfg.hp_pins[0];
16492 if (pin) /* connect to front and use dac 0 */
16493 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16494 pin = spec->autocfg.speaker_pins[0];
16495 if (pin)
16496 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16499 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16501 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16503 struct alc_spec *spec = codec->spec;
16504 int i;
16506 for (i = 0; i < AUTO_PIN_LAST; i++) {
16507 hda_nid_t nid = spec->autocfg.input_pins[i];
16508 if (alc_is_input_pin(codec, nid)) {
16509 alc_set_input_pin(codec, nid, i);
16510 if (nid != ALC861VD_PIN_CD_NID &&
16511 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16512 snd_hda_codec_write(codec, nid, 0,
16513 AC_VERB_SET_AMP_GAIN_MUTE,
16514 AMP_OUT_MUTE);
16519 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16521 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16522 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16524 /* add playback controls from the parsed DAC table */
16525 /* Based on ALC880 version. But ALC861VD has separate,
16526 * different NIDs for mute/unmute switch and volume control */
16527 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16528 const struct auto_pin_cfg *cfg)
16530 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16531 hda_nid_t nid_v, nid_s;
16532 int i, err;
16534 for (i = 0; i < cfg->line_outs; i++) {
16535 if (!spec->multiout.dac_nids[i])
16536 continue;
16537 nid_v = alc861vd_idx_to_mixer_vol(
16538 alc880_dac_to_idx(
16539 spec->multiout.dac_nids[i]));
16540 nid_s = alc861vd_idx_to_mixer_switch(
16541 alc880_dac_to_idx(
16542 spec->multiout.dac_nids[i]));
16544 if (i == 2) {
16545 /* Center/LFE */
16546 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16547 "Center",
16548 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16549 HDA_OUTPUT));
16550 if (err < 0)
16551 return err;
16552 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16553 "LFE",
16554 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16555 HDA_OUTPUT));
16556 if (err < 0)
16557 return err;
16558 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16559 "Center",
16560 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16561 HDA_INPUT));
16562 if (err < 0)
16563 return err;
16564 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16565 "LFE",
16566 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16567 HDA_INPUT));
16568 if (err < 0)
16569 return err;
16570 } else {
16571 const char *pfx;
16572 if (cfg->line_outs == 1 &&
16573 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16574 if (!cfg->hp_pins)
16575 pfx = "Speaker";
16576 else
16577 pfx = "PCM";
16578 } else
16579 pfx = chname[i];
16580 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16581 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16582 HDA_OUTPUT));
16583 if (err < 0)
16584 return err;
16585 if (cfg->line_outs == 1 &&
16586 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16587 pfx = "Speaker";
16588 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16589 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16590 HDA_INPUT));
16591 if (err < 0)
16592 return err;
16595 return 0;
16598 /* add playback controls for speaker and HP outputs */
16599 /* Based on ALC880 version. But ALC861VD has separate,
16600 * different NIDs for mute/unmute switch and volume control */
16601 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16602 hda_nid_t pin, const char *pfx)
16604 hda_nid_t nid_v, nid_s;
16605 int err;
16607 if (!pin)
16608 return 0;
16610 if (alc880_is_fixed_pin(pin)) {
16611 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16612 /* specify the DAC as the extra output */
16613 if (!spec->multiout.hp_nid)
16614 spec->multiout.hp_nid = nid_v;
16615 else
16616 spec->multiout.extra_out_nid[0] = nid_v;
16617 /* control HP volume/switch on the output mixer amp */
16618 nid_v = alc861vd_idx_to_mixer_vol(
16619 alc880_fixed_pin_idx(pin));
16620 nid_s = alc861vd_idx_to_mixer_switch(
16621 alc880_fixed_pin_idx(pin));
16623 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16624 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16625 if (err < 0)
16626 return err;
16627 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16628 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16629 if (err < 0)
16630 return err;
16631 } else if (alc880_is_multi_pin(pin)) {
16632 /* set manual connection */
16633 /* we have only a switch on HP-out PIN */
16634 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
16635 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16636 if (err < 0)
16637 return err;
16639 return 0;
16642 /* parse the BIOS configuration and set up the alc_spec
16643 * return 1 if successful, 0 if the proper config is not found,
16644 * or a negative error code
16645 * Based on ALC880 version - had to change it to override
16646 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16647 static int alc861vd_parse_auto_config(struct hda_codec *codec)
16649 struct alc_spec *spec = codec->spec;
16650 int err;
16651 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16653 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16654 alc861vd_ignore);
16655 if (err < 0)
16656 return err;
16657 if (!spec->autocfg.line_outs)
16658 return 0; /* can't find valid BIOS pin config */
16660 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16661 if (err < 0)
16662 return err;
16663 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16664 if (err < 0)
16665 return err;
16666 err = alc861vd_auto_create_extra_out(spec,
16667 spec->autocfg.speaker_pins[0],
16668 "Speaker");
16669 if (err < 0)
16670 return err;
16671 err = alc861vd_auto_create_extra_out(spec,
16672 spec->autocfg.hp_pins[0],
16673 "Headphone");
16674 if (err < 0)
16675 return err;
16676 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
16677 if (err < 0)
16678 return err;
16680 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16682 alc_auto_parse_digital(codec);
16684 if (spec->kctls.list)
16685 add_mixer(spec, spec->kctls.list);
16687 add_verb(spec, alc861vd_volume_init_verbs);
16689 spec->num_mux_defs = 1;
16690 spec->input_mux = &spec->private_imux[0];
16692 err = alc_auto_add_mic_boost(codec);
16693 if (err < 0)
16694 return err;
16696 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16698 return 1;
16701 /* additional initialization for auto-configuration model */
16702 static void alc861vd_auto_init(struct hda_codec *codec)
16704 struct alc_spec *spec = codec->spec;
16705 alc861vd_auto_init_multi_out(codec);
16706 alc861vd_auto_init_hp_out(codec);
16707 alc861vd_auto_init_analog_input(codec);
16708 alc861vd_auto_init_input_src(codec);
16709 alc_auto_init_digital(codec);
16710 if (spec->unsol_event)
16711 alc_inithook(codec);
16714 enum {
16715 ALC660VD_FIX_ASUS_GPIO1
16718 /* reset GPIO1 */
16719 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16720 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16721 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16722 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16726 static const struct alc_fixup alc861vd_fixups[] = {
16727 [ALC660VD_FIX_ASUS_GPIO1] = {
16728 .verbs = alc660vd_fix_asus_gpio1_verbs,
16732 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16733 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16737 static int patch_alc861vd(struct hda_codec *codec)
16739 struct alc_spec *spec;
16740 int err, board_config;
16742 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16743 if (spec == NULL)
16744 return -ENOMEM;
16746 codec->spec = spec;
16748 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16749 alc861vd_models,
16750 alc861vd_cfg_tbl);
16752 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
16753 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16754 codec->chip_name);
16755 board_config = ALC861VD_AUTO;
16758 if (board_config == ALC861VD_AUTO)
16759 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1);
16761 if (board_config == ALC861VD_AUTO) {
16762 /* automatic parse from the BIOS config */
16763 err = alc861vd_parse_auto_config(codec);
16764 if (err < 0) {
16765 alc_free(codec);
16766 return err;
16767 } else if (!err) {
16768 printk(KERN_INFO
16769 "hda_codec: Cannot set up configuration "
16770 "from BIOS. Using base mode...\n");
16771 board_config = ALC861VD_3ST;
16775 err = snd_hda_attach_beep_device(codec, 0x23);
16776 if (err < 0) {
16777 alc_free(codec);
16778 return err;
16781 if (board_config != ALC861VD_AUTO)
16782 setup_preset(codec, &alc861vd_presets[board_config]);
16784 if (codec->vendor_id == 0x10ec0660) {
16785 /* always turn on EAPD */
16786 add_verb(spec, alc660vd_eapd_verbs);
16789 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16790 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16792 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16793 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16795 if (!spec->adc_nids) {
16796 spec->adc_nids = alc861vd_adc_nids;
16797 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16799 if (!spec->capsrc_nids)
16800 spec->capsrc_nids = alc861vd_capsrc_nids;
16802 set_capture_mixer(codec);
16803 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16805 spec->vmaster_nid = 0x02;
16807 if (board_config == ALC861VD_AUTO)
16808 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
16810 codec->patch_ops = alc_patch_ops;
16812 if (board_config == ALC861VD_AUTO)
16813 spec->init_hook = alc861vd_auto_init;
16814 #ifdef CONFIG_SND_HDA_POWER_SAVE
16815 if (!spec->loopback.amplist)
16816 spec->loopback.amplist = alc861vd_loopbacks;
16817 #endif
16819 return 0;
16823 * ALC662 support
16825 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16826 * configuration. Each pin widget can choose any input DACs and a mixer.
16827 * Each ADC is connected from a mixer of all inputs. This makes possible
16828 * 6-channel independent captures.
16830 * In addition, an independent DAC for the multi-playback (not used in this
16831 * driver yet).
16833 #define ALC662_DIGOUT_NID 0x06
16834 #define ALC662_DIGIN_NID 0x0a
16836 static hda_nid_t alc662_dac_nids[4] = {
16837 /* front, rear, clfe, rear_surr */
16838 0x02, 0x03, 0x04
16841 static hda_nid_t alc272_dac_nids[2] = {
16842 0x02, 0x03
16845 static hda_nid_t alc662_adc_nids[2] = {
16846 /* ADC1-2 */
16847 0x09, 0x08
16850 static hda_nid_t alc272_adc_nids[1] = {
16851 /* ADC1-2 */
16852 0x08,
16855 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16856 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16859 /* input MUX */
16860 /* FIXME: should be a matrix-type input source selection */
16861 static struct hda_input_mux alc662_capture_source = {
16862 .num_items = 4,
16863 .items = {
16864 { "Mic", 0x0 },
16865 { "Front Mic", 0x1 },
16866 { "Line", 0x2 },
16867 { "CD", 0x4 },
16871 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16872 .num_items = 2,
16873 .items = {
16874 { "Mic", 0x1 },
16875 { "Line", 0x2 },
16879 static struct hda_input_mux alc663_capture_source = {
16880 .num_items = 3,
16881 .items = {
16882 { "Mic", 0x0 },
16883 { "Front Mic", 0x1 },
16884 { "Line", 0x2 },
16888 #if 0 /* set to 1 for testing other input sources below */
16889 static struct hda_input_mux alc272_nc10_capture_source = {
16890 .num_items = 16,
16891 .items = {
16892 { "Autoselect Mic", 0x0 },
16893 { "Internal Mic", 0x1 },
16894 { "In-0x02", 0x2 },
16895 { "In-0x03", 0x3 },
16896 { "In-0x04", 0x4 },
16897 { "In-0x05", 0x5 },
16898 { "In-0x06", 0x6 },
16899 { "In-0x07", 0x7 },
16900 { "In-0x08", 0x8 },
16901 { "In-0x09", 0x9 },
16902 { "In-0x0a", 0x0a },
16903 { "In-0x0b", 0x0b },
16904 { "In-0x0c", 0x0c },
16905 { "In-0x0d", 0x0d },
16906 { "In-0x0e", 0x0e },
16907 { "In-0x0f", 0x0f },
16910 #endif
16913 * 2ch mode
16915 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16916 { 2, NULL }
16920 * 2ch mode
16922 static struct hda_verb alc662_3ST_ch2_init[] = {
16923 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16924 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16925 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16926 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16927 { } /* end */
16931 * 6ch mode
16933 static struct hda_verb alc662_3ST_ch6_init[] = {
16934 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16935 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16936 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16937 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16938 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16939 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16940 { } /* end */
16943 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16944 { 2, alc662_3ST_ch2_init },
16945 { 6, alc662_3ST_ch6_init },
16949 * 2ch mode
16951 static struct hda_verb alc662_sixstack_ch6_init[] = {
16952 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16953 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16954 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16955 { } /* end */
16959 * 6ch mode
16961 static struct hda_verb alc662_sixstack_ch8_init[] = {
16962 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16963 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16964 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16965 { } /* end */
16968 static struct hda_channel_mode alc662_5stack_modes[2] = {
16969 { 2, alc662_sixstack_ch6_init },
16970 { 6, alc662_sixstack_ch8_init },
16973 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16974 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16977 static struct snd_kcontrol_new alc662_base_mixer[] = {
16978 /* output mixer control */
16979 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16980 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16981 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16982 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16983 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16984 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16985 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16986 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16987 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16989 /*Input mixer control */
16990 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16991 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16992 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16993 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16994 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16995 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16997 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16998 { } /* end */
17001 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17002 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17003 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17009 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17011 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17012 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17013 { } /* end */
17016 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17017 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17018 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17019 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17020 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17021 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17022 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17023 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17024 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17026 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17027 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17028 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17029 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17033 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17034 { } /* end */
17037 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17038 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17039 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17040 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17041 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17042 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17043 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17044 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17047 { } /* end */
17050 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17051 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17052 ALC262_HIPPO_MASTER_SWITCH,
17054 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
17055 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17056 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17058 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17059 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17060 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17061 { } /* end */
17064 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17065 ALC262_HIPPO_MASTER_SWITCH,
17066 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17067 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17068 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17069 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17070 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17071 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17072 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17075 { } /* end */
17078 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17079 .ops = &snd_hda_bind_vol,
17080 .values = {
17081 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17082 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17087 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17088 .ops = &snd_hda_bind_sw,
17089 .values = {
17090 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17091 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17096 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17097 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17098 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17101 { } /* end */
17104 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17105 .ops = &snd_hda_bind_sw,
17106 .values = {
17107 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17108 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17109 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17114 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17115 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17116 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17119 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17120 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17122 { } /* end */
17125 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17126 .ops = &snd_hda_bind_sw,
17127 .values = {
17128 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17129 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17130 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17135 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17136 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17137 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17140 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17141 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17142 { } /* end */
17145 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17146 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17147 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17148 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17151 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17152 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17153 { } /* end */
17156 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17157 .ops = &snd_hda_bind_vol,
17158 .values = {
17159 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17160 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17165 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17166 .ops = &snd_hda_bind_sw,
17167 .values = {
17168 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17169 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17174 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17175 HDA_BIND_VOL("Master Playback Volume",
17176 &alc663_asus_two_bind_master_vol),
17177 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17178 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17179 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17180 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17182 { } /* end */
17185 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17186 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17187 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17188 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17192 { } /* end */
17195 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17197 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17199 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17200 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17202 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17203 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17204 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17205 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17206 { } /* end */
17209 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17211 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17216 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17217 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17220 { } /* end */
17223 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17224 .ops = &snd_hda_bind_sw,
17225 .values = {
17226 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17227 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17228 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17229 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17230 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17235 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17236 .ops = &snd_hda_bind_sw,
17237 .values = {
17238 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17239 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17244 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17245 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17246 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17247 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17248 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17249 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17250 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17251 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17253 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17254 { } /* end */
17257 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17258 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17259 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17260 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17261 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17262 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17265 { } /* end */
17269 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17271 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17272 .name = "Channel Mode",
17273 .info = alc_ch_mode_info,
17274 .get = alc_ch_mode_get,
17275 .put = alc_ch_mode_put,
17277 { } /* end */
17280 static struct hda_verb alc662_init_verbs[] = {
17281 /* ADC: mute amp left and right */
17282 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17283 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17285 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17287 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17288 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17289 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17290 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17292 /* Front Pin: output 0 (0x0c) */
17293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17296 /* Rear Pin: output 1 (0x0d) */
17297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17298 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17300 /* CLFE Pin: output 2 (0x0e) */
17301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17304 /* Mic (rear) pin: input vref at 80% */
17305 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17306 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17307 /* Front Mic pin: input vref at 80% */
17308 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17309 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17310 /* Line In pin: input */
17311 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17313 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17314 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17316 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17317 /* CD pin widget for input */
17318 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17320 /* FIXME: use matrix-type input source selection */
17321 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17322 /* Input mixer */
17323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17326 /* always trun on EAPD */
17327 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17328 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17333 static struct hda_verb alc663_init_verbs[] = {
17334 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17336 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17337 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17343 static struct hda_verb alc272_init_verbs[] = {
17344 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17345 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17346 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17347 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17348 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17349 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17350 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17351 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17355 static struct hda_verb alc662_sue_init_verbs[] = {
17356 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17357 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17361 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17362 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17363 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17367 /* Set Unsolicited Event*/
17368 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17370 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17374 static struct hda_verb alc663_m51va_init_verbs[] = {
17375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17376 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17377 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17378 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17379 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17381 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17382 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17383 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17387 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17388 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17389 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17390 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17393 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17394 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17398 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17399 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17400 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17401 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17402 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17403 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17404 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17405 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17406 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17410 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17412 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17413 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17414 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17415 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17416 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17417 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17421 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17422 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17423 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17424 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17425 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17426 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17429 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17430 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17431 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17432 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17433 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17437 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17438 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17444 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17445 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17446 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17447 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17448 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17449 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17453 static struct hda_verb alc663_g71v_init_verbs[] = {
17454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17455 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17456 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17458 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17459 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17460 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17462 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17463 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17464 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17468 static struct hda_verb alc663_g50v_init_verbs[] = {
17469 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17470 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17471 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17473 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17474 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17478 static struct hda_verb alc662_ecs_init_verbs[] = {
17479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17481 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17482 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17486 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17487 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17488 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17489 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17490 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17491 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17492 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17493 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17495 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17496 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17497 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17501 static struct hda_verb alc272_dell_init_verbs[] = {
17502 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17503 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17504 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17505 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17506 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17507 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17508 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17510 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17511 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17512 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17516 static struct hda_verb alc663_mode7_init_verbs[] = {
17517 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17518 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17519 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17520 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17521 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17522 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17523 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17524 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17525 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17526 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17529 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17530 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17531 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17535 static struct hda_verb alc663_mode8_init_verbs[] = {
17536 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17539 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17541 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17542 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17543 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17544 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17545 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17546 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17547 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17548 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17549 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17550 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17551 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17555 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17556 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17557 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17558 { } /* end */
17561 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17562 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17563 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17564 { } /* end */
17567 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17569 unsigned int present;
17570 unsigned char bits;
17572 present = snd_hda_jack_detect(codec, 0x14);
17573 bits = present ? HDA_AMP_MUTE : 0;
17575 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17576 HDA_AMP_MUTE, bits);
17579 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17581 unsigned int present;
17582 unsigned char bits;
17584 present = snd_hda_jack_detect(codec, 0x1b);
17585 bits = present ? HDA_AMP_MUTE : 0;
17587 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17588 HDA_AMP_MUTE, bits);
17589 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17590 HDA_AMP_MUTE, bits);
17593 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17594 unsigned int res)
17596 if ((res >> 26) == ALC880_HP_EVENT)
17597 alc662_lenovo_101e_all_automute(codec);
17598 if ((res >> 26) == ALC880_FRONT_EVENT)
17599 alc662_lenovo_101e_ispeaker_automute(codec);
17602 /* unsolicited event for HP jack sensing */
17603 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17604 unsigned int res)
17606 if ((res >> 26) == ALC880_MIC_EVENT)
17607 alc_mic_automute(codec);
17608 else
17609 alc262_hippo_unsol_event(codec, res);
17612 static void alc662_eeepc_setup(struct hda_codec *codec)
17614 struct alc_spec *spec = codec->spec;
17616 alc262_hippo1_setup(codec);
17617 spec->ext_mic.pin = 0x18;
17618 spec->ext_mic.mux_idx = 0;
17619 spec->int_mic.pin = 0x19;
17620 spec->int_mic.mux_idx = 1;
17621 spec->auto_mic = 1;
17624 static void alc662_eeepc_inithook(struct hda_codec *codec)
17626 alc262_hippo_automute(codec);
17627 alc_mic_automute(codec);
17630 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17632 struct alc_spec *spec = codec->spec;
17634 spec->autocfg.hp_pins[0] = 0x14;
17635 spec->autocfg.speaker_pins[0] = 0x1b;
17638 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17640 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17642 unsigned int present;
17643 unsigned char bits;
17645 present = snd_hda_jack_detect(codec, 0x21);
17646 bits = present ? HDA_AMP_MUTE : 0;
17647 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17648 HDA_AMP_MUTE, bits);
17649 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17650 HDA_AMP_MUTE, bits);
17653 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17655 unsigned int present;
17656 unsigned char bits;
17658 present = snd_hda_jack_detect(codec, 0x21);
17659 bits = present ? HDA_AMP_MUTE : 0;
17660 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17661 HDA_AMP_MUTE, bits);
17662 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17663 HDA_AMP_MUTE, bits);
17664 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17665 HDA_AMP_MUTE, bits);
17666 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17667 HDA_AMP_MUTE, bits);
17670 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17672 unsigned int present;
17673 unsigned char bits;
17675 present = snd_hda_jack_detect(codec, 0x15);
17676 bits = present ? HDA_AMP_MUTE : 0;
17677 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17678 HDA_AMP_MUTE, bits);
17679 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17680 HDA_AMP_MUTE, bits);
17681 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17682 HDA_AMP_MUTE, bits);
17683 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17684 HDA_AMP_MUTE, bits);
17687 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17689 unsigned int present;
17690 unsigned char bits;
17692 present = snd_hda_jack_detect(codec, 0x1b);
17693 bits = present ? 0 : PIN_OUT;
17694 snd_hda_codec_write(codec, 0x14, 0,
17695 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17698 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17700 unsigned int present1, present2;
17702 present1 = snd_hda_jack_detect(codec, 0x21);
17703 present2 = snd_hda_jack_detect(codec, 0x15);
17705 if (present1 || present2) {
17706 snd_hda_codec_write_cache(codec, 0x14, 0,
17707 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17708 } else {
17709 snd_hda_codec_write_cache(codec, 0x14, 0,
17710 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17714 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17716 unsigned int present1, present2;
17718 present1 = snd_hda_jack_detect(codec, 0x1b);
17719 present2 = snd_hda_jack_detect(codec, 0x15);
17721 if (present1 || present2) {
17722 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17723 HDA_AMP_MUTE, HDA_AMP_MUTE);
17724 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17725 HDA_AMP_MUTE, HDA_AMP_MUTE);
17726 } else {
17727 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17728 HDA_AMP_MUTE, 0);
17729 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17730 HDA_AMP_MUTE, 0);
17734 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17736 unsigned int present1, present2;
17738 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17739 AC_VERB_GET_PIN_SENSE, 0)
17740 & AC_PINSENSE_PRESENCE;
17741 present2 = snd_hda_codec_read(codec, 0x21, 0,
17742 AC_VERB_GET_PIN_SENSE, 0)
17743 & AC_PINSENSE_PRESENCE;
17745 if (present1 || present2) {
17746 snd_hda_codec_write_cache(codec, 0x14, 0,
17747 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17748 snd_hda_codec_write_cache(codec, 0x17, 0,
17749 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17750 } else {
17751 snd_hda_codec_write_cache(codec, 0x14, 0,
17752 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17753 snd_hda_codec_write_cache(codec, 0x17, 0,
17754 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17758 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17760 unsigned int present1, present2;
17762 present1 = snd_hda_codec_read(codec, 0x21, 0,
17763 AC_VERB_GET_PIN_SENSE, 0)
17764 & AC_PINSENSE_PRESENCE;
17765 present2 = snd_hda_codec_read(codec, 0x15, 0,
17766 AC_VERB_GET_PIN_SENSE, 0)
17767 & AC_PINSENSE_PRESENCE;
17769 if (present1 || present2) {
17770 snd_hda_codec_write_cache(codec, 0x14, 0,
17771 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17772 snd_hda_codec_write_cache(codec, 0x17, 0,
17773 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17774 } else {
17775 snd_hda_codec_write_cache(codec, 0x14, 0,
17776 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17777 snd_hda_codec_write_cache(codec, 0x17, 0,
17778 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17782 static void alc663_m51va_unsol_event(struct hda_codec *codec,
17783 unsigned int res)
17785 switch (res >> 26) {
17786 case ALC880_HP_EVENT:
17787 alc663_m51va_speaker_automute(codec);
17788 break;
17789 case ALC880_MIC_EVENT:
17790 alc_mic_automute(codec);
17791 break;
17795 static void alc663_m51va_setup(struct hda_codec *codec)
17797 struct alc_spec *spec = codec->spec;
17798 spec->ext_mic.pin = 0x18;
17799 spec->ext_mic.mux_idx = 0;
17800 spec->int_mic.pin = 0x12;
17801 spec->int_mic.mux_idx = 9;
17802 spec->auto_mic = 1;
17805 static void alc663_m51va_inithook(struct hda_codec *codec)
17807 alc663_m51va_speaker_automute(codec);
17808 alc_mic_automute(codec);
17811 /* ***************** Mode1 ******************************/
17812 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
17814 static void alc663_mode1_setup(struct hda_codec *codec)
17816 struct alc_spec *spec = codec->spec;
17817 spec->ext_mic.pin = 0x18;
17818 spec->ext_mic.mux_idx = 0;
17819 spec->int_mic.pin = 0x19;
17820 spec->int_mic.mux_idx = 1;
17821 spec->auto_mic = 1;
17824 #define alc663_mode1_inithook alc663_m51va_inithook
17826 /* ***************** Mode2 ******************************/
17827 static void alc662_mode2_unsol_event(struct hda_codec *codec,
17828 unsigned int res)
17830 switch (res >> 26) {
17831 case ALC880_HP_EVENT:
17832 alc662_f5z_speaker_automute(codec);
17833 break;
17834 case ALC880_MIC_EVENT:
17835 alc_mic_automute(codec);
17836 break;
17840 #define alc662_mode2_setup alc663_mode1_setup
17842 static void alc662_mode2_inithook(struct hda_codec *codec)
17844 alc662_f5z_speaker_automute(codec);
17845 alc_mic_automute(codec);
17847 /* ***************** Mode3 ******************************/
17848 static void alc663_mode3_unsol_event(struct hda_codec *codec,
17849 unsigned int res)
17851 switch (res >> 26) {
17852 case ALC880_HP_EVENT:
17853 alc663_two_hp_m1_speaker_automute(codec);
17854 break;
17855 case ALC880_MIC_EVENT:
17856 alc_mic_automute(codec);
17857 break;
17861 #define alc663_mode3_setup alc663_mode1_setup
17863 static void alc663_mode3_inithook(struct hda_codec *codec)
17865 alc663_two_hp_m1_speaker_automute(codec);
17866 alc_mic_automute(codec);
17868 /* ***************** Mode4 ******************************/
17869 static void alc663_mode4_unsol_event(struct hda_codec *codec,
17870 unsigned int res)
17872 switch (res >> 26) {
17873 case ALC880_HP_EVENT:
17874 alc663_21jd_two_speaker_automute(codec);
17875 break;
17876 case ALC880_MIC_EVENT:
17877 alc_mic_automute(codec);
17878 break;
17882 #define alc663_mode4_setup alc663_mode1_setup
17884 static void alc663_mode4_inithook(struct hda_codec *codec)
17886 alc663_21jd_two_speaker_automute(codec);
17887 alc_mic_automute(codec);
17889 /* ***************** Mode5 ******************************/
17890 static void alc663_mode5_unsol_event(struct hda_codec *codec,
17891 unsigned int res)
17893 switch (res >> 26) {
17894 case ALC880_HP_EVENT:
17895 alc663_15jd_two_speaker_automute(codec);
17896 break;
17897 case ALC880_MIC_EVENT:
17898 alc_mic_automute(codec);
17899 break;
17903 #define alc663_mode5_setup alc663_mode1_setup
17905 static void alc663_mode5_inithook(struct hda_codec *codec)
17907 alc663_15jd_two_speaker_automute(codec);
17908 alc_mic_automute(codec);
17910 /* ***************** Mode6 ******************************/
17911 static void alc663_mode6_unsol_event(struct hda_codec *codec,
17912 unsigned int res)
17914 switch (res >> 26) {
17915 case ALC880_HP_EVENT:
17916 alc663_two_hp_m2_speaker_automute(codec);
17917 break;
17918 case ALC880_MIC_EVENT:
17919 alc_mic_automute(codec);
17920 break;
17924 #define alc663_mode6_setup alc663_mode1_setup
17926 static void alc663_mode6_inithook(struct hda_codec *codec)
17928 alc663_two_hp_m2_speaker_automute(codec);
17929 alc_mic_automute(codec);
17932 /* ***************** Mode7 ******************************/
17933 static void alc663_mode7_unsol_event(struct hda_codec *codec,
17934 unsigned int res)
17936 switch (res >> 26) {
17937 case ALC880_HP_EVENT:
17938 alc663_two_hp_m7_speaker_automute(codec);
17939 break;
17940 case ALC880_MIC_EVENT:
17941 alc_mic_automute(codec);
17942 break;
17946 #define alc663_mode7_setup alc663_mode1_setup
17948 static void alc663_mode7_inithook(struct hda_codec *codec)
17950 alc663_two_hp_m7_speaker_automute(codec);
17951 alc_mic_automute(codec);
17954 /* ***************** Mode8 ******************************/
17955 static void alc663_mode8_unsol_event(struct hda_codec *codec,
17956 unsigned int res)
17958 switch (res >> 26) {
17959 case ALC880_HP_EVENT:
17960 alc663_two_hp_m8_speaker_automute(codec);
17961 break;
17962 case ALC880_MIC_EVENT:
17963 alc_mic_automute(codec);
17964 break;
17968 #define alc663_mode8_setup alc663_m51va_setup
17970 static void alc663_mode8_inithook(struct hda_codec *codec)
17972 alc663_two_hp_m8_speaker_automute(codec);
17973 alc_mic_automute(codec);
17976 static void alc663_g71v_hp_automute(struct hda_codec *codec)
17978 unsigned int present;
17979 unsigned char bits;
17981 present = snd_hda_jack_detect(codec, 0x21);
17982 bits = present ? HDA_AMP_MUTE : 0;
17983 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17984 HDA_AMP_MUTE, bits);
17985 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17986 HDA_AMP_MUTE, bits);
17989 static void alc663_g71v_front_automute(struct hda_codec *codec)
17991 unsigned int present;
17992 unsigned char bits;
17994 present = snd_hda_jack_detect(codec, 0x15);
17995 bits = present ? HDA_AMP_MUTE : 0;
17996 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17997 HDA_AMP_MUTE, bits);
18000 static void alc663_g71v_unsol_event(struct hda_codec *codec,
18001 unsigned int res)
18003 switch (res >> 26) {
18004 case ALC880_HP_EVENT:
18005 alc663_g71v_hp_automute(codec);
18006 break;
18007 case ALC880_FRONT_EVENT:
18008 alc663_g71v_front_automute(codec);
18009 break;
18010 case ALC880_MIC_EVENT:
18011 alc_mic_automute(codec);
18012 break;
18016 #define alc663_g71v_setup alc663_m51va_setup
18018 static void alc663_g71v_inithook(struct hda_codec *codec)
18020 alc663_g71v_front_automute(codec);
18021 alc663_g71v_hp_automute(codec);
18022 alc_mic_automute(codec);
18025 static void alc663_g50v_unsol_event(struct hda_codec *codec,
18026 unsigned int res)
18028 switch (res >> 26) {
18029 case ALC880_HP_EVENT:
18030 alc663_m51va_speaker_automute(codec);
18031 break;
18032 case ALC880_MIC_EVENT:
18033 alc_mic_automute(codec);
18034 break;
18038 #define alc663_g50v_setup alc663_m51va_setup
18040 static void alc663_g50v_inithook(struct hda_codec *codec)
18042 alc663_m51va_speaker_automute(codec);
18043 alc_mic_automute(codec);
18046 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18047 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18048 ALC262_HIPPO_MASTER_SWITCH,
18050 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
18051 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18052 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18054 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
18055 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18056 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18057 { } /* end */
18060 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18061 /* Master Playback automatically created from Speaker and Headphone */
18062 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18063 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18064 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18067 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18068 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18069 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
18071 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18072 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18073 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
18074 { } /* end */
18077 #ifdef CONFIG_SND_HDA_POWER_SAVE
18078 #define alc662_loopbacks alc880_loopbacks
18079 #endif
18082 /* pcm configuration: identical with ALC880 */
18083 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18084 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18085 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18086 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18089 * configuration and preset
18091 static const char *alc662_models[ALC662_MODEL_LAST] = {
18092 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18093 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18094 [ALC662_3ST_6ch] = "3stack-6ch",
18095 [ALC662_5ST_DIG] = "6stack-dig",
18096 [ALC662_LENOVO_101E] = "lenovo-101e",
18097 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18098 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18099 [ALC662_ECS] = "ecs",
18100 [ALC663_ASUS_M51VA] = "m51va",
18101 [ALC663_ASUS_G71V] = "g71v",
18102 [ALC663_ASUS_H13] = "h13",
18103 [ALC663_ASUS_G50V] = "g50v",
18104 [ALC663_ASUS_MODE1] = "asus-mode1",
18105 [ALC662_ASUS_MODE2] = "asus-mode2",
18106 [ALC663_ASUS_MODE3] = "asus-mode3",
18107 [ALC663_ASUS_MODE4] = "asus-mode4",
18108 [ALC663_ASUS_MODE5] = "asus-mode5",
18109 [ALC663_ASUS_MODE6] = "asus-mode6",
18110 [ALC663_ASUS_MODE7] = "asus-mode7",
18111 [ALC663_ASUS_MODE8] = "asus-mode8",
18112 [ALC272_DELL] = "dell",
18113 [ALC272_DELL_ZM1] = "dell-zm1",
18114 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18115 [ALC662_AUTO] = "auto",
18118 static struct snd_pci_quirk alc662_cfg_tbl[] = {
18119 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18120 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18121 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18122 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18123 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18124 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18125 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18126 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18127 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18128 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18129 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18130 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18131 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18132 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18133 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18134 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18135 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18136 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18137 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18138 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18139 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18140 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18141 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18142 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18143 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18144 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18145 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18146 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18147 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18148 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18149 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18150 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18151 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18152 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18153 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18154 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18155 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18156 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18157 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18158 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18159 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18160 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18161 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18162 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18163 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18164 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18165 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18166 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18167 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18168 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18169 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18170 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18171 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18172 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18173 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18174 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18175 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18176 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18177 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18178 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18179 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18180 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18181 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18182 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18183 ALC662_3ST_6ch_DIG),
18184 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18185 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18186 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18187 ALC662_3ST_6ch_DIG),
18188 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18189 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18190 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18191 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18192 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18193 ALC662_3ST_6ch_DIG),
18194 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18195 ALC663_ASUS_H13),
18199 static struct alc_config_preset alc662_presets[] = {
18200 [ALC662_3ST_2ch_DIG] = {
18201 .mixers = { alc662_3ST_2ch_mixer },
18202 .init_verbs = { alc662_init_verbs },
18203 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18204 .dac_nids = alc662_dac_nids,
18205 .dig_out_nid = ALC662_DIGOUT_NID,
18206 .dig_in_nid = ALC662_DIGIN_NID,
18207 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18208 .channel_mode = alc662_3ST_2ch_modes,
18209 .input_mux = &alc662_capture_source,
18211 [ALC662_3ST_6ch_DIG] = {
18212 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18213 .init_verbs = { alc662_init_verbs },
18214 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18215 .dac_nids = alc662_dac_nids,
18216 .dig_out_nid = ALC662_DIGOUT_NID,
18217 .dig_in_nid = ALC662_DIGIN_NID,
18218 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18219 .channel_mode = alc662_3ST_6ch_modes,
18220 .need_dac_fix = 1,
18221 .input_mux = &alc662_capture_source,
18223 [ALC662_3ST_6ch] = {
18224 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18225 .init_verbs = { alc662_init_verbs },
18226 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18227 .dac_nids = alc662_dac_nids,
18228 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18229 .channel_mode = alc662_3ST_6ch_modes,
18230 .need_dac_fix = 1,
18231 .input_mux = &alc662_capture_source,
18233 [ALC662_5ST_DIG] = {
18234 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18235 .init_verbs = { alc662_init_verbs },
18236 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18237 .dac_nids = alc662_dac_nids,
18238 .dig_out_nid = ALC662_DIGOUT_NID,
18239 .dig_in_nid = ALC662_DIGIN_NID,
18240 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18241 .channel_mode = alc662_5stack_modes,
18242 .input_mux = &alc662_capture_source,
18244 [ALC662_LENOVO_101E] = {
18245 .mixers = { alc662_lenovo_101e_mixer },
18246 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18247 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18248 .dac_nids = alc662_dac_nids,
18249 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18250 .channel_mode = alc662_3ST_2ch_modes,
18251 .input_mux = &alc662_lenovo_101e_capture_source,
18252 .unsol_event = alc662_lenovo_101e_unsol_event,
18253 .init_hook = alc662_lenovo_101e_all_automute,
18255 [ALC662_ASUS_EEEPC_P701] = {
18256 .mixers = { alc662_eeepc_p701_mixer },
18257 .init_verbs = { alc662_init_verbs,
18258 alc662_eeepc_sue_init_verbs },
18259 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18260 .dac_nids = alc662_dac_nids,
18261 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18262 .channel_mode = alc662_3ST_2ch_modes,
18263 .unsol_event = alc662_eeepc_unsol_event,
18264 .setup = alc662_eeepc_setup,
18265 .init_hook = alc662_eeepc_inithook,
18267 [ALC662_ASUS_EEEPC_EP20] = {
18268 .mixers = { alc662_eeepc_ep20_mixer,
18269 alc662_chmode_mixer },
18270 .init_verbs = { alc662_init_verbs,
18271 alc662_eeepc_ep20_sue_init_verbs },
18272 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18273 .dac_nids = alc662_dac_nids,
18274 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18275 .channel_mode = alc662_3ST_6ch_modes,
18276 .input_mux = &alc662_lenovo_101e_capture_source,
18277 .unsol_event = alc662_eeepc_unsol_event,
18278 .setup = alc662_eeepc_ep20_setup,
18279 .init_hook = alc662_eeepc_ep20_inithook,
18281 [ALC662_ECS] = {
18282 .mixers = { alc662_ecs_mixer },
18283 .init_verbs = { alc662_init_verbs,
18284 alc662_ecs_init_verbs },
18285 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18286 .dac_nids = alc662_dac_nids,
18287 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18288 .channel_mode = alc662_3ST_2ch_modes,
18289 .unsol_event = alc662_eeepc_unsol_event,
18290 .setup = alc662_eeepc_setup,
18291 .init_hook = alc662_eeepc_inithook,
18293 [ALC663_ASUS_M51VA] = {
18294 .mixers = { alc663_m51va_mixer },
18295 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18296 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
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_m51va_unsol_event,
18302 .setup = alc663_m51va_setup,
18303 .init_hook = alc663_m51va_inithook,
18305 [ALC663_ASUS_G71V] = {
18306 .mixers = { alc663_g71v_mixer },
18307 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18308 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18309 .dac_nids = alc662_dac_nids,
18310 .dig_out_nid = ALC662_DIGOUT_NID,
18311 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18312 .channel_mode = alc662_3ST_2ch_modes,
18313 .unsol_event = alc663_g71v_unsol_event,
18314 .setup = alc663_g71v_setup,
18315 .init_hook = alc663_g71v_inithook,
18317 [ALC663_ASUS_H13] = {
18318 .mixers = { alc663_m51va_mixer },
18319 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18320 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18321 .dac_nids = alc662_dac_nids,
18322 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18323 .channel_mode = alc662_3ST_2ch_modes,
18324 .unsol_event = alc663_m51va_unsol_event,
18325 .init_hook = alc663_m51va_inithook,
18327 [ALC663_ASUS_G50V] = {
18328 .mixers = { alc663_g50v_mixer },
18329 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18330 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18331 .dac_nids = alc662_dac_nids,
18332 .dig_out_nid = ALC662_DIGOUT_NID,
18333 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18334 .channel_mode = alc662_3ST_6ch_modes,
18335 .input_mux = &alc663_capture_source,
18336 .unsol_event = alc663_g50v_unsol_event,
18337 .setup = alc663_g50v_setup,
18338 .init_hook = alc663_g50v_inithook,
18340 [ALC663_ASUS_MODE1] = {
18341 .mixers = { alc663_m51va_mixer },
18342 .cap_mixer = alc662_auto_capture_mixer,
18343 .init_verbs = { alc662_init_verbs,
18344 alc663_21jd_amic_init_verbs },
18345 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18346 .hp_nid = 0x03,
18347 .dac_nids = alc662_dac_nids,
18348 .dig_out_nid = ALC662_DIGOUT_NID,
18349 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18350 .channel_mode = alc662_3ST_2ch_modes,
18351 .unsol_event = alc663_mode1_unsol_event,
18352 .setup = alc663_mode1_setup,
18353 .init_hook = alc663_mode1_inithook,
18355 [ALC662_ASUS_MODE2] = {
18356 .mixers = { alc662_1bjd_mixer },
18357 .cap_mixer = alc662_auto_capture_mixer,
18358 .init_verbs = { alc662_init_verbs,
18359 alc662_1bjd_amic_init_verbs },
18360 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18361 .dac_nids = alc662_dac_nids,
18362 .dig_out_nid = ALC662_DIGOUT_NID,
18363 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18364 .channel_mode = alc662_3ST_2ch_modes,
18365 .unsol_event = alc662_mode2_unsol_event,
18366 .setup = alc662_mode2_setup,
18367 .init_hook = alc662_mode2_inithook,
18369 [ALC663_ASUS_MODE3] = {
18370 .mixers = { alc663_two_hp_m1_mixer },
18371 .cap_mixer = alc662_auto_capture_mixer,
18372 .init_verbs = { alc662_init_verbs,
18373 alc663_two_hp_amic_m1_init_verbs },
18374 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18375 .hp_nid = 0x03,
18376 .dac_nids = alc662_dac_nids,
18377 .dig_out_nid = ALC662_DIGOUT_NID,
18378 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18379 .channel_mode = alc662_3ST_2ch_modes,
18380 .unsol_event = alc663_mode3_unsol_event,
18381 .setup = alc663_mode3_setup,
18382 .init_hook = alc663_mode3_inithook,
18384 [ALC663_ASUS_MODE4] = {
18385 .mixers = { alc663_asus_21jd_clfe_mixer },
18386 .cap_mixer = alc662_auto_capture_mixer,
18387 .init_verbs = { alc662_init_verbs,
18388 alc663_21jd_amic_init_verbs},
18389 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18390 .hp_nid = 0x03,
18391 .dac_nids = alc662_dac_nids,
18392 .dig_out_nid = ALC662_DIGOUT_NID,
18393 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18394 .channel_mode = alc662_3ST_2ch_modes,
18395 .unsol_event = alc663_mode4_unsol_event,
18396 .setup = alc663_mode4_setup,
18397 .init_hook = alc663_mode4_inithook,
18399 [ALC663_ASUS_MODE5] = {
18400 .mixers = { alc663_asus_15jd_clfe_mixer },
18401 .cap_mixer = alc662_auto_capture_mixer,
18402 .init_verbs = { alc662_init_verbs,
18403 alc663_15jd_amic_init_verbs },
18404 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18405 .hp_nid = 0x03,
18406 .dac_nids = alc662_dac_nids,
18407 .dig_out_nid = ALC662_DIGOUT_NID,
18408 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18409 .channel_mode = alc662_3ST_2ch_modes,
18410 .unsol_event = alc663_mode5_unsol_event,
18411 .setup = alc663_mode5_setup,
18412 .init_hook = alc663_mode5_inithook,
18414 [ALC663_ASUS_MODE6] = {
18415 .mixers = { alc663_two_hp_m2_mixer },
18416 .cap_mixer = alc662_auto_capture_mixer,
18417 .init_verbs = { alc662_init_verbs,
18418 alc663_two_hp_amic_m2_init_verbs },
18419 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18420 .hp_nid = 0x03,
18421 .dac_nids = alc662_dac_nids,
18422 .dig_out_nid = ALC662_DIGOUT_NID,
18423 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18424 .channel_mode = alc662_3ST_2ch_modes,
18425 .unsol_event = alc663_mode6_unsol_event,
18426 .setup = alc663_mode6_setup,
18427 .init_hook = alc663_mode6_inithook,
18429 [ALC663_ASUS_MODE7] = {
18430 .mixers = { alc663_mode7_mixer },
18431 .cap_mixer = alc662_auto_capture_mixer,
18432 .init_verbs = { alc662_init_verbs,
18433 alc663_mode7_init_verbs },
18434 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18435 .hp_nid = 0x03,
18436 .dac_nids = alc662_dac_nids,
18437 .dig_out_nid = ALC662_DIGOUT_NID,
18438 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18439 .channel_mode = alc662_3ST_2ch_modes,
18440 .unsol_event = alc663_mode7_unsol_event,
18441 .setup = alc663_mode7_setup,
18442 .init_hook = alc663_mode7_inithook,
18444 [ALC663_ASUS_MODE8] = {
18445 .mixers = { alc663_mode8_mixer },
18446 .cap_mixer = alc662_auto_capture_mixer,
18447 .init_verbs = { alc662_init_verbs,
18448 alc663_mode8_init_verbs },
18449 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18450 .hp_nid = 0x03,
18451 .dac_nids = alc662_dac_nids,
18452 .dig_out_nid = ALC662_DIGOUT_NID,
18453 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18454 .channel_mode = alc662_3ST_2ch_modes,
18455 .unsol_event = alc663_mode8_unsol_event,
18456 .setup = alc663_mode8_setup,
18457 .init_hook = alc663_mode8_inithook,
18459 [ALC272_DELL] = {
18460 .mixers = { alc663_m51va_mixer },
18461 .cap_mixer = alc272_auto_capture_mixer,
18462 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18463 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18464 .dac_nids = alc662_dac_nids,
18465 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18466 .adc_nids = alc272_adc_nids,
18467 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18468 .capsrc_nids = alc272_capsrc_nids,
18469 .channel_mode = alc662_3ST_2ch_modes,
18470 .unsol_event = alc663_m51va_unsol_event,
18471 .setup = alc663_m51va_setup,
18472 .init_hook = alc663_m51va_inithook,
18474 [ALC272_DELL_ZM1] = {
18475 .mixers = { alc663_m51va_mixer },
18476 .cap_mixer = alc662_auto_capture_mixer,
18477 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18478 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18479 .dac_nids = alc662_dac_nids,
18480 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18481 .adc_nids = alc662_adc_nids,
18482 .num_adc_nids = 1,
18483 .capsrc_nids = alc662_capsrc_nids,
18484 .channel_mode = alc662_3ST_2ch_modes,
18485 .unsol_event = alc663_m51va_unsol_event,
18486 .setup = alc663_m51va_setup,
18487 .init_hook = alc663_m51va_inithook,
18489 [ALC272_SAMSUNG_NC10] = {
18490 .mixers = { alc272_nc10_mixer },
18491 .init_verbs = { alc662_init_verbs,
18492 alc663_21jd_amic_init_verbs },
18493 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18494 .dac_nids = alc272_dac_nids,
18495 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18496 .channel_mode = alc662_3ST_2ch_modes,
18497 /*.input_mux = &alc272_nc10_capture_source,*/
18498 .unsol_event = alc663_mode4_unsol_event,
18499 .setup = alc663_mode4_setup,
18500 .init_hook = alc663_mode4_inithook,
18506 * BIOS auto configuration
18509 /* convert from MIX nid to DAC */
18510 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18512 if (nid == 0x0f)
18513 return 0x02;
18514 else if (nid >= 0x0c && nid <= 0x0e)
18515 return nid - 0x0c + 0x02;
18516 else
18517 return 0;
18520 /* get MIX nid connected to the given pin targeted to DAC */
18521 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18522 hda_nid_t dac)
18524 hda_nid_t mix[4];
18525 int i, num;
18527 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18528 for (i = 0; i < num; i++) {
18529 if (alc662_mix_to_dac(mix[i]) == dac)
18530 return mix[i];
18532 return 0;
18535 /* look for an empty DAC slot */
18536 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18538 struct alc_spec *spec = codec->spec;
18539 hda_nid_t srcs[5];
18540 int i, j, num;
18542 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18543 if (num < 0)
18544 return 0;
18545 for (i = 0; i < num; i++) {
18546 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18547 if (!nid)
18548 continue;
18549 for (j = 0; j < spec->multiout.num_dacs; j++)
18550 if (spec->multiout.dac_nids[j] == nid)
18551 break;
18552 if (j >= spec->multiout.num_dacs)
18553 return nid;
18555 return 0;
18558 /* fill in the dac_nids table from the parsed pin configuration */
18559 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18560 const struct auto_pin_cfg *cfg)
18562 struct alc_spec *spec = codec->spec;
18563 int i;
18564 hda_nid_t dac;
18566 spec->multiout.dac_nids = spec->private_dac_nids;
18567 for (i = 0; i < cfg->line_outs; i++) {
18568 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18569 if (!dac)
18570 continue;
18571 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18573 return 0;
18576 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18577 hda_nid_t nid, unsigned int chs)
18579 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
18580 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18583 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18584 hda_nid_t nid, unsigned int chs)
18586 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18587 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18590 #define alc662_add_stereo_vol(spec, pfx, nid) \
18591 alc662_add_vol_ctl(spec, pfx, nid, 3)
18592 #define alc662_add_stereo_sw(spec, pfx, nid) \
18593 alc662_add_sw_ctl(spec, pfx, nid, 3)
18595 /* add playback controls from the parsed DAC table */
18596 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18597 const struct auto_pin_cfg *cfg)
18599 struct alc_spec *spec = codec->spec;
18600 static const char *chname[4] = {
18601 "Front", "Surround", NULL /*CLFE*/, "Side"
18603 hda_nid_t nid, mix;
18604 int i, err;
18606 for (i = 0; i < cfg->line_outs; i++) {
18607 nid = spec->multiout.dac_nids[i];
18608 if (!nid)
18609 continue;
18610 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18611 if (!mix)
18612 continue;
18613 if (i == 2) {
18614 /* Center/LFE */
18615 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18616 if (err < 0)
18617 return err;
18618 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
18619 if (err < 0)
18620 return err;
18621 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
18622 if (err < 0)
18623 return err;
18624 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
18625 if (err < 0)
18626 return err;
18627 } else {
18628 const char *pfx;
18629 if (cfg->line_outs == 1 &&
18630 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
18631 if (cfg->hp_outs)
18632 pfx = "Speaker";
18633 else
18634 pfx = "PCM";
18635 } else
18636 pfx = chname[i];
18637 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18638 if (err < 0)
18639 return err;
18640 if (cfg->line_outs == 1 &&
18641 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18642 pfx = "Speaker";
18643 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18644 if (err < 0)
18645 return err;
18648 return 0;
18651 /* add playback controls for speaker and HP outputs */
18652 /* return DAC nid if any new DAC is assigned */
18653 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18654 const char *pfx)
18656 struct alc_spec *spec = codec->spec;
18657 hda_nid_t nid, mix;
18658 int err;
18660 if (!pin)
18661 return 0;
18662 nid = alc662_look_for_dac(codec, pin);
18663 if (!nid) {
18664 /* the corresponding DAC is already occupied */
18665 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18666 return 0; /* no way */
18667 /* create a switch only */
18668 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18669 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18672 mix = alc662_dac_to_mix(codec, pin, nid);
18673 if (!mix)
18674 return 0;
18675 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18676 if (err < 0)
18677 return err;
18678 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18679 if (err < 0)
18680 return err;
18681 return nid;
18684 /* create playback/capture controls for input pins */
18685 #define alc662_auto_create_input_ctls \
18686 alc882_auto_create_input_ctls
18688 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18689 hda_nid_t nid, int pin_type,
18690 hda_nid_t dac)
18692 int i, num;
18693 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18695 alc_set_pin_output(codec, nid, pin_type);
18696 /* need the manual connection? */
18697 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18698 if (num <= 1)
18699 return;
18700 for (i = 0; i < num; i++) {
18701 if (alc662_mix_to_dac(srcs[i]) != dac)
18702 continue;
18703 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18704 return;
18708 static void alc662_auto_init_multi_out(struct hda_codec *codec)
18710 struct alc_spec *spec = codec->spec;
18711 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18712 int i;
18714 for (i = 0; i <= HDA_SIDE; i++) {
18715 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18716 if (nid)
18717 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
18718 spec->multiout.dac_nids[i]);
18722 static void alc662_auto_init_hp_out(struct hda_codec *codec)
18724 struct alc_spec *spec = codec->spec;
18725 hda_nid_t pin;
18727 pin = spec->autocfg.hp_pins[0];
18728 if (pin)
18729 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18730 spec->multiout.hp_nid);
18731 pin = spec->autocfg.speaker_pins[0];
18732 if (pin)
18733 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18734 spec->multiout.extra_out_nid[0]);
18737 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18739 static void alc662_auto_init_analog_input(struct hda_codec *codec)
18741 struct alc_spec *spec = codec->spec;
18742 int i;
18744 for (i = 0; i < AUTO_PIN_LAST; i++) {
18745 hda_nid_t nid = spec->autocfg.input_pins[i];
18746 if (alc_is_input_pin(codec, nid)) {
18747 alc_set_input_pin(codec, nid, i);
18748 if (nid != ALC662_PIN_CD_NID &&
18749 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
18750 snd_hda_codec_write(codec, nid, 0,
18751 AC_VERB_SET_AMP_GAIN_MUTE,
18752 AMP_OUT_MUTE);
18757 #define alc662_auto_init_input_src alc882_auto_init_input_src
18759 static int alc662_parse_auto_config(struct hda_codec *codec)
18761 struct alc_spec *spec = codec->spec;
18762 int err;
18763 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18765 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18766 alc662_ignore);
18767 if (err < 0)
18768 return err;
18769 if (!spec->autocfg.line_outs)
18770 return 0; /* can't find valid BIOS pin config */
18772 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
18773 if (err < 0)
18774 return err;
18775 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
18776 if (err < 0)
18777 return err;
18778 err = alc662_auto_create_extra_out(codec,
18779 spec->autocfg.speaker_pins[0],
18780 "Speaker");
18781 if (err < 0)
18782 return err;
18783 if (err)
18784 spec->multiout.extra_out_nid[0] = err;
18785 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18786 "Headphone");
18787 if (err < 0)
18788 return err;
18789 if (err)
18790 spec->multiout.hp_nid = err;
18791 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
18792 if (err < 0)
18793 return err;
18795 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18797 alc_auto_parse_digital(codec);
18799 if (spec->kctls.list)
18800 add_mixer(spec, spec->kctls.list);
18802 spec->num_mux_defs = 1;
18803 spec->input_mux = &spec->private_imux[0];
18805 add_verb(spec, alc662_init_verbs);
18806 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18807 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18808 add_verb(spec, alc663_init_verbs);
18810 if (codec->vendor_id == 0x10ec0272)
18811 add_verb(spec, alc272_init_verbs);
18813 err = alc_auto_add_mic_boost(codec);
18814 if (err < 0)
18815 return err;
18817 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18818 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18819 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18820 else
18821 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18823 return 1;
18826 /* additional initialization for auto-configuration model */
18827 static void alc662_auto_init(struct hda_codec *codec)
18829 struct alc_spec *spec = codec->spec;
18830 alc662_auto_init_multi_out(codec);
18831 alc662_auto_init_hp_out(codec);
18832 alc662_auto_init_analog_input(codec);
18833 alc662_auto_init_input_src(codec);
18834 alc_auto_init_digital(codec);
18835 if (spec->unsol_event)
18836 alc_inithook(codec);
18839 static int patch_alc662(struct hda_codec *codec)
18841 struct alc_spec *spec;
18842 int err, board_config;
18844 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18845 if (!spec)
18846 return -ENOMEM;
18848 codec->spec = spec;
18850 alc_auto_parse_customize_define(codec);
18852 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18854 if (alc_read_coef_idx(codec, 0) == 0x8020)
18855 alc_codec_rename(codec, "ALC661");
18856 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18857 codec->bus->pci->subsystem_vendor == 0x1025 &&
18858 spec->cdefine.platform_type == 1)
18859 alc_codec_rename(codec, "ALC272X");
18861 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18862 alc662_models,
18863 alc662_cfg_tbl);
18864 if (board_config < 0) {
18865 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18866 codec->chip_name);
18867 board_config = ALC662_AUTO;
18870 if (board_config == ALC662_AUTO) {
18871 /* automatic parse from the BIOS config */
18872 err = alc662_parse_auto_config(codec);
18873 if (err < 0) {
18874 alc_free(codec);
18875 return err;
18876 } else if (!err) {
18877 printk(KERN_INFO
18878 "hda_codec: Cannot set up configuration "
18879 "from BIOS. Using base mode...\n");
18880 board_config = ALC662_3ST_2ch_DIG;
18884 if (has_cdefine_beep(codec)) {
18885 err = snd_hda_attach_beep_device(codec, 0x1);
18886 if (err < 0) {
18887 alc_free(codec);
18888 return err;
18892 if (board_config != ALC662_AUTO)
18893 setup_preset(codec, &alc662_presets[board_config]);
18895 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18896 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18898 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18899 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18901 if (!spec->adc_nids) {
18902 spec->adc_nids = alc662_adc_nids;
18903 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18905 if (!spec->capsrc_nids)
18906 spec->capsrc_nids = alc662_capsrc_nids;
18908 if (!spec->cap_mixer)
18909 set_capture_mixer(codec);
18911 if (has_cdefine_beep(codec)) {
18912 switch (codec->vendor_id) {
18913 case 0x10ec0662:
18914 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18915 break;
18916 case 0x10ec0272:
18917 case 0x10ec0663:
18918 case 0x10ec0665:
18919 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18920 break;
18921 case 0x10ec0273:
18922 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18923 break;
18926 spec->vmaster_nid = 0x02;
18928 codec->patch_ops = alc_patch_ops;
18929 if (board_config == ALC662_AUTO)
18930 spec->init_hook = alc662_auto_init;
18931 #ifdef CONFIG_SND_HDA_POWER_SAVE
18932 if (!spec->loopback.amplist)
18933 spec->loopback.amplist = alc662_loopbacks;
18934 #endif
18936 return 0;
18939 static int patch_alc888(struct hda_codec *codec)
18941 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18942 kfree(codec->chip_name);
18943 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18944 if (!codec->chip_name) {
18945 alc_free(codec);
18946 return -ENOMEM;
18948 return patch_alc662(codec);
18950 return patch_alc882(codec);
18954 * ALC680 support
18956 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18957 #define alc680_modes alc260_modes
18959 static hda_nid_t alc680_dac_nids[3] = {
18960 /* Lout1, Lout2, hp */
18961 0x02, 0x03, 0x04
18964 static hda_nid_t alc680_adc_nids[3] = {
18965 /* ADC0-2 */
18966 /* DMIC, MIC, Line-in*/
18967 0x07, 0x08, 0x09
18970 static struct snd_kcontrol_new alc680_base_mixer[] = {
18971 /* output mixer control */
18972 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
18973 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18974 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
18975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
18976 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
18980 static struct snd_kcontrol_new alc680_capture_mixer[] = {
18981 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
18982 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
18983 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
18984 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
18985 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
18986 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
18987 { } /* end */
18991 * generic initialization of ADC, input mixers and output mixers
18993 static struct hda_verb alc680_init_verbs[] = {
18994 /* Unmute DAC0-1 and set vol = 0 */
18995 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18996 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18997 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
18999 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19000 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
19001 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
19002 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
19003 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
19005 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19007 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19008 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19009 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19013 /* create input playback/capture controls for the given pin */
19014 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19015 const char *ctlname, int idx)
19017 hda_nid_t dac;
19018 int err;
19020 switch (nid) {
19021 case 0x14:
19022 dac = 0x02;
19023 break;
19024 case 0x15:
19025 dac = 0x03;
19026 break;
19027 case 0x16:
19028 dac = 0x04;
19029 break;
19030 default:
19031 return 0;
19033 if (spec->multiout.dac_nids[0] != dac &&
19034 spec->multiout.dac_nids[1] != dac) {
19035 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19036 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19037 HDA_OUTPUT));
19038 if (err < 0)
19039 return err;
19041 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19042 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19044 if (err < 0)
19045 return err;
19046 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19049 return 0;
19052 /* add playback controls from the parsed DAC table */
19053 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19054 const struct auto_pin_cfg *cfg)
19056 hda_nid_t nid;
19057 int err;
19059 spec->multiout.dac_nids = spec->private_dac_nids;
19061 nid = cfg->line_out_pins[0];
19062 if (nid) {
19063 const char *name;
19064 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19065 name = "Speaker";
19066 else
19067 name = "Front";
19068 err = alc680_new_analog_output(spec, nid, name, 0);
19069 if (err < 0)
19070 return err;
19073 nid = cfg->speaker_pins[0];
19074 if (nid) {
19075 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19076 if (err < 0)
19077 return err;
19079 nid = cfg->hp_pins[0];
19080 if (nid) {
19081 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19082 if (err < 0)
19083 return err;
19086 return 0;
19089 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19090 hda_nid_t nid, int pin_type)
19092 alc_set_pin_output(codec, nid, pin_type);
19095 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19097 struct alc_spec *spec = codec->spec;
19098 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19099 if (nid) {
19100 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19101 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19105 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19107 struct alc_spec *spec = codec->spec;
19108 hda_nid_t pin;
19110 pin = spec->autocfg.hp_pins[0];
19111 if (pin)
19112 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19113 pin = spec->autocfg.speaker_pins[0];
19114 if (pin)
19115 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19118 /* pcm configuration: identical with ALC880 */
19119 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19120 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19121 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19122 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19124 static struct hda_input_mux alc680_capture_source = {
19125 .num_items = 1,
19126 .items = {
19127 { "Mic", 0x0 },
19132 * BIOS auto configuration
19134 static int alc680_parse_auto_config(struct hda_codec *codec)
19136 struct alc_spec *spec = codec->spec;
19137 int err;
19138 static hda_nid_t alc680_ignore[] = { 0 };
19140 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19141 alc680_ignore);
19142 if (err < 0)
19143 return err;
19144 if (!spec->autocfg.line_outs) {
19145 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19146 spec->multiout.max_channels = 2;
19147 spec->no_analog = 1;
19148 goto dig_only;
19150 return 0; /* can't find valid BIOS pin config */
19152 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19153 if (err < 0)
19154 return err;
19156 spec->multiout.max_channels = 2;
19158 dig_only:
19159 /* digital only support output */
19160 alc_auto_parse_digital(codec);
19161 if (spec->kctls.list)
19162 add_mixer(spec, spec->kctls.list);
19164 add_verb(spec, alc680_init_verbs);
19165 spec->num_mux_defs = 1;
19166 spec->input_mux = &alc680_capture_source;
19168 err = alc_auto_add_mic_boost(codec);
19169 if (err < 0)
19170 return err;
19172 return 1;
19175 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19177 /* init callback for auto-configuration model -- overriding the default init */
19178 static void alc680_auto_init(struct hda_codec *codec)
19180 struct alc_spec *spec = codec->spec;
19181 alc680_auto_init_multi_out(codec);
19182 alc680_auto_init_hp_out(codec);
19183 alc680_auto_init_analog_input(codec);
19184 alc_auto_init_digital(codec);
19185 if (spec->unsol_event)
19186 alc_inithook(codec);
19190 * configuration and preset
19192 static const char *alc680_models[ALC680_MODEL_LAST] = {
19193 [ALC680_BASE] = "base",
19194 [ALC680_AUTO] = "auto",
19197 static struct snd_pci_quirk alc680_cfg_tbl[] = {
19198 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19202 static struct alc_config_preset alc680_presets[] = {
19203 [ALC680_BASE] = {
19204 .mixers = { alc680_base_mixer },
19205 .cap_mixer = alc680_capture_mixer,
19206 .init_verbs = { alc680_init_verbs },
19207 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19208 .dac_nids = alc680_dac_nids,
19209 .num_adc_nids = ARRAY_SIZE(alc680_adc_nids),
19210 .adc_nids = alc680_adc_nids,
19211 .hp_nid = 0x04,
19212 .dig_out_nid = ALC680_DIGOUT_NID,
19213 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19214 .channel_mode = alc680_modes,
19215 .input_mux = &alc680_capture_source,
19219 static int patch_alc680(struct hda_codec *codec)
19221 struct alc_spec *spec;
19222 int board_config;
19223 int err;
19225 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19226 if (spec == NULL)
19227 return -ENOMEM;
19229 codec->spec = spec;
19231 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19232 alc680_models,
19233 alc680_cfg_tbl);
19235 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19236 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19237 codec->chip_name);
19238 board_config = ALC680_AUTO;
19241 if (board_config == ALC680_AUTO) {
19242 /* automatic parse from the BIOS config */
19243 err = alc680_parse_auto_config(codec);
19244 if (err < 0) {
19245 alc_free(codec);
19246 return err;
19247 } else if (!err) {
19248 printk(KERN_INFO
19249 "hda_codec: Cannot set up configuration "
19250 "from BIOS. Using base mode...\n");
19251 board_config = ALC680_BASE;
19255 if (board_config != ALC680_AUTO)
19256 setup_preset(codec, &alc680_presets[board_config]);
19258 spec->stream_analog_playback = &alc680_pcm_analog_playback;
19259 spec->stream_analog_capture = &alc680_pcm_analog_capture;
19260 spec->stream_analog_alt_capture = &alc680_pcm_analog_alt_capture;
19261 spec->stream_digital_playback = &alc680_pcm_digital_playback;
19263 if (!spec->adc_nids) {
19264 spec->adc_nids = alc680_adc_nids;
19265 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19268 if (!spec->cap_mixer)
19269 set_capture_mixer(codec);
19271 spec->vmaster_nid = 0x02;
19273 codec->patch_ops = alc_patch_ops;
19274 if (board_config == ALC680_AUTO)
19275 spec->init_hook = alc680_auto_init;
19277 return 0;
19281 * patch entries
19283 static struct hda_codec_preset snd_hda_preset_realtek[] = {
19284 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
19285 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
19286 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
19287 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
19288 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
19289 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
19290 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
19291 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
19292 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
19293 .patch = patch_alc861 },
19294 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19295 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19296 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
19297 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
19298 .patch = patch_alc882 },
19299 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19300 .patch = patch_alc662 },
19301 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
19302 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
19303 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
19304 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
19305 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
19306 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
19307 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
19308 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
19309 .patch = patch_alc882 },
19310 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
19311 .patch = patch_alc882 },
19312 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
19313 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
19314 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
19315 .patch = patch_alc882 },
19316 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
19317 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
19318 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
19319 {} /* terminator */
19322 MODULE_ALIAS("snd-hda-codec-id:10ec*");
19324 MODULE_LICENSE("GPL");
19325 MODULE_DESCRIPTION("Realtek HD-audio codec");
19327 static struct hda_codec_preset_list realtek_list = {
19328 .preset = snd_hda_preset_realtek,
19329 .owner = THIS_MODULE,
19332 static int __init patch_realtek_init(void)
19334 return snd_hda_add_codec_preset(&realtek_list);
19337 static void __exit patch_realtek_exit(void)
19339 snd_hda_delete_codec_preset(&realtek_list);
19342 module_init(patch_realtek_init)
19343 module_exit(patch_realtek_exit)