Merge branch 'media_fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
[cris-mirror.git] / sound / pci / hda / patch_realtek.c
blobbe4df4c6fd56bd585ad79b64ddabf6b9344d0f3c
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 <sound/jack.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34 #include "hda_beep.h"
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
41 /* ALC880 board config type */
42 enum {
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
48 ALC880_Z71V,
49 ALC880_6ST,
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
55 ALC880_ASUS_DIG2,
56 ALC880_FUJITSU,
57 ALC880_UNIWILL_DIG,
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
62 ALC880_LG,
63 ALC880_LG_LW,
64 ALC880_MEDION_RIM,
65 #ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67 #endif
68 ALC880_AUTO,
69 ALC880_MODEL_LAST /* last tag */
72 /* ALC260 models */
73 enum {
74 ALC260_BASIC,
75 ALC260_HP,
76 ALC260_HP_DC7600,
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
79 ALC260_ACER,
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
82 ALC260_FAVORIT100,
83 #ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85 #endif
86 ALC260_AUTO,
87 ALC260_MODEL_LAST /* last tag */
90 /* ALC262 models */
91 enum {
92 ALC262_BASIC,
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
95 ALC262_FUJITSU,
96 ALC262_HP_BPC,
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
99 ALC262_HP_TC_T5735,
100 ALC262_HP_RP5700,
101 ALC262_BENQ_ED8,
102 ALC262_SONY_ASSAMD,
103 ALC262_BENQ_T31,
104 ALC262_ULTRA,
105 ALC262_LENOVO_3000,
106 ALC262_NEC,
107 ALC262_TOSHIBA_S06,
108 ALC262_TOSHIBA_RX1,
109 ALC262_TYAN,
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
114 /* ALC268 models */
115 enum {
116 ALC267_QUANTA_IL1,
117 ALC268_3ST,
118 ALC268_TOSHIBA,
119 ALC268_ACER,
120 ALC268_ACER_DMIC,
121 ALC268_ACER_ASPIRE_ONE,
122 ALC268_DELL,
123 ALC268_ZEPTO,
124 #ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126 #endif
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
131 /* ALC269 models */
132 enum {
133 ALC269_BASIC,
134 ALC269_QUANTA_FL1,
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
139 ALC269_FUJITSU,
140 ALC269_LIFEBOOK,
141 ALC271_ACER,
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
146 /* ALC861 models */
147 enum {
148 ALC861_3ST,
149 ALC660_3ST,
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
152 ALC861_UNIWILL_M31,
153 ALC861_TOSHIBA,
154 ALC861_ASUS,
155 ALC861_ASUS_LAPTOP,
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
160 /* ALC861-VD models */
161 enum {
162 ALC660VD_3ST,
163 ALC660VD_3ST_DIG,
164 ALC660VD_ASUS_V1S,
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
168 ALC861VD_LENOVO,
169 ALC861VD_DALLAS,
170 ALC861VD_HP,
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
175 /* ALC662 models */
176 enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
199 ALC272_SAMSUNG_NC10,
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
204 /* ALC882 models */
205 enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
208 ALC882_ARIMA,
209 ALC882_W2JC,
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
212 ALC882_ASUS_A7M,
213 ALC885_MACPRO,
214 ALC885_MBA21,
215 ALC885_MBP3,
216 ALC885_MB5,
217 ALC885_MACMINI3,
218 ALC885_IMAC24,
219 ALC885_IMAC91,
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
227 ALC883_ACER,
228 ALC883_ACER_ASPIRE,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION,
234 ALC883_MEDION_WIM2160,
235 ALC883_LAPTOP_EAPD,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
239 ALC888_LENOVO_SKY,
240 ALC883_HAIER_W66,
241 ALC888_3ST_HP,
242 ALC888_6ST_DELL,
243 ALC883_MITAC,
244 ALC883_CLEVO_M540R,
245 ALC883_CLEVO_M720,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
249 ALC889A_INTEL,
250 ALC889_INTEL,
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
253 ALC889A_MB31,
254 ALC1200_ASUS_P5Q,
255 ALC883_SONY_VAIO_TT,
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
260 /* ALC680 models */
261 enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
267 /* for GPIO Poll */
268 #define GPIO_MASK 0x03
270 /* extra amp-initialization sequence types */
271 enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
279 struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
285 struct alc_jack {
286 hda_nid_t nid;
287 int type;
288 struct snd_jack *jack;
291 #define MUX_IDX_UNDEF ((unsigned char)-1)
293 struct alc_customize_define {
294 unsigned int sku_cfg;
295 unsigned char port_connectivity;
296 unsigned char check_sum;
297 unsigned char customization;
298 unsigned char external_amp;
299 unsigned int enable_pcbeep:1;
300 unsigned int platform_type:1;
301 unsigned int swap:1;
302 unsigned int override:1;
303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
306 struct alc_fixup;
308 struct alc_spec {
309 /* codec parameterization */
310 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
311 unsigned int num_mixers;
312 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
313 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
315 const struct hda_verb *init_verbs[10]; /* initialization verbs
316 * don't forget NULL
317 * termination!
319 unsigned int num_init_verbs;
321 char stream_name_analog[32]; /* analog PCM stream */
322 struct hda_pcm_stream *stream_analog_playback;
323 struct hda_pcm_stream *stream_analog_capture;
324 struct hda_pcm_stream *stream_analog_alt_playback;
325 struct hda_pcm_stream *stream_analog_alt_capture;
327 char stream_name_digital[32]; /* digital PCM stream */
328 struct hda_pcm_stream *stream_digital_playback;
329 struct hda_pcm_stream *stream_digital_capture;
331 /* playback */
332 struct hda_multi_out multiout; /* playback set-up
333 * max_channels, dacs must be set
334 * dig_out_nid and hp_nid are optional
336 hda_nid_t alt_dac_nid;
337 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
338 int dig_out_type;
340 /* capture */
341 unsigned int num_adc_nids;
342 hda_nid_t *adc_nids;
343 hda_nid_t *capsrc_nids;
344 hda_nid_t dig_in_nid; /* digital-in NID; optional */
346 /* capture setup for dynamic dual-adc switch */
347 unsigned int cur_adc_idx;
348 hda_nid_t cur_adc;
349 unsigned int cur_adc_stream_tag;
350 unsigned int cur_adc_format;
352 /* capture source */
353 unsigned int num_mux_defs;
354 const struct hda_input_mux *input_mux;
355 unsigned int cur_mux[3];
356 struct alc_mic_route ext_mic;
357 struct alc_mic_route int_mic;
359 /* channel model */
360 const struct hda_channel_mode *channel_mode;
361 int num_channel_mode;
362 int need_dac_fix;
363 int const_channel_count;
364 int ext_channel_count;
366 /* PCM information */
367 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
369 /* jack detection */
370 struct snd_array jacks;
372 /* dynamic controls, init_verbs and input_mux */
373 struct auto_pin_cfg autocfg;
374 struct alc_customize_define cdefine;
375 struct snd_array kctls;
376 struct hda_input_mux private_imux[3];
377 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
378 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
379 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
381 /* hooks */
382 void (*init_hook)(struct hda_codec *codec);
383 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
384 #ifdef CONFIG_SND_HDA_POWER_SAVE
385 void (*power_hook)(struct hda_codec *codec);
386 #endif
388 /* for pin sensing */
389 unsigned int sense_updated: 1;
390 unsigned int jack_present: 1;
391 unsigned int master_sw: 1;
392 unsigned int auto_mic:1;
394 /* other flags */
395 unsigned int no_analog :1; /* digital I/O only */
396 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
397 int init_amp;
398 int codec_variant; /* flag for other variants */
400 /* for virtual master */
401 hda_nid_t vmaster_nid;
402 #ifdef CONFIG_SND_HDA_POWER_SAVE
403 struct hda_loopback_check loopback;
404 #endif
406 /* for PLL fix */
407 hda_nid_t pll_nid;
408 unsigned int pll_coef_idx, pll_coef_bit;
410 /* fix-up list */
411 int fixup_id;
412 const struct alc_fixup *fixup_list;
413 const char *fixup_name;
417 * configuration template - to be copied to the spec instance
419 struct alc_config_preset {
420 struct snd_kcontrol_new *mixers[5]; /* should be identical size
421 * with spec
423 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
424 const struct hda_verb *init_verbs[5];
425 unsigned int num_dacs;
426 hda_nid_t *dac_nids;
427 hda_nid_t dig_out_nid; /* optional */
428 hda_nid_t hp_nid; /* optional */
429 hda_nid_t *slave_dig_outs;
430 unsigned int num_adc_nids;
431 hda_nid_t *adc_nids;
432 hda_nid_t *capsrc_nids;
433 hda_nid_t dig_in_nid;
434 unsigned int num_channel_mode;
435 const struct hda_channel_mode *channel_mode;
436 int need_dac_fix;
437 int const_channel_count;
438 unsigned int num_mux_defs;
439 const struct hda_input_mux *input_mux;
440 void (*unsol_event)(struct hda_codec *, unsigned int);
441 void (*setup)(struct hda_codec *);
442 void (*init_hook)(struct hda_codec *);
443 #ifdef CONFIG_SND_HDA_POWER_SAVE
444 struct hda_amp_list *loopbacks;
445 void (*power_hook)(struct hda_codec *codec);
446 #endif
451 * input MUX handling
453 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_info *uinfo)
456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
457 struct alc_spec *spec = codec->spec;
458 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
459 if (mux_idx >= spec->num_mux_defs)
460 mux_idx = 0;
461 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
462 mux_idx = 0;
463 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
466 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 struct alc_spec *spec = codec->spec;
471 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
473 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
474 return 0;
477 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
478 struct snd_ctl_elem_value *ucontrol)
480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
481 struct alc_spec *spec = codec->spec;
482 const struct hda_input_mux *imux;
483 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
484 unsigned int mux_idx;
485 hda_nid_t nid = spec->capsrc_nids ?
486 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
487 unsigned int type;
489 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
490 imux = &spec->input_mux[mux_idx];
491 if (!imux->num_items && mux_idx > 0)
492 imux = &spec->input_mux[0];
494 type = get_wcaps_type(get_wcaps(codec, nid));
495 if (type == AC_WID_AUD_MIX) {
496 /* Matrix-mixer style (e.g. ALC882) */
497 unsigned int *cur_val = &spec->cur_mux[adc_idx];
498 unsigned int i, idx;
500 idx = ucontrol->value.enumerated.item[0];
501 if (idx >= imux->num_items)
502 idx = imux->num_items - 1;
503 if (*cur_val == idx)
504 return 0;
505 for (i = 0; i < imux->num_items; i++) {
506 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
507 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
508 imux->items[i].index,
509 HDA_AMP_MUTE, v);
511 *cur_val = idx;
512 return 1;
513 } else {
514 /* MUX style (e.g. ALC880) */
515 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
516 &spec->cur_mux[adc_idx]);
521 * channel mode setting
523 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
524 struct snd_ctl_elem_info *uinfo)
526 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
527 struct alc_spec *spec = codec->spec;
528 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
529 spec->num_channel_mode);
532 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_value *ucontrol)
535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
536 struct alc_spec *spec = codec->spec;
537 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
538 spec->num_channel_mode,
539 spec->ext_channel_count);
542 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
547 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
548 spec->num_channel_mode,
549 &spec->ext_channel_count);
550 if (err >= 0 && !spec->const_channel_count) {
551 spec->multiout.max_channels = spec->ext_channel_count;
552 if (spec->need_dac_fix)
553 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
555 return err;
559 * Control the mode of pin widget settings via the mixer. "pc" is used
560 * instead of "%" to avoid consequences of accidently treating the % as
561 * being part of a format specifier. Maximum allowed length of a value is
562 * 63 characters plus NULL terminator.
564 * Note: some retasking pin complexes seem to ignore requests for input
565 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
566 * are requested. Therefore order this list so that this behaviour will not
567 * cause problems when mixer clients move through the enum sequentially.
568 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
569 * March 2006.
571 static char *alc_pin_mode_names[] = {
572 "Mic 50pc bias", "Mic 80pc bias",
573 "Line in", "Line out", "Headphone out",
575 static unsigned char alc_pin_mode_values[] = {
576 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
578 /* The control can present all 5 options, or it can limit the options based
579 * in the pin being assumed to be exclusively an input or an output pin. In
580 * addition, "input" pins may or may not process the mic bias option
581 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
582 * accept requests for bias as of chip versions up to March 2006) and/or
583 * wiring in the computer.
585 #define ALC_PIN_DIR_IN 0x00
586 #define ALC_PIN_DIR_OUT 0x01
587 #define ALC_PIN_DIR_INOUT 0x02
588 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
589 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
591 /* Info about the pin modes supported by the different pin direction modes.
592 * For each direction the minimum and maximum values are given.
594 static signed char alc_pin_mode_dir_info[5][2] = {
595 { 0, 2 }, /* ALC_PIN_DIR_IN */
596 { 3, 4 }, /* ALC_PIN_DIR_OUT */
597 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
598 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
599 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
601 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
602 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
603 #define alc_pin_mode_n_items(_dir) \
604 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
606 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
607 struct snd_ctl_elem_info *uinfo)
609 unsigned int item_num = uinfo->value.enumerated.item;
610 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
612 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
613 uinfo->count = 1;
614 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
616 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
617 item_num = alc_pin_mode_min(dir);
618 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
619 return 0;
622 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
623 struct snd_ctl_elem_value *ucontrol)
625 unsigned int i;
626 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
627 hda_nid_t nid = kcontrol->private_value & 0xffff;
628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
629 long *valp = ucontrol->value.integer.value;
630 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
631 AC_VERB_GET_PIN_WIDGET_CONTROL,
632 0x00);
634 /* Find enumerated value for current pinctl setting */
635 i = alc_pin_mode_min(dir);
636 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
637 i++;
638 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
639 return 0;
642 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
645 signed int change;
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
649 long val = *ucontrol->value.integer.value;
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
652 0x00);
654 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
655 val = alc_pin_mode_min(dir);
657 change = pinctl != alc_pin_mode_values[val];
658 if (change) {
659 /* Set pin mode to that requested */
660 snd_hda_codec_write_cache(codec, nid, 0,
661 AC_VERB_SET_PIN_WIDGET_CONTROL,
662 alc_pin_mode_values[val]);
664 /* Also enable the retasking pin's input/output as required
665 * for the requested pin mode. Enum values of 2 or less are
666 * input modes.
668 * Dynamically switching the input/output buffers probably
669 * reduces noise slightly (particularly on input) so we'll
670 * do it. However, having both input and output buffers
671 * enabled simultaneously doesn't seem to be problematic if
672 * this turns out to be necessary in the future.
674 if (val <= 2) {
675 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
676 HDA_AMP_MUTE, HDA_AMP_MUTE);
677 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
678 HDA_AMP_MUTE, 0);
679 } else {
680 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
681 HDA_AMP_MUTE, HDA_AMP_MUTE);
682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
683 HDA_AMP_MUTE, 0);
686 return change;
689 #define ALC_PIN_MODE(xname, nid, dir) \
690 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
691 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
692 .info = alc_pin_mode_info, \
693 .get = alc_pin_mode_get, \
694 .put = alc_pin_mode_put, \
695 .private_value = nid | (dir<<16) }
697 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
698 * together using a mask with more than one bit set. This control is
699 * currently used only by the ALC260 test model. At this stage they are not
700 * needed for any "production" models.
702 #ifdef CONFIG_SND_DEBUG
703 #define alc_gpio_data_info snd_ctl_boolean_mono_info
705 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
709 hda_nid_t nid = kcontrol->private_value & 0xffff;
710 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
711 long *valp = ucontrol->value.integer.value;
712 unsigned int val = snd_hda_codec_read(codec, nid, 0,
713 AC_VERB_GET_GPIO_DATA, 0x00);
715 *valp = (val & mask) != 0;
716 return 0;
718 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
721 signed int change;
722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
723 hda_nid_t nid = kcontrol->private_value & 0xffff;
724 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
725 long val = *ucontrol->value.integer.value;
726 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
727 AC_VERB_GET_GPIO_DATA,
728 0x00);
730 /* Set/unset the masked GPIO bit(s) as needed */
731 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
732 if (val == 0)
733 gpio_data &= ~mask;
734 else
735 gpio_data |= mask;
736 snd_hda_codec_write_cache(codec, nid, 0,
737 AC_VERB_SET_GPIO_DATA, gpio_data);
739 return change;
741 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
742 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
744 .info = alc_gpio_data_info, \
745 .get = alc_gpio_data_get, \
746 .put = alc_gpio_data_put, \
747 .private_value = nid | (mask<<16) }
748 #endif /* CONFIG_SND_DEBUG */
750 /* A switch control to allow the enabling of the digital IO pins on the
751 * ALC260. This is incredibly simplistic; the intention of this control is
752 * to provide something in the test model allowing digital outputs to be
753 * identified if present. If models are found which can utilise these
754 * outputs a more complete mixer control can be devised for those models if
755 * necessary.
757 #ifdef CONFIG_SND_DEBUG
758 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
760 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
761 struct snd_ctl_elem_value *ucontrol)
763 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
764 hda_nid_t nid = kcontrol->private_value & 0xffff;
765 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
766 long *valp = ucontrol->value.integer.value;
767 unsigned int val = snd_hda_codec_read(codec, nid, 0,
768 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
770 *valp = (val & mask) != 0;
771 return 0;
773 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
774 struct snd_ctl_elem_value *ucontrol)
776 signed int change;
777 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
778 hda_nid_t nid = kcontrol->private_value & 0xffff;
779 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
780 long val = *ucontrol->value.integer.value;
781 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
782 AC_VERB_GET_DIGI_CONVERT_1,
783 0x00);
785 /* Set/unset the masked control bit(s) as needed */
786 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
787 if (val==0)
788 ctrl_data &= ~mask;
789 else
790 ctrl_data |= mask;
791 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
792 ctrl_data);
794 return change;
796 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
798 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
799 .info = alc_spdif_ctrl_info, \
800 .get = alc_spdif_ctrl_get, \
801 .put = alc_spdif_ctrl_put, \
802 .private_value = nid | (mask<<16) }
803 #endif /* CONFIG_SND_DEBUG */
805 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
806 * Again, this is only used in the ALC26x test models to help identify when
807 * the EAPD line must be asserted for features to work.
809 #ifdef CONFIG_SND_DEBUG
810 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
812 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
813 struct snd_ctl_elem_value *ucontrol)
815 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
816 hda_nid_t nid = kcontrol->private_value & 0xffff;
817 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
818 long *valp = ucontrol->value.integer.value;
819 unsigned int val = snd_hda_codec_read(codec, nid, 0,
820 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
822 *valp = (val & mask) != 0;
823 return 0;
826 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
827 struct snd_ctl_elem_value *ucontrol)
829 int change;
830 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
831 hda_nid_t nid = kcontrol->private_value & 0xffff;
832 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
833 long val = *ucontrol->value.integer.value;
834 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
835 AC_VERB_GET_EAPD_BTLENABLE,
836 0x00);
838 /* Set/unset the masked control bit(s) as needed */
839 change = (!val ? 0 : mask) != (ctrl_data & mask);
840 if (!val)
841 ctrl_data &= ~mask;
842 else
843 ctrl_data |= mask;
844 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
845 ctrl_data);
847 return change;
850 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
851 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
852 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
853 .info = alc_eapd_ctrl_info, \
854 .get = alc_eapd_ctrl_get, \
855 .put = alc_eapd_ctrl_put, \
856 .private_value = nid | (mask<<16) }
857 #endif /* CONFIG_SND_DEBUG */
860 * set up the input pin config (depending on the given auto-pin type)
862 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
863 int auto_pin_type)
865 unsigned int val = PIN_IN;
867 if (auto_pin_type == AUTO_PIN_MIC) {
868 unsigned int pincap;
869 unsigned int oldval;
870 oldval = snd_hda_codec_read(codec, nid, 0,
871 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
872 pincap = snd_hda_query_pin_caps(codec, nid);
873 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
874 /* if the default pin setup is vref50, we give it priority */
875 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
876 val = PIN_VREF80;
877 else if (pincap & AC_PINCAP_VREF_50)
878 val = PIN_VREF50;
879 else if (pincap & AC_PINCAP_VREF_100)
880 val = PIN_VREF100;
881 else if (pincap & AC_PINCAP_VREF_GRD)
882 val = PIN_VREFGRD;
884 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
887 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
889 struct alc_spec *spec = codec->spec;
890 struct auto_pin_cfg *cfg = &spec->autocfg;
892 if (!cfg->line_outs) {
893 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
894 cfg->line_out_pins[cfg->line_outs])
895 cfg->line_outs++;
897 if (!cfg->speaker_outs) {
898 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
899 cfg->speaker_pins[cfg->speaker_outs])
900 cfg->speaker_outs++;
902 if (!cfg->hp_outs) {
903 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
904 cfg->hp_pins[cfg->hp_outs])
905 cfg->hp_outs++;
911 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
913 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
914 return;
915 spec->mixers[spec->num_mixers++] = mix;
918 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
920 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
921 return;
922 spec->init_verbs[spec->num_init_verbs++] = verb;
926 * set up from the preset table
928 static void setup_preset(struct hda_codec *codec,
929 const struct alc_config_preset *preset)
931 struct alc_spec *spec = codec->spec;
932 int i;
934 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
935 add_mixer(spec, preset->mixers[i]);
936 spec->cap_mixer = preset->cap_mixer;
937 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
938 i++)
939 add_verb(spec, preset->init_verbs[i]);
941 spec->channel_mode = preset->channel_mode;
942 spec->num_channel_mode = preset->num_channel_mode;
943 spec->need_dac_fix = preset->need_dac_fix;
944 spec->const_channel_count = preset->const_channel_count;
946 if (preset->const_channel_count)
947 spec->multiout.max_channels = preset->const_channel_count;
948 else
949 spec->multiout.max_channels = spec->channel_mode[0].channels;
950 spec->ext_channel_count = spec->channel_mode[0].channels;
952 spec->multiout.num_dacs = preset->num_dacs;
953 spec->multiout.dac_nids = preset->dac_nids;
954 spec->multiout.dig_out_nid = preset->dig_out_nid;
955 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
956 spec->multiout.hp_nid = preset->hp_nid;
958 spec->num_mux_defs = preset->num_mux_defs;
959 if (!spec->num_mux_defs)
960 spec->num_mux_defs = 1;
961 spec->input_mux = preset->input_mux;
963 spec->num_adc_nids = preset->num_adc_nids;
964 spec->adc_nids = preset->adc_nids;
965 spec->capsrc_nids = preset->capsrc_nids;
966 spec->dig_in_nid = preset->dig_in_nid;
968 spec->unsol_event = preset->unsol_event;
969 spec->init_hook = preset->init_hook;
970 #ifdef CONFIG_SND_HDA_POWER_SAVE
971 spec->power_hook = preset->power_hook;
972 spec->loopback.amplist = preset->loopbacks;
973 #endif
975 if (preset->setup)
976 preset->setup(codec);
978 alc_fixup_autocfg_pin_nums(codec);
981 /* Enable GPIO mask and set output */
982 static struct hda_verb alc_gpio1_init_verbs[] = {
983 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
984 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
985 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
989 static struct hda_verb alc_gpio2_init_verbs[] = {
990 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
991 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
992 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
996 static struct hda_verb alc_gpio3_init_verbs[] = {
997 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
998 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
999 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1004 * Fix hardware PLL issue
1005 * On some codecs, the analog PLL gating control must be off while
1006 * the default value is 1.
1008 static void alc_fix_pll(struct hda_codec *codec)
1010 struct alc_spec *spec = codec->spec;
1011 unsigned int val;
1013 if (!spec->pll_nid)
1014 return;
1015 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1016 spec->pll_coef_idx);
1017 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1018 AC_VERB_GET_PROC_COEF, 0);
1019 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1020 spec->pll_coef_idx);
1021 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1022 val & ~(1 << spec->pll_coef_bit));
1025 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1026 unsigned int coef_idx, unsigned int coef_bit)
1028 struct alc_spec *spec = codec->spec;
1029 spec->pll_nid = nid;
1030 spec->pll_coef_idx = coef_idx;
1031 spec->pll_coef_bit = coef_bit;
1032 alc_fix_pll(codec);
1035 #ifdef CONFIG_SND_HDA_INPUT_JACK
1036 static void alc_free_jack_priv(struct snd_jack *jack)
1038 struct alc_jack *jacks = jack->private_data;
1039 jacks->nid = 0;
1040 jacks->jack = NULL;
1043 static int alc_add_jack(struct hda_codec *codec,
1044 hda_nid_t nid, int type)
1046 struct alc_spec *spec;
1047 struct alc_jack *jack;
1048 const char *name;
1049 int err;
1051 spec = codec->spec;
1052 snd_array_init(&spec->jacks, sizeof(*jack), 32);
1053 jack = snd_array_new(&spec->jacks);
1054 if (!jack)
1055 return -ENOMEM;
1057 jack->nid = nid;
1058 jack->type = type;
1059 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
1061 err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
1062 if (err < 0)
1063 return err;
1064 jack->jack->private_data = jack;
1065 jack->jack->private_free = alc_free_jack_priv;
1066 return 0;
1069 static void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1071 struct alc_spec *spec = codec->spec;
1072 struct alc_jack *jacks = spec->jacks.list;
1074 if (jacks) {
1075 int i;
1076 for (i = 0; i < spec->jacks.used; i++) {
1077 if (jacks->nid == nid) {
1078 unsigned int present;
1079 present = snd_hda_jack_detect(codec, nid);
1081 present = (present) ? jacks->type : 0;
1083 snd_jack_report(jacks->jack, present);
1085 jacks++;
1090 static int alc_init_jacks(struct hda_codec *codec)
1092 struct alc_spec *spec = codec->spec;
1093 int err;
1094 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1095 unsigned int mic_nid = spec->ext_mic.pin;
1097 if (hp_nid) {
1098 err = alc_add_jack(codec, hp_nid, SND_JACK_HEADPHONE);
1099 if (err < 0)
1100 return err;
1101 alc_report_jack(codec, hp_nid);
1104 if (mic_nid) {
1105 err = alc_add_jack(codec, mic_nid, SND_JACK_MICROPHONE);
1106 if (err < 0)
1107 return err;
1108 alc_report_jack(codec, mic_nid);
1111 return 0;
1113 #else
1114 static inline void alc_report_jack(struct hda_codec *codec, hda_nid_t nid)
1118 static inline int alc_init_jacks(struct hda_codec *codec)
1120 return 0;
1122 #endif
1124 static void alc_automute_speaker(struct hda_codec *codec, int pinctl)
1126 struct alc_spec *spec = codec->spec;
1127 unsigned int mute;
1128 hda_nid_t nid;
1129 int i;
1131 spec->jack_present = 0;
1132 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1133 nid = spec->autocfg.hp_pins[i];
1134 if (!nid)
1135 break;
1136 if (snd_hda_jack_detect(codec, nid)) {
1137 spec->jack_present = 1;
1138 break;
1140 alc_report_jack(codec, spec->autocfg.hp_pins[i]);
1143 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1144 /* Toggle internal speakers muting */
1145 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1146 nid = spec->autocfg.speaker_pins[i];
1147 if (!nid)
1148 break;
1149 if (pinctl) {
1150 snd_hda_codec_write(codec, nid, 0,
1151 AC_VERB_SET_PIN_WIDGET_CONTROL,
1152 spec->jack_present ? 0 : PIN_OUT);
1153 } else {
1154 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1155 HDA_AMP_MUTE, mute);
1160 static void alc_automute_pin(struct hda_codec *codec)
1162 alc_automute_speaker(codec, 1);
1165 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1166 hda_nid_t nid)
1168 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1169 int i, nums;
1171 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1172 for (i = 0; i < nums; i++)
1173 if (conn[i] == nid)
1174 return i;
1175 return -1;
1178 /* switch the current ADC according to the jack state */
1179 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1181 struct alc_spec *spec = codec->spec;
1182 unsigned int present;
1183 hda_nid_t new_adc;
1185 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1186 if (present)
1187 spec->cur_adc_idx = 1;
1188 else
1189 spec->cur_adc_idx = 0;
1190 new_adc = spec->adc_nids[spec->cur_adc_idx];
1191 if (spec->cur_adc && spec->cur_adc != new_adc) {
1192 /* stream is running, let's swap the current ADC */
1193 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1194 spec->cur_adc = new_adc;
1195 snd_hda_codec_setup_stream(codec, new_adc,
1196 spec->cur_adc_stream_tag, 0,
1197 spec->cur_adc_format);
1201 static void alc_mic_automute(struct hda_codec *codec)
1203 struct alc_spec *spec = codec->spec;
1204 struct alc_mic_route *dead, *alive;
1205 unsigned int present, type;
1206 hda_nid_t cap_nid;
1208 if (!spec->auto_mic)
1209 return;
1210 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1211 return;
1212 if (snd_BUG_ON(!spec->adc_nids))
1213 return;
1215 if (spec->dual_adc_switch) {
1216 alc_dual_mic_adc_auto_switch(codec);
1217 return;
1220 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1222 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1223 if (present) {
1224 alive = &spec->ext_mic;
1225 dead = &spec->int_mic;
1226 } else {
1227 alive = &spec->int_mic;
1228 dead = &spec->ext_mic;
1231 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1232 if (type == AC_WID_AUD_MIX) {
1233 /* Matrix-mixer style (e.g. ALC882) */
1234 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1235 alive->mux_idx,
1236 HDA_AMP_MUTE, 0);
1237 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1238 dead->mux_idx,
1239 HDA_AMP_MUTE, HDA_AMP_MUTE);
1240 } else {
1241 /* MUX style (e.g. ALC880) */
1242 snd_hda_codec_write_cache(codec, cap_nid, 0,
1243 AC_VERB_SET_CONNECT_SEL,
1244 alive->mux_idx);
1246 alc_report_jack(codec, spec->ext_mic.pin);
1248 /* FIXME: analog mixer */
1251 /* unsolicited event for HP jack sensing */
1252 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1254 if (codec->vendor_id == 0x10ec0880)
1255 res >>= 28;
1256 else
1257 res >>= 26;
1258 switch (res) {
1259 case ALC880_HP_EVENT:
1260 alc_automute_pin(codec);
1261 break;
1262 case ALC880_MIC_EVENT:
1263 alc_mic_automute(codec);
1264 break;
1268 static void alc_inithook(struct hda_codec *codec)
1270 alc_automute_pin(codec);
1271 alc_mic_automute(codec);
1274 /* additional initialization for ALC888 variants */
1275 static void alc888_coef_init(struct hda_codec *codec)
1277 unsigned int tmp;
1279 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1280 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1281 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1282 if ((tmp & 0xf0) == 0x20)
1283 /* alc888S-VC */
1284 snd_hda_codec_read(codec, 0x20, 0,
1285 AC_VERB_SET_PROC_COEF, 0x830);
1286 else
1287 /* alc888-VB */
1288 snd_hda_codec_read(codec, 0x20, 0,
1289 AC_VERB_SET_PROC_COEF, 0x3030);
1292 static void alc889_coef_init(struct hda_codec *codec)
1294 unsigned int tmp;
1296 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1297 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1298 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1299 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1302 /* turn on/off EAPD control (only if available) */
1303 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1305 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1306 return;
1307 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1308 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1309 on ? 2 : 0);
1312 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1314 unsigned int tmp;
1316 switch (type) {
1317 case ALC_INIT_GPIO1:
1318 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1319 break;
1320 case ALC_INIT_GPIO2:
1321 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1322 break;
1323 case ALC_INIT_GPIO3:
1324 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1325 break;
1326 case ALC_INIT_DEFAULT:
1327 switch (codec->vendor_id) {
1328 case 0x10ec0260:
1329 set_eapd(codec, 0x0f, 1);
1330 set_eapd(codec, 0x10, 1);
1331 break;
1332 case 0x10ec0262:
1333 case 0x10ec0267:
1334 case 0x10ec0268:
1335 case 0x10ec0269:
1336 case 0x10ec0270:
1337 case 0x10ec0272:
1338 case 0x10ec0660:
1339 case 0x10ec0662:
1340 case 0x10ec0663:
1341 case 0x10ec0862:
1342 case 0x10ec0889:
1343 set_eapd(codec, 0x14, 1);
1344 set_eapd(codec, 0x15, 1);
1345 break;
1347 switch (codec->vendor_id) {
1348 case 0x10ec0260:
1349 snd_hda_codec_write(codec, 0x1a, 0,
1350 AC_VERB_SET_COEF_INDEX, 7);
1351 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1352 AC_VERB_GET_PROC_COEF, 0);
1353 snd_hda_codec_write(codec, 0x1a, 0,
1354 AC_VERB_SET_COEF_INDEX, 7);
1355 snd_hda_codec_write(codec, 0x1a, 0,
1356 AC_VERB_SET_PROC_COEF,
1357 tmp | 0x2010);
1358 break;
1359 case 0x10ec0262:
1360 case 0x10ec0880:
1361 case 0x10ec0882:
1362 case 0x10ec0883:
1363 case 0x10ec0885:
1364 case 0x10ec0887:
1365 case 0x10ec0889:
1366 alc889_coef_init(codec);
1367 break;
1368 case 0x10ec0888:
1369 alc888_coef_init(codec);
1370 break;
1371 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1372 case 0x10ec0267:
1373 case 0x10ec0268:
1374 snd_hda_codec_write(codec, 0x20, 0,
1375 AC_VERB_SET_COEF_INDEX, 7);
1376 tmp = snd_hda_codec_read(codec, 0x20, 0,
1377 AC_VERB_GET_PROC_COEF, 0);
1378 snd_hda_codec_write(codec, 0x20, 0,
1379 AC_VERB_SET_COEF_INDEX, 7);
1380 snd_hda_codec_write(codec, 0x20, 0,
1381 AC_VERB_SET_PROC_COEF,
1382 tmp | 0x3000);
1383 break;
1384 #endif /* XXX */
1386 break;
1390 static void alc_init_auto_hp(struct hda_codec *codec)
1392 struct alc_spec *spec = codec->spec;
1393 struct auto_pin_cfg *cfg = &spec->autocfg;
1394 int i;
1396 if (!cfg->hp_pins[0]) {
1397 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1398 return;
1401 if (!cfg->speaker_pins[0]) {
1402 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1403 return;
1404 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1405 sizeof(cfg->speaker_pins));
1406 cfg->speaker_outs = cfg->line_outs;
1409 if (!cfg->hp_pins[0]) {
1410 memcpy(cfg->hp_pins, cfg->line_out_pins,
1411 sizeof(cfg->hp_pins));
1412 cfg->hp_outs = cfg->line_outs;
1415 for (i = 0; i < cfg->hp_outs; i++) {
1416 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1417 cfg->hp_pins[i]);
1418 snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0,
1419 AC_VERB_SET_UNSOLICITED_ENABLE,
1420 AC_USRSP_EN | ALC880_HP_EVENT);
1422 spec->unsol_event = alc_sku_unsol_event;
1425 static void alc_init_auto_mic(struct hda_codec *codec)
1427 struct alc_spec *spec = codec->spec;
1428 struct auto_pin_cfg *cfg = &spec->autocfg;
1429 hda_nid_t fixed, ext;
1430 int i;
1432 /* there must be only two mic inputs exclusively */
1433 for (i = 0; i < cfg->num_inputs; i++)
1434 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
1435 return;
1437 fixed = ext = 0;
1438 for (i = 0; i < cfg->num_inputs; i++) {
1439 hda_nid_t nid = cfg->inputs[i].pin;
1440 unsigned int defcfg;
1441 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1442 switch (snd_hda_get_input_pin_attr(defcfg)) {
1443 case INPUT_PIN_ATTR_INT:
1444 if (fixed)
1445 return; /* already occupied */
1446 fixed = nid;
1447 break;
1448 case INPUT_PIN_ATTR_UNUSED:
1449 return; /* invalid entry */
1450 default:
1451 if (ext)
1452 return; /* already occupied */
1453 ext = nid;
1454 break;
1457 if (!ext || !fixed)
1458 return;
1459 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1460 return; /* no unsol support */
1461 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1462 ext, fixed);
1463 spec->ext_mic.pin = ext;
1464 spec->int_mic.pin = fixed;
1465 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1466 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1467 spec->auto_mic = 1;
1468 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1469 AC_VERB_SET_UNSOLICITED_ENABLE,
1470 AC_USRSP_EN | ALC880_MIC_EVENT);
1471 spec->unsol_event = alc_sku_unsol_event;
1474 /* Could be any non-zero and even value. When used as fixup, tells
1475 * the driver to ignore any present sku defines.
1477 #define ALC_FIXUP_SKU_IGNORE (2)
1479 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1481 unsigned int ass, tmp, i;
1482 unsigned nid = 0;
1483 struct alc_spec *spec = codec->spec;
1485 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1487 if (spec->cdefine.fixup) {
1488 ass = spec->cdefine.sku_cfg;
1489 if (ass == ALC_FIXUP_SKU_IGNORE)
1490 return -1;
1491 goto do_sku;
1494 ass = codec->subsystem_id & 0xffff;
1495 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1496 goto do_sku;
1498 nid = 0x1d;
1499 if (codec->vendor_id == 0x10ec0260)
1500 nid = 0x17;
1501 ass = snd_hda_codec_get_pincfg(codec, nid);
1503 if (!(ass & 1)) {
1504 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1505 codec->chip_name, ass);
1506 return -1;
1509 /* check sum */
1510 tmp = 0;
1511 for (i = 1; i < 16; i++) {
1512 if ((ass >> i) & 1)
1513 tmp++;
1515 if (((ass >> 16) & 0xf) != tmp)
1516 return -1;
1518 spec->cdefine.port_connectivity = ass >> 30;
1519 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1520 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1521 spec->cdefine.customization = ass >> 8;
1522 do_sku:
1523 spec->cdefine.sku_cfg = ass;
1524 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1525 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1526 spec->cdefine.swap = (ass & 0x2) >> 1;
1527 spec->cdefine.override = ass & 0x1;
1529 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1530 nid, spec->cdefine.sku_cfg);
1531 snd_printd("SKU: port_connectivity=0x%x\n",
1532 spec->cdefine.port_connectivity);
1533 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1534 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1535 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1536 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1537 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1538 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1539 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1541 return 0;
1544 /* check subsystem ID and set up device-specific initialization;
1545 * return 1 if initialized, 0 if invalid SSID
1547 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1548 * 31 ~ 16 : Manufacture ID
1549 * 15 ~ 8 : SKU ID
1550 * 7 ~ 0 : Assembly ID
1551 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1553 static int alc_subsystem_id(struct hda_codec *codec,
1554 hda_nid_t porta, hda_nid_t porte,
1555 hda_nid_t portd, hda_nid_t porti)
1557 unsigned int ass, tmp, i;
1558 unsigned nid;
1559 struct alc_spec *spec = codec->spec;
1561 if (spec->cdefine.fixup) {
1562 ass = spec->cdefine.sku_cfg;
1563 if (ass == ALC_FIXUP_SKU_IGNORE)
1564 return 0;
1565 goto do_sku;
1568 ass = codec->subsystem_id & 0xffff;
1569 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1570 goto do_sku;
1572 /* invalid SSID, check the special NID pin defcfg instead */
1574 * 31~30 : port connectivity
1575 * 29~21 : reserve
1576 * 20 : PCBEEP input
1577 * 19~16 : Check sum (15:1)
1578 * 15~1 : Custom
1579 * 0 : override
1581 nid = 0x1d;
1582 if (codec->vendor_id == 0x10ec0260)
1583 nid = 0x17;
1584 ass = snd_hda_codec_get_pincfg(codec, nid);
1585 snd_printd("realtek: No valid SSID, "
1586 "checking pincfg 0x%08x for NID 0x%x\n",
1587 ass, nid);
1588 if (!(ass & 1))
1589 return 0;
1590 if ((ass >> 30) != 1) /* no physical connection */
1591 return 0;
1593 /* check sum */
1594 tmp = 0;
1595 for (i = 1; i < 16; i++) {
1596 if ((ass >> i) & 1)
1597 tmp++;
1599 if (((ass >> 16) & 0xf) != tmp)
1600 return 0;
1601 do_sku:
1602 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1603 ass & 0xffff, codec->vendor_id);
1605 * 0 : override
1606 * 1 : Swap Jack
1607 * 2 : 0 --> Desktop, 1 --> Laptop
1608 * 3~5 : External Amplifier control
1609 * 7~6 : Reserved
1611 tmp = (ass & 0x38) >> 3; /* external Amp control */
1612 switch (tmp) {
1613 case 1:
1614 spec->init_amp = ALC_INIT_GPIO1;
1615 break;
1616 case 3:
1617 spec->init_amp = ALC_INIT_GPIO2;
1618 break;
1619 case 7:
1620 spec->init_amp = ALC_INIT_GPIO3;
1621 break;
1622 case 5:
1623 default:
1624 spec->init_amp = ALC_INIT_DEFAULT;
1625 break;
1628 /* is laptop or Desktop and enable the function "Mute internal speaker
1629 * when the external headphone out jack is plugged"
1631 if (!(ass & 0x8000))
1632 return 1;
1634 * 10~8 : Jack location
1635 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1636 * 14~13: Resvered
1637 * 15 : 1 --> enable the function "Mute internal speaker
1638 * when the external headphone out jack is plugged"
1640 if (!spec->autocfg.hp_pins[0]) {
1641 hda_nid_t nid;
1642 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1643 if (tmp == 0)
1644 nid = porta;
1645 else if (tmp == 1)
1646 nid = porte;
1647 else if (tmp == 2)
1648 nid = portd;
1649 else if (tmp == 3)
1650 nid = porti;
1651 else
1652 return 1;
1653 for (i = 0; i < spec->autocfg.line_outs; i++)
1654 if (spec->autocfg.line_out_pins[i] == nid)
1655 return 1;
1656 spec->autocfg.hp_pins[0] = nid;
1659 alc_init_auto_hp(codec);
1660 alc_init_auto_mic(codec);
1661 return 1;
1664 static void alc_ssid_check(struct hda_codec *codec,
1665 hda_nid_t porta, hda_nid_t porte,
1666 hda_nid_t portd, hda_nid_t porti)
1668 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1669 struct alc_spec *spec = codec->spec;
1670 snd_printd("realtek: "
1671 "Enable default setup for auto mode as fallback\n");
1672 spec->init_amp = ALC_INIT_DEFAULT;
1673 alc_init_auto_hp(codec);
1674 alc_init_auto_mic(codec);
1679 * Fix-up pin default configurations and add default verbs
1682 struct alc_pincfg {
1683 hda_nid_t nid;
1684 u32 val;
1687 struct alc_model_fixup {
1688 const int id;
1689 const char *name;
1692 struct alc_fixup {
1693 int type;
1694 bool chained;
1695 int chain_id;
1696 union {
1697 unsigned int sku;
1698 const struct alc_pincfg *pins;
1699 const struct hda_verb *verbs;
1700 void (*func)(struct hda_codec *codec,
1701 const struct alc_fixup *fix,
1702 int action);
1703 } v;
1706 enum {
1707 ALC_FIXUP_INVALID,
1708 ALC_FIXUP_SKU,
1709 ALC_FIXUP_PINS,
1710 ALC_FIXUP_VERBS,
1711 ALC_FIXUP_FUNC,
1714 enum {
1715 ALC_FIXUP_ACT_PRE_PROBE,
1716 ALC_FIXUP_ACT_PROBE,
1717 ALC_FIXUP_ACT_INIT,
1720 static void alc_apply_fixup(struct hda_codec *codec, int action)
1722 struct alc_spec *spec = codec->spec;
1723 int id = spec->fixup_id;
1724 #ifdef CONFIG_SND_DEBUG_VERBOSE
1725 const char *modelname = spec->fixup_name;
1726 #endif
1727 int depth = 0;
1729 if (!spec->fixup_list)
1730 return;
1732 while (id >= 0) {
1733 const struct alc_fixup *fix = spec->fixup_list + id;
1734 const struct alc_pincfg *cfg;
1736 switch (fix->type) {
1737 case ALC_FIXUP_SKU:
1738 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1739 break;;
1740 snd_printdd(KERN_INFO "hda_codec: %s: "
1741 "Apply sku override for %s\n",
1742 codec->chip_name, modelname);
1743 spec->cdefine.sku_cfg = fix->v.sku;
1744 spec->cdefine.fixup = 1;
1745 break;
1746 case ALC_FIXUP_PINS:
1747 cfg = fix->v.pins;
1748 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1749 break;
1750 snd_printdd(KERN_INFO "hda_codec: %s: "
1751 "Apply pincfg for %s\n",
1752 codec->chip_name, modelname);
1753 for (; cfg->nid; cfg++)
1754 snd_hda_codec_set_pincfg(codec, cfg->nid,
1755 cfg->val);
1756 break;
1757 case ALC_FIXUP_VERBS:
1758 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1759 break;
1760 snd_printdd(KERN_INFO "hda_codec: %s: "
1761 "Apply fix-verbs for %s\n",
1762 codec->chip_name, modelname);
1763 add_verb(codec->spec, fix->v.verbs);
1764 break;
1765 case ALC_FIXUP_FUNC:
1766 if (!fix->v.func)
1767 break;
1768 snd_printdd(KERN_INFO "hda_codec: %s: "
1769 "Apply fix-func for %s\n",
1770 codec->chip_name, modelname);
1771 fix->v.func(codec, fix, action);
1772 break;
1773 default:
1774 snd_printk(KERN_ERR "hda_codec: %s: "
1775 "Invalid fixup type %d\n",
1776 codec->chip_name, fix->type);
1777 break;
1779 if (!fix[id].chained)
1780 break;
1781 if (++depth > 10)
1782 break;
1783 id = fix[id].chain_id;
1787 static void alc_pick_fixup(struct hda_codec *codec,
1788 const struct alc_model_fixup *models,
1789 const struct snd_pci_quirk *quirk,
1790 const struct alc_fixup *fixlist)
1792 struct alc_spec *spec = codec->spec;
1793 int id = -1;
1794 const char *name = NULL;
1796 if (codec->modelname && models) {
1797 while (models->name) {
1798 if (!strcmp(codec->modelname, models->name)) {
1799 id = models->id;
1800 name = models->name;
1801 break;
1803 models++;
1806 if (id < 0) {
1807 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1808 if (quirk) {
1809 id = quirk->value;
1810 #ifdef CONFIG_SND_DEBUG_VERBOSE
1811 name = quirk->name;
1812 #endif
1816 spec->fixup_id = id;
1817 if (id >= 0) {
1818 spec->fixup_list = fixlist;
1819 spec->fixup_name = name;
1823 static int alc_read_coef_idx(struct hda_codec *codec,
1824 unsigned int coef_idx)
1826 unsigned int val;
1827 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1828 coef_idx);
1829 val = snd_hda_codec_read(codec, 0x20, 0,
1830 AC_VERB_GET_PROC_COEF, 0);
1831 return val;
1834 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
1835 unsigned int coef_val)
1837 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1838 coef_idx);
1839 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
1840 coef_val);
1843 /* set right pin controls for digital I/O */
1844 static void alc_auto_init_digital(struct hda_codec *codec)
1846 struct alc_spec *spec = codec->spec;
1847 int i;
1848 hda_nid_t pin;
1850 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1851 pin = spec->autocfg.dig_out_pins[i];
1852 if (pin) {
1853 snd_hda_codec_write(codec, pin, 0,
1854 AC_VERB_SET_PIN_WIDGET_CONTROL,
1855 PIN_OUT);
1858 pin = spec->autocfg.dig_in_pin;
1859 if (pin)
1860 snd_hda_codec_write(codec, pin, 0,
1861 AC_VERB_SET_PIN_WIDGET_CONTROL,
1862 PIN_IN);
1865 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
1866 static void alc_auto_parse_digital(struct hda_codec *codec)
1868 struct alc_spec *spec = codec->spec;
1869 int i, err;
1870 hda_nid_t dig_nid;
1872 /* support multiple SPDIFs; the secondary is set up as a slave */
1873 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1874 err = snd_hda_get_connections(codec,
1875 spec->autocfg.dig_out_pins[i],
1876 &dig_nid, 1);
1877 if (err < 0)
1878 continue;
1879 if (!i) {
1880 spec->multiout.dig_out_nid = dig_nid;
1881 spec->dig_out_type = spec->autocfg.dig_out_type[0];
1882 } else {
1883 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
1884 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
1885 break;
1886 spec->slave_dig_outs[i - 1] = dig_nid;
1890 if (spec->autocfg.dig_in_pin) {
1891 dig_nid = codec->start_nid;
1892 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
1893 unsigned int wcaps = get_wcaps(codec, dig_nid);
1894 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
1895 continue;
1896 if (!(wcaps & AC_WCAP_DIGITAL))
1897 continue;
1898 if (!(wcaps & AC_WCAP_CONN_LIST))
1899 continue;
1900 err = get_connection_index(codec, dig_nid,
1901 spec->autocfg.dig_in_pin);
1902 if (err >= 0) {
1903 spec->dig_in_nid = dig_nid;
1904 break;
1911 * ALC888
1915 * 2ch mode
1917 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1918 /* Mic-in jack as mic in */
1919 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1920 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1921 /* Line-in jack as Line in */
1922 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1923 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1924 /* Line-Out as Front */
1925 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1926 { } /* end */
1930 * 4ch mode
1932 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1933 /* Mic-in jack as mic in */
1934 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1935 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1936 /* Line-in jack as Surround */
1937 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1938 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1939 /* Line-Out as Front */
1940 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1941 { } /* end */
1945 * 6ch mode
1947 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1948 /* Mic-in jack as CLFE */
1949 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1950 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1951 /* Line-in jack as Surround */
1952 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1953 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1954 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1955 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1956 { } /* end */
1960 * 8ch mode
1962 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1963 /* Mic-in jack as CLFE */
1964 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1965 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1966 /* Line-in jack as Surround */
1967 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1968 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1969 /* Line-Out as Side */
1970 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1971 { } /* end */
1974 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1975 { 2, alc888_4ST_ch2_intel_init },
1976 { 4, alc888_4ST_ch4_intel_init },
1977 { 6, alc888_4ST_ch6_intel_init },
1978 { 8, alc888_4ST_ch8_intel_init },
1982 * ALC888 Fujitsu Siemens Amillo xa3530
1985 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1986 /* Front Mic: set to PIN_IN (empty by default) */
1987 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1988 /* Connect Internal HP to Front */
1989 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1990 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1991 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1992 /* Connect Bass HP to Front */
1993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1995 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1996 /* Connect Line-Out side jack (SPDIF) to Side */
1997 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1998 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1999 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2000 /* Connect Mic jack to CLFE */
2001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2003 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2004 /* Connect Line-in jack to Surround */
2005 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2006 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2007 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2008 /* Connect HP out jack to Front */
2009 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2010 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2011 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2012 /* Enable unsolicited event for HP jack and Line-out jack */
2013 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2014 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2018 static void alc_automute_amp(struct hda_codec *codec)
2020 alc_automute_speaker(codec, 0);
2023 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
2024 unsigned int res)
2026 if (codec->vendor_id == 0x10ec0880)
2027 res >>= 28;
2028 else
2029 res >>= 26;
2030 if (res == ALC880_HP_EVENT)
2031 alc_automute_amp(codec);
2034 static void alc889_automute_setup(struct hda_codec *codec)
2036 struct alc_spec *spec = codec->spec;
2038 spec->autocfg.hp_pins[0] = 0x15;
2039 spec->autocfg.speaker_pins[0] = 0x14;
2040 spec->autocfg.speaker_pins[1] = 0x16;
2041 spec->autocfg.speaker_pins[2] = 0x17;
2042 spec->autocfg.speaker_pins[3] = 0x19;
2043 spec->autocfg.speaker_pins[4] = 0x1a;
2046 static void alc889_intel_init_hook(struct hda_codec *codec)
2048 alc889_coef_init(codec);
2049 alc_automute_amp(codec);
2052 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2054 struct alc_spec *spec = codec->spec;
2056 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2057 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2058 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2059 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2063 * ALC888 Acer Aspire 4930G model
2066 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2067 /* Front Mic: set to PIN_IN (empty by default) */
2068 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2069 /* Unselect Front Mic by default in input mixer 3 */
2070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2071 /* Enable unsolicited event for HP jack */
2072 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2073 /* Connect Internal HP to front */
2074 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2075 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2076 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2077 /* Connect HP out to front */
2078 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2079 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2081 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2086 * ALC888 Acer Aspire 6530G model
2089 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2090 /* Route to built-in subwoofer as well as speakers */
2091 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2093 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2094 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2095 /* Bias voltage on for external mic port */
2096 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2097 /* Front Mic: set to PIN_IN (empty by default) */
2098 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2099 /* Unselect Front Mic by default in input mixer 3 */
2100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2101 /* Enable unsolicited event for HP jack */
2102 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2103 /* Enable speaker output */
2104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2106 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2107 /* Enable headphone output */
2108 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2111 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2116 *ALC888 Acer Aspire 7730G model
2119 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2120 /* Bias voltage on for external mic port */
2121 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2122 /* Front Mic: set to PIN_IN (empty by default) */
2123 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2124 /* Unselect Front Mic by default in input mixer 3 */
2125 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2126 /* Enable unsolicited event for HP jack */
2127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2128 /* Enable speaker output */
2129 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2130 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2131 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2132 /* Enable headphone output */
2133 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2135 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2136 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2137 /*Enable internal subwoofer */
2138 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2139 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2140 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2141 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2146 * ALC889 Acer Aspire 8930G model
2149 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2150 /* Front Mic: set to PIN_IN (empty by default) */
2151 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2152 /* Unselect Front Mic by default in input mixer 3 */
2153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2154 /* Enable unsolicited event for HP jack */
2155 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2156 /* Connect Internal Front to Front */
2157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2159 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2160 /* Connect Internal Rear to Rear */
2161 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2162 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2163 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2164 /* Connect Internal CLFE to CLFE */
2165 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2167 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2168 /* Connect HP out to Front */
2169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2170 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2171 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2172 /* Enable all DACs */
2173 /* DAC DISABLE/MUTE 1? */
2174 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2175 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2176 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2177 /* DAC DISABLE/MUTE 2? */
2178 /* some bit here disables the other DACs. Init=0x4900 */
2179 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2180 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2181 /* DMIC fix
2182 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2183 * which makes the stereo useless. However, either the mic or the ALC889
2184 * makes the signal become a difference/sum signal instead of standard
2185 * stereo, which is annoying. So instead we flip this bit which makes the
2186 * codec replicate the sum signal to both channels, turning it into a
2187 * normal mono mic.
2189 /* DMIC_CONTROL? Init value = 0x0001 */
2190 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2191 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2195 static struct hda_input_mux alc888_2_capture_sources[2] = {
2196 /* Front mic only available on one ADC */
2198 .num_items = 4,
2199 .items = {
2200 { "Mic", 0x0 },
2201 { "Line", 0x2 },
2202 { "CD", 0x4 },
2203 { "Front Mic", 0xb },
2207 .num_items = 3,
2208 .items = {
2209 { "Mic", 0x0 },
2210 { "Line", 0x2 },
2211 { "CD", 0x4 },
2216 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2217 /* Interal mic only available on one ADC */
2219 .num_items = 5,
2220 .items = {
2221 { "Mic", 0x0 },
2222 { "Line In", 0x2 },
2223 { "CD", 0x4 },
2224 { "Input Mix", 0xa },
2225 { "Internal Mic", 0xb },
2229 .num_items = 4,
2230 .items = {
2231 { "Mic", 0x0 },
2232 { "Line In", 0x2 },
2233 { "CD", 0x4 },
2234 { "Input Mix", 0xa },
2239 static struct hda_input_mux alc889_capture_sources[3] = {
2240 /* Digital mic only available on first "ADC" */
2242 .num_items = 5,
2243 .items = {
2244 { "Mic", 0x0 },
2245 { "Line", 0x2 },
2246 { "CD", 0x4 },
2247 { "Front Mic", 0xb },
2248 { "Input Mix", 0xa },
2252 .num_items = 4,
2253 .items = {
2254 { "Mic", 0x0 },
2255 { "Line", 0x2 },
2256 { "CD", 0x4 },
2257 { "Input Mix", 0xa },
2261 .num_items = 4,
2262 .items = {
2263 { "Mic", 0x0 },
2264 { "Line", 0x2 },
2265 { "CD", 0x4 },
2266 { "Input Mix", 0xa },
2271 static struct snd_kcontrol_new alc888_base_mixer[] = {
2272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2273 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2275 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2276 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2277 HDA_OUTPUT),
2278 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2279 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2280 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2281 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2282 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2290 { } /* end */
2293 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2296 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2297 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2298 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2299 HDA_OUTPUT),
2300 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2301 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2302 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2308 { } /* end */
2312 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2314 struct alc_spec *spec = codec->spec;
2316 spec->autocfg.hp_pins[0] = 0x15;
2317 spec->autocfg.speaker_pins[0] = 0x14;
2318 spec->autocfg.speaker_pins[1] = 0x16;
2319 spec->autocfg.speaker_pins[2] = 0x17;
2322 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2324 struct alc_spec *spec = codec->spec;
2326 spec->autocfg.hp_pins[0] = 0x15;
2327 spec->autocfg.speaker_pins[0] = 0x14;
2328 spec->autocfg.speaker_pins[1] = 0x16;
2329 spec->autocfg.speaker_pins[2] = 0x17;
2332 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2334 struct alc_spec *spec = codec->spec;
2336 spec->autocfg.hp_pins[0] = 0x15;
2337 spec->autocfg.speaker_pins[0] = 0x14;
2338 spec->autocfg.speaker_pins[1] = 0x16;
2339 spec->autocfg.speaker_pins[2] = 0x17;
2342 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2344 struct alc_spec *spec = codec->spec;
2346 spec->autocfg.hp_pins[0] = 0x15;
2347 spec->autocfg.speaker_pins[0] = 0x14;
2348 spec->autocfg.speaker_pins[1] = 0x16;
2349 spec->autocfg.speaker_pins[2] = 0x1b;
2353 * ALC880 3-stack model
2355 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2356 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2357 * F-Mic = 0x1b, HP = 0x19
2360 static hda_nid_t alc880_dac_nids[4] = {
2361 /* front, rear, clfe, rear_surr */
2362 0x02, 0x05, 0x04, 0x03
2365 static hda_nid_t alc880_adc_nids[3] = {
2366 /* ADC0-2 */
2367 0x07, 0x08, 0x09,
2370 /* The datasheet says the node 0x07 is connected from inputs,
2371 * but it shows zero connection in the real implementation on some devices.
2372 * Note: this is a 915GAV bug, fixed on 915GLV
2374 static hda_nid_t alc880_adc_nids_alt[2] = {
2375 /* ADC1-2 */
2376 0x08, 0x09,
2379 #define ALC880_DIGOUT_NID 0x06
2380 #define ALC880_DIGIN_NID 0x0a
2382 static struct hda_input_mux alc880_capture_source = {
2383 .num_items = 4,
2384 .items = {
2385 { "Mic", 0x0 },
2386 { "Front Mic", 0x3 },
2387 { "Line", 0x2 },
2388 { "CD", 0x4 },
2392 /* channel source setting (2/6 channel selection for 3-stack) */
2393 /* 2ch mode */
2394 static struct hda_verb alc880_threestack_ch2_init[] = {
2395 /* set line-in to input, mute it */
2396 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2397 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2398 /* set mic-in to input vref 80%, mute it */
2399 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2400 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2401 { } /* end */
2404 /* 6ch mode */
2405 static struct hda_verb alc880_threestack_ch6_init[] = {
2406 /* set line-in to output, unmute it */
2407 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2408 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2409 /* set mic-in to output, unmute it */
2410 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2411 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2412 { } /* end */
2415 static struct hda_channel_mode alc880_threestack_modes[2] = {
2416 { 2, alc880_threestack_ch2_init },
2417 { 6, alc880_threestack_ch6_init },
2420 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2421 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2422 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2423 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2424 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2425 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2426 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2427 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2428 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2429 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2430 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2431 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2432 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2434 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2435 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2436 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2440 .name = "Channel Mode",
2441 .info = alc_ch_mode_info,
2442 .get = alc_ch_mode_get,
2443 .put = alc_ch_mode_put,
2445 { } /* end */
2448 /* capture mixer elements */
2449 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2450 struct snd_ctl_elem_info *uinfo)
2452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2453 struct alc_spec *spec = codec->spec;
2454 int err;
2456 mutex_lock(&codec->control_mutex);
2457 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2458 HDA_INPUT);
2459 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2460 mutex_unlock(&codec->control_mutex);
2461 return err;
2464 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2465 unsigned int size, unsigned int __user *tlv)
2467 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2468 struct alc_spec *spec = codec->spec;
2469 int err;
2471 mutex_lock(&codec->control_mutex);
2472 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2473 HDA_INPUT);
2474 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2475 mutex_unlock(&codec->control_mutex);
2476 return err;
2479 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2480 struct snd_ctl_elem_value *ucontrol);
2482 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_value *ucontrol,
2484 getput_call_t func)
2486 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2487 struct alc_spec *spec = codec->spec;
2488 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2489 int err;
2491 mutex_lock(&codec->control_mutex);
2492 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2493 3, 0, HDA_INPUT);
2494 err = func(kcontrol, ucontrol);
2495 mutex_unlock(&codec->control_mutex);
2496 return err;
2499 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2500 struct snd_ctl_elem_value *ucontrol)
2502 return alc_cap_getput_caller(kcontrol, ucontrol,
2503 snd_hda_mixer_amp_volume_get);
2506 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2507 struct snd_ctl_elem_value *ucontrol)
2509 return alc_cap_getput_caller(kcontrol, ucontrol,
2510 snd_hda_mixer_amp_volume_put);
2513 /* capture mixer elements */
2514 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2516 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2517 struct snd_ctl_elem_value *ucontrol)
2519 return alc_cap_getput_caller(kcontrol, ucontrol,
2520 snd_hda_mixer_amp_switch_get);
2523 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2524 struct snd_ctl_elem_value *ucontrol)
2526 return alc_cap_getput_caller(kcontrol, ucontrol,
2527 snd_hda_mixer_amp_switch_put);
2530 #define _DEFINE_CAPMIX(num) \
2532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2533 .name = "Capture Switch", \
2534 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2535 .count = num, \
2536 .info = alc_cap_sw_info, \
2537 .get = alc_cap_sw_get, \
2538 .put = alc_cap_sw_put, \
2539 }, \
2541 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2542 .name = "Capture Volume", \
2543 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2544 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2545 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2546 .count = num, \
2547 .info = alc_cap_vol_info, \
2548 .get = alc_cap_vol_get, \
2549 .put = alc_cap_vol_put, \
2550 .tlv = { .c = alc_cap_vol_tlv }, \
2553 #define _DEFINE_CAPSRC(num) \
2555 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2556 /* .name = "Capture Source", */ \
2557 .name = "Input Source", \
2558 .count = num, \
2559 .info = alc_mux_enum_info, \
2560 .get = alc_mux_enum_get, \
2561 .put = alc_mux_enum_put, \
2564 #define DEFINE_CAPMIX(num) \
2565 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2566 _DEFINE_CAPMIX(num), \
2567 _DEFINE_CAPSRC(num), \
2568 { } /* end */ \
2571 #define DEFINE_CAPMIX_NOSRC(num) \
2572 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2573 _DEFINE_CAPMIX(num), \
2574 { } /* end */ \
2577 /* up to three ADCs */
2578 DEFINE_CAPMIX(1);
2579 DEFINE_CAPMIX(2);
2580 DEFINE_CAPMIX(3);
2581 DEFINE_CAPMIX_NOSRC(1);
2582 DEFINE_CAPMIX_NOSRC(2);
2583 DEFINE_CAPMIX_NOSRC(3);
2586 * ALC880 5-stack model
2588 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2589 * Side = 0x02 (0xd)
2590 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2591 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2594 /* additional mixers to alc880_three_stack_mixer */
2595 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2596 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2597 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2598 { } /* end */
2601 /* channel source setting (6/8 channel selection for 5-stack) */
2602 /* 6ch mode */
2603 static struct hda_verb alc880_fivestack_ch6_init[] = {
2604 /* set line-in to input, mute it */
2605 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2606 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2607 { } /* end */
2610 /* 8ch mode */
2611 static struct hda_verb alc880_fivestack_ch8_init[] = {
2612 /* set line-in to output, unmute it */
2613 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2614 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2615 { } /* end */
2618 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2619 { 6, alc880_fivestack_ch6_init },
2620 { 8, alc880_fivestack_ch8_init },
2625 * ALC880 6-stack model
2627 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2628 * Side = 0x05 (0x0f)
2629 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2630 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2633 static hda_nid_t alc880_6st_dac_nids[4] = {
2634 /* front, rear, clfe, rear_surr */
2635 0x02, 0x03, 0x04, 0x05
2638 static struct hda_input_mux alc880_6stack_capture_source = {
2639 .num_items = 4,
2640 .items = {
2641 { "Mic", 0x0 },
2642 { "Front Mic", 0x1 },
2643 { "Line", 0x2 },
2644 { "CD", 0x4 },
2648 /* fixed 8-channels */
2649 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2650 { 8, NULL },
2653 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2654 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2655 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2656 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2657 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2658 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2659 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2660 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2661 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2663 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2664 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2665 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2666 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2667 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2670 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2671 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674 .name = "Channel Mode",
2675 .info = alc_ch_mode_info,
2676 .get = alc_ch_mode_get,
2677 .put = alc_ch_mode_put,
2679 { } /* end */
2684 * ALC880 W810 model
2686 * W810 has rear IO for:
2687 * Front (DAC 02)
2688 * Surround (DAC 03)
2689 * Center/LFE (DAC 04)
2690 * Digital out (06)
2692 * The system also has a pair of internal speakers, and a headphone jack.
2693 * These are both connected to Line2 on the codec, hence to DAC 02.
2695 * There is a variable resistor to control the speaker or headphone
2696 * volume. This is a hardware-only device without a software API.
2698 * Plugging headphones in will disable the internal speakers. This is
2699 * implemented in hardware, not via the driver using jack sense. In
2700 * a similar fashion, plugging into the rear socket marked "front" will
2701 * disable both the speakers and headphones.
2703 * For input, there's a microphone jack, and an "audio in" jack.
2704 * These may not do anything useful with this driver yet, because I
2705 * haven't setup any initialization verbs for these yet...
2708 static hda_nid_t alc880_w810_dac_nids[3] = {
2709 /* front, rear/surround, clfe */
2710 0x02, 0x03, 0x04
2713 /* fixed 6 channels */
2714 static struct hda_channel_mode alc880_w810_modes[1] = {
2715 { 6, NULL }
2718 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2719 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2720 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2721 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2722 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2723 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2724 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2725 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2726 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2727 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2728 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2729 { } /* end */
2734 * Z710V model
2736 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2737 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2738 * Line = 0x1a
2741 static hda_nid_t alc880_z71v_dac_nids[1] = {
2742 0x02
2744 #define ALC880_Z71V_HP_DAC 0x03
2746 /* fixed 2 channels */
2747 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2748 { 2, NULL }
2751 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2752 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2753 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2754 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2755 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2756 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2757 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2758 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2759 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2760 { } /* end */
2765 * ALC880 F1734 model
2767 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2768 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2771 static hda_nid_t alc880_f1734_dac_nids[1] = {
2772 0x03
2774 #define ALC880_F1734_HP_DAC 0x02
2776 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2777 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2778 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2779 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2780 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2781 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2782 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2783 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2784 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2785 { } /* end */
2788 static struct hda_input_mux alc880_f1734_capture_source = {
2789 .num_items = 2,
2790 .items = {
2791 { "Mic", 0x1 },
2792 { "CD", 0x4 },
2798 * ALC880 ASUS model
2800 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2801 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2802 * Mic = 0x18, Line = 0x1a
2805 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2806 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2808 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2811 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2812 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2813 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2814 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2815 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2816 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2817 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2818 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2819 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2820 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2824 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2825 .name = "Channel Mode",
2826 .info = alc_ch_mode_info,
2827 .get = alc_ch_mode_get,
2828 .put = alc_ch_mode_put,
2830 { } /* end */
2834 * ALC880 ASUS W1V model
2836 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2837 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2838 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2841 /* additional mixers to alc880_asus_mixer */
2842 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2843 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2844 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2845 { } /* end */
2848 /* TCL S700 */
2849 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2850 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2851 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2852 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2854 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2857 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2858 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2859 { } /* end */
2862 /* Uniwill */
2863 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2864 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2865 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2866 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2867 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2868 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2869 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2870 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2871 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2872 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2873 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2874 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2875 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2878 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2879 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2881 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2882 .name = "Channel Mode",
2883 .info = alc_ch_mode_info,
2884 .get = alc_ch_mode_get,
2885 .put = alc_ch_mode_put,
2887 { } /* end */
2890 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2891 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2892 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2893 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2894 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2899 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2900 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2901 { } /* end */
2904 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2905 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2906 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2907 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2908 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2911 { } /* end */
2915 * virtual master controls
2919 * slave controls for virtual master
2921 static const char * const alc_slave_vols[] = {
2922 "Front Playback Volume",
2923 "Surround Playback Volume",
2924 "Center Playback Volume",
2925 "LFE Playback Volume",
2926 "Side Playback Volume",
2927 "Headphone Playback Volume",
2928 "Speaker Playback Volume",
2929 "Mono Playback Volume",
2930 "Line-Out Playback Volume",
2931 "PCM Playback Volume",
2932 NULL,
2935 static const char * const alc_slave_sws[] = {
2936 "Front Playback Switch",
2937 "Surround Playback Switch",
2938 "Center Playback Switch",
2939 "LFE Playback Switch",
2940 "Side Playback Switch",
2941 "Headphone Playback Switch",
2942 "Speaker Playback Switch",
2943 "Mono Playback Switch",
2944 "IEC958 Playback Switch",
2945 "Line-Out Playback Switch",
2946 "PCM Playback Switch",
2947 NULL,
2951 * build control elements
2954 #define NID_MAPPING (-1)
2956 #define SUBDEV_SPEAKER_ (0 << 6)
2957 #define SUBDEV_HP_ (1 << 6)
2958 #define SUBDEV_LINE_ (2 << 6)
2959 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2960 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2961 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2963 static void alc_free_kctls(struct hda_codec *codec);
2965 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2966 /* additional beep mixers; the actual parameters are overwritten at build */
2967 static struct snd_kcontrol_new alc_beep_mixer[] = {
2968 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2969 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2970 { } /* end */
2972 #endif
2974 static int alc_build_controls(struct hda_codec *codec)
2976 struct alc_spec *spec = codec->spec;
2977 struct snd_kcontrol *kctl = NULL;
2978 struct snd_kcontrol_new *knew;
2979 int i, j, err;
2980 unsigned int u;
2981 hda_nid_t nid;
2983 for (i = 0; i < spec->num_mixers; i++) {
2984 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2985 if (err < 0)
2986 return err;
2988 if (spec->cap_mixer) {
2989 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2990 if (err < 0)
2991 return err;
2993 if (spec->multiout.dig_out_nid) {
2994 err = snd_hda_create_spdif_out_ctls(codec,
2995 spec->multiout.dig_out_nid);
2996 if (err < 0)
2997 return err;
2998 if (!spec->no_analog) {
2999 err = snd_hda_create_spdif_share_sw(codec,
3000 &spec->multiout);
3001 if (err < 0)
3002 return err;
3003 spec->multiout.share_spdif = 1;
3006 if (spec->dig_in_nid) {
3007 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3008 if (err < 0)
3009 return err;
3012 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3013 /* create beep controls if needed */
3014 if (spec->beep_amp) {
3015 struct snd_kcontrol_new *knew;
3016 for (knew = alc_beep_mixer; knew->name; knew++) {
3017 struct snd_kcontrol *kctl;
3018 kctl = snd_ctl_new1(knew, codec);
3019 if (!kctl)
3020 return -ENOMEM;
3021 kctl->private_value = spec->beep_amp;
3022 err = snd_hda_ctl_add(codec, 0, kctl);
3023 if (err < 0)
3024 return err;
3027 #endif
3029 /* if we have no master control, let's create it */
3030 if (!spec->no_analog &&
3031 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3032 unsigned int vmaster_tlv[4];
3033 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3034 HDA_OUTPUT, vmaster_tlv);
3035 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3036 vmaster_tlv, alc_slave_vols);
3037 if (err < 0)
3038 return err;
3040 if (!spec->no_analog &&
3041 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3042 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3043 NULL, alc_slave_sws);
3044 if (err < 0)
3045 return err;
3048 /* assign Capture Source enums to NID */
3049 if (spec->capsrc_nids || spec->adc_nids) {
3050 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3051 if (!kctl)
3052 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3053 for (i = 0; kctl && i < kctl->count; i++) {
3054 hda_nid_t *nids = spec->capsrc_nids;
3055 if (!nids)
3056 nids = spec->adc_nids;
3057 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3058 if (err < 0)
3059 return err;
3062 if (spec->cap_mixer) {
3063 const char *kname = kctl ? kctl->id.name : NULL;
3064 for (knew = spec->cap_mixer; knew->name; knew++) {
3065 if (kname && strcmp(knew->name, kname) == 0)
3066 continue;
3067 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3068 for (i = 0; kctl && i < kctl->count; i++) {
3069 err = snd_hda_add_nid(codec, kctl, i,
3070 spec->adc_nids[i]);
3071 if (err < 0)
3072 return err;
3077 /* other nid->control mapping */
3078 for (i = 0; i < spec->num_mixers; i++) {
3079 for (knew = spec->mixers[i]; knew->name; knew++) {
3080 if (knew->iface != NID_MAPPING)
3081 continue;
3082 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3083 if (kctl == NULL)
3084 continue;
3085 u = knew->subdevice;
3086 for (j = 0; j < 4; j++, u >>= 8) {
3087 nid = u & 0x3f;
3088 if (nid == 0)
3089 continue;
3090 switch (u & 0xc0) {
3091 case SUBDEV_SPEAKER_:
3092 nid = spec->autocfg.speaker_pins[nid];
3093 break;
3094 case SUBDEV_LINE_:
3095 nid = spec->autocfg.line_out_pins[nid];
3096 break;
3097 case SUBDEV_HP_:
3098 nid = spec->autocfg.hp_pins[nid];
3099 break;
3100 default:
3101 continue;
3103 err = snd_hda_add_nid(codec, kctl, 0, nid);
3104 if (err < 0)
3105 return err;
3107 u = knew->private_value;
3108 for (j = 0; j < 4; j++, u >>= 8) {
3109 nid = u & 0xff;
3110 if (nid == 0)
3111 continue;
3112 err = snd_hda_add_nid(codec, kctl, 0, nid);
3113 if (err < 0)
3114 return err;
3119 alc_free_kctls(codec); /* no longer needed */
3121 return 0;
3126 * initialize the codec volumes, etc
3130 * generic initialization of ADC, input mixers and output mixers
3132 static struct hda_verb alc880_volume_init_verbs[] = {
3134 * Unmute ADC0-2 and set the default input to mic-in
3136 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3137 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3138 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3139 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3140 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3141 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3143 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3144 * mixer widget
3145 * Note: PASD motherboards uses the Line In 2 as the input for front
3146 * panel mic (mic 2)
3148 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3152 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3153 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3158 * Set up output mixers (0x0c - 0x0f)
3160 /* set vol=0 to output mixers */
3161 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3162 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3163 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3164 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3165 /* set up input amps for analog loopback */
3166 /* Amp Indices: DAC = 0, mixer = 1 */
3167 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3170 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3171 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3172 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3173 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3174 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3180 * 3-stack pin configuration:
3181 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3183 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
3185 * preset connection lists of input pins
3186 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3188 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3189 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3190 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3193 * Set pin mode and muting
3195 /* set front pin widgets 0x14 for output */
3196 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3197 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3198 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3199 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3200 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3201 /* Mic2 (as headphone out) for HP output */
3202 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3203 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3204 /* Line In pin widget for input */
3205 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3206 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3207 /* Line2 (as front mic) pin widget for input and vref at 80% */
3208 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3209 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3210 /* CD pin widget for input */
3211 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3217 * 5-stack pin configuration:
3218 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3219 * line-in/side = 0x1a, f-mic = 0x1b
3221 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
3223 * preset connection lists of input pins
3224 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3226 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3227 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3230 * Set pin mode and muting
3232 /* set pin widgets 0x14-0x17 for output */
3233 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3234 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3235 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3236 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3237 /* unmute pins for output (no gain on this amp) */
3238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3241 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3243 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3244 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3245 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3246 /* Mic2 (as headphone out) for HP output */
3247 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3248 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3249 /* Line In pin widget for input */
3250 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3251 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3252 /* Line2 (as front mic) pin widget for input and vref at 80% */
3253 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3254 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3255 /* CD pin widget for input */
3256 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3262 * W810 pin configuration:
3263 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3265 static struct hda_verb alc880_pin_w810_init_verbs[] = {
3266 /* hphone/speaker input selector: front DAC */
3267 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3269 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3270 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3272 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3273 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3274 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3277 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3283 * Z71V pin configuration:
3284 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3286 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
3287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3292 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3293 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3294 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3295 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3301 * 6-stack pin configuration:
3302 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3303 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3305 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
3306 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3308 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3309 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3310 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3312 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3313 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3314 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3315 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3317 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3319 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3320 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3321 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3322 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3323 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3324 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3325 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3331 * Uniwill pin configuration:
3332 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3333 * line = 0x1a
3335 static struct hda_verb alc880_uniwill_init_verbs[] = {
3336 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3339 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3341 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3343 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3344 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3345 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3347 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3348 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3349 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3350 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3353 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3354 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3355 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3356 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3357 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3358 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3359 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3360 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3361 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3363 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3364 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3370 * Uniwill P53
3371 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3373 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3374 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3378 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3380 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3381 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3384 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3386 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3387 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3389 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3390 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3394 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3396 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3397 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3402 static struct hda_verb alc880_beep_init_verbs[] = {
3403 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3407 /* auto-toggle front mic */
3408 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3410 unsigned int present;
3411 unsigned char bits;
3413 present = snd_hda_jack_detect(codec, 0x18);
3414 bits = present ? HDA_AMP_MUTE : 0;
3415 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3418 static void alc880_uniwill_setup(struct hda_codec *codec)
3420 struct alc_spec *spec = codec->spec;
3422 spec->autocfg.hp_pins[0] = 0x14;
3423 spec->autocfg.speaker_pins[0] = 0x15;
3424 spec->autocfg.speaker_pins[0] = 0x16;
3427 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3429 alc_automute_amp(codec);
3430 alc88x_simple_mic_automute(codec);
3433 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3434 unsigned int res)
3436 /* Looks like the unsol event is incompatible with the standard
3437 * definition. 4bit tag is placed at 28 bit!
3439 switch (res >> 28) {
3440 case ALC880_MIC_EVENT:
3441 alc88x_simple_mic_automute(codec);
3442 break;
3443 default:
3444 alc_automute_amp_unsol_event(codec, res);
3445 break;
3449 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3451 struct alc_spec *spec = codec->spec;
3453 spec->autocfg.hp_pins[0] = 0x14;
3454 spec->autocfg.speaker_pins[0] = 0x15;
3457 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3459 unsigned int present;
3461 present = snd_hda_codec_read(codec, 0x21, 0,
3462 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3463 present &= HDA_AMP_VOLMASK;
3464 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3465 HDA_AMP_VOLMASK, present);
3466 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3467 HDA_AMP_VOLMASK, present);
3470 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3471 unsigned int res)
3473 /* Looks like the unsol event is incompatible with the standard
3474 * definition. 4bit tag is placed at 28 bit!
3476 if ((res >> 28) == ALC880_DCVOL_EVENT)
3477 alc880_uniwill_p53_dcvol_automute(codec);
3478 else
3479 alc_automute_amp_unsol_event(codec, res);
3483 * F1734 pin configuration:
3484 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3486 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3487 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3488 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3489 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3490 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3491 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3495 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3496 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3500 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3501 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3504 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3505 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3509 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3515 * ASUS pin configuration:
3516 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3518 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3519 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3520 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3521 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3522 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3524 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3533 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3535 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3536 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3537 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3538 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3546 /* Enable GPIO mask and set output */
3547 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3548 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3549 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3551 /* Clevo m520g init */
3552 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3553 /* headphone output */
3554 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3555 /* line-out */
3556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3557 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3558 /* Line-in */
3559 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3560 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561 /* CD */
3562 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3563 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3564 /* Mic1 (rear panel) */
3565 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3566 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567 /* Mic2 (front panel) */
3568 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3569 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570 /* headphone */
3571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3573 /* change to EAPD mode */
3574 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3575 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3580 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3581 /* change to EAPD mode */
3582 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3583 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3585 /* Headphone output */
3586 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3587 /* Front output*/
3588 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3589 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3591 /* Line In pin widget for input */
3592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3593 /* CD pin widget for input */
3594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3595 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3596 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3598 /* change to EAPD mode */
3599 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3600 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3606 * LG m1 express dual
3608 * Pin assignment:
3609 * Rear Line-In/Out (blue): 0x14
3610 * Build-in Mic-In: 0x15
3611 * Speaker-out: 0x17
3612 * HP-Out (green): 0x1b
3613 * Mic-In/Out (red): 0x19
3614 * SPDIF-Out: 0x1e
3617 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3618 static hda_nid_t alc880_lg_dac_nids[3] = {
3619 0x05, 0x02, 0x03
3622 /* seems analog CD is not working */
3623 static struct hda_input_mux alc880_lg_capture_source = {
3624 .num_items = 3,
3625 .items = {
3626 { "Mic", 0x1 },
3627 { "Line", 0x5 },
3628 { "Internal Mic", 0x6 },
3632 /* 2,4,6 channel modes */
3633 static struct hda_verb alc880_lg_ch2_init[] = {
3634 /* set line-in and mic-in to input */
3635 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3636 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3640 static struct hda_verb alc880_lg_ch4_init[] = {
3641 /* set line-in to out and mic-in to input */
3642 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3643 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3647 static struct hda_verb alc880_lg_ch6_init[] = {
3648 /* set line-in and mic-in to output */
3649 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3650 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3654 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3655 { 2, alc880_lg_ch2_init },
3656 { 4, alc880_lg_ch4_init },
3657 { 6, alc880_lg_ch6_init },
3660 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3661 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3662 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3663 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3664 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3665 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3666 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3667 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3668 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3671 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3672 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3673 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3674 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3676 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3677 .name = "Channel Mode",
3678 .info = alc_ch_mode_info,
3679 .get = alc_ch_mode_get,
3680 .put = alc_ch_mode_put,
3682 { } /* end */
3685 static struct hda_verb alc880_lg_init_verbs[] = {
3686 /* set capture source to mic-in */
3687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3688 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3689 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3690 /* mute all amp mixer inputs */
3691 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3692 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3693 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3694 /* line-in to input */
3695 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3696 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3697 /* built-in mic */
3698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3700 /* speaker-out */
3701 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3702 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3703 /* mic-in to input */
3704 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3705 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3706 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3707 /* HP-out */
3708 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3710 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3711 /* jack sense */
3712 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3716 /* toggle speaker-output according to the hp-jack state */
3717 static void alc880_lg_setup(struct hda_codec *codec)
3719 struct alc_spec *spec = codec->spec;
3721 spec->autocfg.hp_pins[0] = 0x1b;
3722 spec->autocfg.speaker_pins[0] = 0x17;
3726 * LG LW20
3728 * Pin assignment:
3729 * Speaker-out: 0x14
3730 * Mic-In: 0x18
3731 * Built-in Mic-In: 0x19
3732 * Line-In: 0x1b
3733 * HP-Out: 0x1a
3734 * SPDIF-Out: 0x1e
3737 static struct hda_input_mux alc880_lg_lw_capture_source = {
3738 .num_items = 3,
3739 .items = {
3740 { "Mic", 0x0 },
3741 { "Internal Mic", 0x1 },
3742 { "Line In", 0x2 },
3746 #define alc880_lg_lw_modes alc880_threestack_modes
3748 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3749 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3750 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3751 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3752 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3753 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3754 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3755 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3756 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3757 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3758 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3759 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3760 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3761 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3762 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3764 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3765 .name = "Channel Mode",
3766 .info = alc_ch_mode_info,
3767 .get = alc_ch_mode_get,
3768 .put = alc_ch_mode_put,
3770 { } /* end */
3773 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3774 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3775 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3776 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3778 /* set capture source to mic-in */
3779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3781 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3782 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3783 /* speaker-out */
3784 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3786 /* HP-out */
3787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3789 /* mic-in to input */
3790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3791 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3792 /* built-in mic */
3793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3795 /* jack sense */
3796 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3800 /* toggle speaker-output according to the hp-jack state */
3801 static void alc880_lg_lw_setup(struct hda_codec *codec)
3803 struct alc_spec *spec = codec->spec;
3805 spec->autocfg.hp_pins[0] = 0x1b;
3806 spec->autocfg.speaker_pins[0] = 0x14;
3809 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3810 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3811 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3812 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3813 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3814 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3815 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3816 { } /* end */
3819 static struct hda_input_mux alc880_medion_rim_capture_source = {
3820 .num_items = 2,
3821 .items = {
3822 { "Mic", 0x0 },
3823 { "Internal Mic", 0x1 },
3827 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3833 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3834 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3836 /* Mic2 (as headphone out) for HP output */
3837 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3839 /* Internal Speaker */
3840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3843 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3844 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3846 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3850 /* toggle speaker-output according to the hp-jack state */
3851 static void alc880_medion_rim_automute(struct hda_codec *codec)
3853 struct alc_spec *spec = codec->spec;
3854 alc_automute_amp(codec);
3855 /* toggle EAPD */
3856 if (spec->jack_present)
3857 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3858 else
3859 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3862 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3863 unsigned int res)
3865 /* Looks like the unsol event is incompatible with the standard
3866 * definition. 4bit tag is placed at 28 bit!
3868 if ((res >> 28) == ALC880_HP_EVENT)
3869 alc880_medion_rim_automute(codec);
3872 static void alc880_medion_rim_setup(struct hda_codec *codec)
3874 struct alc_spec *spec = codec->spec;
3876 spec->autocfg.hp_pins[0] = 0x14;
3877 spec->autocfg.speaker_pins[0] = 0x1b;
3880 #ifdef CONFIG_SND_HDA_POWER_SAVE
3881 static struct hda_amp_list alc880_loopbacks[] = {
3882 { 0x0b, HDA_INPUT, 0 },
3883 { 0x0b, HDA_INPUT, 1 },
3884 { 0x0b, HDA_INPUT, 2 },
3885 { 0x0b, HDA_INPUT, 3 },
3886 { 0x0b, HDA_INPUT, 4 },
3887 { } /* end */
3890 static struct hda_amp_list alc880_lg_loopbacks[] = {
3891 { 0x0b, HDA_INPUT, 1 },
3892 { 0x0b, HDA_INPUT, 6 },
3893 { 0x0b, HDA_INPUT, 7 },
3894 { } /* end */
3896 #endif
3899 * Common callbacks
3902 static int alc_init(struct hda_codec *codec)
3904 struct alc_spec *spec = codec->spec;
3905 unsigned int i;
3907 alc_fix_pll(codec);
3908 alc_auto_init_amp(codec, spec->init_amp);
3910 for (i = 0; i < spec->num_init_verbs; i++)
3911 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3913 if (spec->init_hook)
3914 spec->init_hook(codec);
3916 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3918 hda_call_check_power_status(codec, 0x01);
3919 return 0;
3922 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3924 struct alc_spec *spec = codec->spec;
3926 if (spec->unsol_event)
3927 spec->unsol_event(codec, res);
3930 #ifdef CONFIG_SND_HDA_POWER_SAVE
3931 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3933 struct alc_spec *spec = codec->spec;
3934 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3936 #endif
3939 * Analog playback callbacks
3941 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3942 struct hda_codec *codec,
3943 struct snd_pcm_substream *substream)
3945 struct alc_spec *spec = codec->spec;
3946 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3947 hinfo);
3950 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3951 struct hda_codec *codec,
3952 unsigned int stream_tag,
3953 unsigned int format,
3954 struct snd_pcm_substream *substream)
3956 struct alc_spec *spec = codec->spec;
3957 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3958 stream_tag, format, substream);
3961 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3962 struct hda_codec *codec,
3963 struct snd_pcm_substream *substream)
3965 struct alc_spec *spec = codec->spec;
3966 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3970 * Digital out
3972 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3973 struct hda_codec *codec,
3974 struct snd_pcm_substream *substream)
3976 struct alc_spec *spec = codec->spec;
3977 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3980 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3981 struct hda_codec *codec,
3982 unsigned int stream_tag,
3983 unsigned int format,
3984 struct snd_pcm_substream *substream)
3986 struct alc_spec *spec = codec->spec;
3987 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3988 stream_tag, format, substream);
3991 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3992 struct hda_codec *codec,
3993 struct snd_pcm_substream *substream)
3995 struct alc_spec *spec = codec->spec;
3996 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3999 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4000 struct hda_codec *codec,
4001 struct snd_pcm_substream *substream)
4003 struct alc_spec *spec = codec->spec;
4004 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4008 * Analog capture
4010 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4011 struct hda_codec *codec,
4012 unsigned int stream_tag,
4013 unsigned int format,
4014 struct snd_pcm_substream *substream)
4016 struct alc_spec *spec = codec->spec;
4018 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4019 stream_tag, 0, format);
4020 return 0;
4023 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4024 struct hda_codec *codec,
4025 struct snd_pcm_substream *substream)
4027 struct alc_spec *spec = codec->spec;
4029 snd_hda_codec_cleanup_stream(codec,
4030 spec->adc_nids[substream->number + 1]);
4031 return 0;
4034 /* analog capture with dynamic dual-adc changes */
4035 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4036 struct hda_codec *codec,
4037 unsigned int stream_tag,
4038 unsigned int format,
4039 struct snd_pcm_substream *substream)
4041 struct alc_spec *spec = codec->spec;
4042 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4043 spec->cur_adc_stream_tag = stream_tag;
4044 spec->cur_adc_format = format;
4045 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4046 return 0;
4049 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4050 struct hda_codec *codec,
4051 struct snd_pcm_substream *substream)
4053 struct alc_spec *spec = codec->spec;
4054 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4055 spec->cur_adc = 0;
4056 return 0;
4059 static struct hda_pcm_stream dualmic_pcm_analog_capture = {
4060 .substreams = 1,
4061 .channels_min = 2,
4062 .channels_max = 2,
4063 .nid = 0, /* fill later */
4064 .ops = {
4065 .prepare = dualmic_capture_pcm_prepare,
4066 .cleanup = dualmic_capture_pcm_cleanup
4072 static struct hda_pcm_stream alc880_pcm_analog_playback = {
4073 .substreams = 1,
4074 .channels_min = 2,
4075 .channels_max = 8,
4076 /* NID is set in alc_build_pcms */
4077 .ops = {
4078 .open = alc880_playback_pcm_open,
4079 .prepare = alc880_playback_pcm_prepare,
4080 .cleanup = alc880_playback_pcm_cleanup
4084 static struct hda_pcm_stream alc880_pcm_analog_capture = {
4085 .substreams = 1,
4086 .channels_min = 2,
4087 .channels_max = 2,
4088 /* NID is set in alc_build_pcms */
4091 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4092 .substreams = 1,
4093 .channels_min = 2,
4094 .channels_max = 2,
4095 /* NID is set in alc_build_pcms */
4098 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4099 .substreams = 2, /* can be overridden */
4100 .channels_min = 2,
4101 .channels_max = 2,
4102 /* NID is set in alc_build_pcms */
4103 .ops = {
4104 .prepare = alc880_alt_capture_pcm_prepare,
4105 .cleanup = alc880_alt_capture_pcm_cleanup
4109 static struct hda_pcm_stream alc880_pcm_digital_playback = {
4110 .substreams = 1,
4111 .channels_min = 2,
4112 .channels_max = 2,
4113 /* NID is set in alc_build_pcms */
4114 .ops = {
4115 .open = alc880_dig_playback_pcm_open,
4116 .close = alc880_dig_playback_pcm_close,
4117 .prepare = alc880_dig_playback_pcm_prepare,
4118 .cleanup = alc880_dig_playback_pcm_cleanup
4122 static struct hda_pcm_stream alc880_pcm_digital_capture = {
4123 .substreams = 1,
4124 .channels_min = 2,
4125 .channels_max = 2,
4126 /* NID is set in alc_build_pcms */
4129 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4130 static struct hda_pcm_stream alc_pcm_null_stream = {
4131 .substreams = 0,
4132 .channels_min = 0,
4133 .channels_max = 0,
4136 static int alc_build_pcms(struct hda_codec *codec)
4138 struct alc_spec *spec = codec->spec;
4139 struct hda_pcm *info = spec->pcm_rec;
4140 int i;
4142 codec->num_pcms = 1;
4143 codec->pcm_info = info;
4145 if (spec->no_analog)
4146 goto skip_analog;
4148 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4149 "%s Analog", codec->chip_name);
4150 info->name = spec->stream_name_analog;
4152 if (spec->stream_analog_playback) {
4153 if (snd_BUG_ON(!spec->multiout.dac_nids))
4154 return -EINVAL;
4155 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4156 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4158 if (spec->stream_analog_capture) {
4159 if (snd_BUG_ON(!spec->adc_nids))
4160 return -EINVAL;
4161 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4162 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4165 if (spec->channel_mode) {
4166 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4167 for (i = 0; i < spec->num_channel_mode; i++) {
4168 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4169 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4174 skip_analog:
4175 /* SPDIF for stream index #1 */
4176 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4177 snprintf(spec->stream_name_digital,
4178 sizeof(spec->stream_name_digital),
4179 "%s Digital", codec->chip_name);
4180 codec->num_pcms = 2;
4181 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4182 info = spec->pcm_rec + 1;
4183 info->name = spec->stream_name_digital;
4184 if (spec->dig_out_type)
4185 info->pcm_type = spec->dig_out_type;
4186 else
4187 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4188 if (spec->multiout.dig_out_nid &&
4189 spec->stream_digital_playback) {
4190 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4191 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4193 if (spec->dig_in_nid &&
4194 spec->stream_digital_capture) {
4195 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4196 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4198 /* FIXME: do we need this for all Realtek codec models? */
4199 codec->spdif_status_reset = 1;
4202 if (spec->no_analog)
4203 return 0;
4205 /* If the use of more than one ADC is requested for the current
4206 * model, configure a second analog capture-only PCM.
4208 /* Additional Analaog capture for index #2 */
4209 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4210 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4211 codec->num_pcms = 3;
4212 info = spec->pcm_rec + 2;
4213 info->name = spec->stream_name_analog;
4214 if (spec->alt_dac_nid) {
4215 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4216 *spec->stream_analog_alt_playback;
4217 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4218 spec->alt_dac_nid;
4219 } else {
4220 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4221 alc_pcm_null_stream;
4222 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4224 if (spec->num_adc_nids > 1) {
4225 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4226 *spec->stream_analog_alt_capture;
4227 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4228 spec->adc_nids[1];
4229 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4230 spec->num_adc_nids - 1;
4231 } else {
4232 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4233 alc_pcm_null_stream;
4234 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4238 return 0;
4241 static inline void alc_shutup(struct hda_codec *codec)
4243 snd_hda_shutup_pins(codec);
4246 static void alc_free_kctls(struct hda_codec *codec)
4248 struct alc_spec *spec = codec->spec;
4250 if (spec->kctls.list) {
4251 struct snd_kcontrol_new *kctl = spec->kctls.list;
4252 int i;
4253 for (i = 0; i < spec->kctls.used; i++)
4254 kfree(kctl[i].name);
4256 snd_array_free(&spec->kctls);
4259 static void alc_free(struct hda_codec *codec)
4261 struct alc_spec *spec = codec->spec;
4263 if (!spec)
4264 return;
4266 alc_shutup(codec);
4267 alc_free_kctls(codec);
4268 kfree(spec);
4269 snd_hda_detach_beep_device(codec);
4272 #ifdef CONFIG_SND_HDA_POWER_SAVE
4273 static void alc_power_eapd(struct hda_codec *codec)
4275 /* We currently only handle front, HP */
4276 switch (codec->vendor_id) {
4277 case 0x10ec0260:
4278 set_eapd(codec, 0x0f, 0);
4279 set_eapd(codec, 0x10, 0);
4280 break;
4281 case 0x10ec0262:
4282 case 0x10ec0267:
4283 case 0x10ec0268:
4284 case 0x10ec0269:
4285 case 0x10ec0270:
4286 case 0x10ec0272:
4287 case 0x10ec0660:
4288 case 0x10ec0662:
4289 case 0x10ec0663:
4290 case 0x10ec0862:
4291 case 0x10ec0889:
4292 set_eapd(codec, 0x14, 0);
4293 set_eapd(codec, 0x15, 0);
4294 break;
4298 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4300 struct alc_spec *spec = codec->spec;
4301 alc_shutup(codec);
4302 if (spec && spec->power_hook)
4303 spec->power_hook(codec);
4304 return 0;
4306 #endif
4308 #ifdef SND_HDA_NEEDS_RESUME
4309 static int alc_resume(struct hda_codec *codec)
4311 codec->patch_ops.init(codec);
4312 snd_hda_codec_resume_amp(codec);
4313 snd_hda_codec_resume_cache(codec);
4314 hda_call_check_power_status(codec, 0x01);
4315 return 0;
4317 #endif
4321 static struct hda_codec_ops alc_patch_ops = {
4322 .build_controls = alc_build_controls,
4323 .build_pcms = alc_build_pcms,
4324 .init = alc_init,
4325 .free = alc_free,
4326 .unsol_event = alc_unsol_event,
4327 #ifdef SND_HDA_NEEDS_RESUME
4328 .resume = alc_resume,
4329 #endif
4330 #ifdef CONFIG_SND_HDA_POWER_SAVE
4331 .suspend = alc_suspend,
4332 .check_power_status = alc_check_power_status,
4333 #endif
4334 .reboot_notify = alc_shutup,
4337 /* replace the codec chip_name with the given string */
4338 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4340 kfree(codec->chip_name);
4341 codec->chip_name = kstrdup(name, GFP_KERNEL);
4342 if (!codec->chip_name) {
4343 alc_free(codec);
4344 return -ENOMEM;
4346 return 0;
4350 * Test configuration for debugging
4352 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4353 * enum controls.
4355 #ifdef CONFIG_SND_DEBUG
4356 static hda_nid_t alc880_test_dac_nids[4] = {
4357 0x02, 0x03, 0x04, 0x05
4360 static struct hda_input_mux alc880_test_capture_source = {
4361 .num_items = 7,
4362 .items = {
4363 { "In-1", 0x0 },
4364 { "In-2", 0x1 },
4365 { "In-3", 0x2 },
4366 { "In-4", 0x3 },
4367 { "CD", 0x4 },
4368 { "Front", 0x5 },
4369 { "Surround", 0x6 },
4373 static struct hda_channel_mode alc880_test_modes[4] = {
4374 { 2, NULL },
4375 { 4, NULL },
4376 { 6, NULL },
4377 { 8, NULL },
4380 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4381 struct snd_ctl_elem_info *uinfo)
4383 static char *texts[] = {
4384 "N/A", "Line Out", "HP Out",
4385 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4387 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4388 uinfo->count = 1;
4389 uinfo->value.enumerated.items = 8;
4390 if (uinfo->value.enumerated.item >= 8)
4391 uinfo->value.enumerated.item = 7;
4392 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4393 return 0;
4396 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4397 struct snd_ctl_elem_value *ucontrol)
4399 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4400 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4401 unsigned int pin_ctl, item = 0;
4403 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4404 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4405 if (pin_ctl & AC_PINCTL_OUT_EN) {
4406 if (pin_ctl & AC_PINCTL_HP_EN)
4407 item = 2;
4408 else
4409 item = 1;
4410 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4411 switch (pin_ctl & AC_PINCTL_VREFEN) {
4412 case AC_PINCTL_VREF_HIZ: item = 3; break;
4413 case AC_PINCTL_VREF_50: item = 4; break;
4414 case AC_PINCTL_VREF_GRD: item = 5; break;
4415 case AC_PINCTL_VREF_80: item = 6; break;
4416 case AC_PINCTL_VREF_100: item = 7; break;
4419 ucontrol->value.enumerated.item[0] = item;
4420 return 0;
4423 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4424 struct snd_ctl_elem_value *ucontrol)
4426 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4427 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4428 static unsigned int ctls[] = {
4429 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4430 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4431 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4432 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4433 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4434 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4436 unsigned int old_ctl, new_ctl;
4438 old_ctl = snd_hda_codec_read(codec, nid, 0,
4439 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4440 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4441 if (old_ctl != new_ctl) {
4442 int val;
4443 snd_hda_codec_write_cache(codec, nid, 0,
4444 AC_VERB_SET_PIN_WIDGET_CONTROL,
4445 new_ctl);
4446 val = ucontrol->value.enumerated.item[0] >= 3 ?
4447 HDA_AMP_MUTE : 0;
4448 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4449 HDA_AMP_MUTE, val);
4450 return 1;
4452 return 0;
4455 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4456 struct snd_ctl_elem_info *uinfo)
4458 static char *texts[] = {
4459 "Front", "Surround", "CLFE", "Side"
4461 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4462 uinfo->count = 1;
4463 uinfo->value.enumerated.items = 4;
4464 if (uinfo->value.enumerated.item >= 4)
4465 uinfo->value.enumerated.item = 3;
4466 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4467 return 0;
4470 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4471 struct snd_ctl_elem_value *ucontrol)
4473 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4474 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4475 unsigned int sel;
4477 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4478 ucontrol->value.enumerated.item[0] = sel & 3;
4479 return 0;
4482 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4483 struct snd_ctl_elem_value *ucontrol)
4485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4486 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4487 unsigned int sel;
4489 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4490 if (ucontrol->value.enumerated.item[0] != sel) {
4491 sel = ucontrol->value.enumerated.item[0] & 3;
4492 snd_hda_codec_write_cache(codec, nid, 0,
4493 AC_VERB_SET_CONNECT_SEL, sel);
4494 return 1;
4496 return 0;
4499 #define PIN_CTL_TEST(xname,nid) { \
4500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4501 .name = xname, \
4502 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4503 .info = alc_test_pin_ctl_info, \
4504 .get = alc_test_pin_ctl_get, \
4505 .put = alc_test_pin_ctl_put, \
4506 .private_value = nid \
4509 #define PIN_SRC_TEST(xname,nid) { \
4510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4511 .name = xname, \
4512 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4513 .info = alc_test_pin_src_info, \
4514 .get = alc_test_pin_src_get, \
4515 .put = alc_test_pin_src_put, \
4516 .private_value = nid \
4519 static struct snd_kcontrol_new alc880_test_mixer[] = {
4520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4521 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4522 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4523 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4524 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4525 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4526 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4527 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4528 PIN_CTL_TEST("Front Pin Mode", 0x14),
4529 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4530 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4531 PIN_CTL_TEST("Side Pin Mode", 0x17),
4532 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4533 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4534 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4535 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4536 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4537 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4538 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4539 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4540 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4541 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4542 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4543 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4544 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4545 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4546 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4547 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4548 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4549 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4551 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4552 .name = "Channel Mode",
4553 .info = alc_ch_mode_info,
4554 .get = alc_ch_mode_get,
4555 .put = alc_ch_mode_put,
4557 { } /* end */
4560 static struct hda_verb alc880_test_init_verbs[] = {
4561 /* Unmute inputs of 0x0c - 0x0f */
4562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4568 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4569 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4570 /* Vol output for 0x0c-0x0f */
4571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4574 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4575 /* Set output pins 0x14-0x17 */
4576 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4577 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4578 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4580 /* Unmute output pins 0x14-0x17 */
4581 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4583 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4584 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4585 /* Set input pins 0x18-0x1c */
4586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4590 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4591 /* Mute input pins 0x18-0x1b */
4592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4594 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4595 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4596 /* ADC set up */
4597 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4598 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4599 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4600 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4601 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4602 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4603 /* Analog input/passthru */
4604 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4605 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4606 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4607 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4608 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4611 #endif
4616 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4617 [ALC880_3ST] = "3stack",
4618 [ALC880_TCL_S700] = "tcl",
4619 [ALC880_3ST_DIG] = "3stack-digout",
4620 [ALC880_CLEVO] = "clevo",
4621 [ALC880_5ST] = "5stack",
4622 [ALC880_5ST_DIG] = "5stack-digout",
4623 [ALC880_W810] = "w810",
4624 [ALC880_Z71V] = "z71v",
4625 [ALC880_6ST] = "6stack",
4626 [ALC880_6ST_DIG] = "6stack-digout",
4627 [ALC880_ASUS] = "asus",
4628 [ALC880_ASUS_W1V] = "asus-w1v",
4629 [ALC880_ASUS_DIG] = "asus-dig",
4630 [ALC880_ASUS_DIG2] = "asus-dig2",
4631 [ALC880_UNIWILL_DIG] = "uniwill",
4632 [ALC880_UNIWILL_P53] = "uniwill-p53",
4633 [ALC880_FUJITSU] = "fujitsu",
4634 [ALC880_F1734] = "F1734",
4635 [ALC880_LG] = "lg",
4636 [ALC880_LG_LW] = "lg-lw",
4637 [ALC880_MEDION_RIM] = "medion",
4638 #ifdef CONFIG_SND_DEBUG
4639 [ALC880_TEST] = "test",
4640 #endif
4641 [ALC880_AUTO] = "auto",
4644 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4645 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4646 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4647 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4648 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4649 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4650 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4651 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4652 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4653 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4654 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4655 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4656 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4657 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4658 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4659 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4660 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4661 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4662 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4663 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4664 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4665 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4666 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4667 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4668 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4669 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4670 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4671 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4672 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4673 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4674 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4675 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4676 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4677 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4678 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4679 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4680 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4681 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4682 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4683 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4684 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4685 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4686 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4687 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4688 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4689 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4690 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4691 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4692 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4693 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4694 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4695 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4696 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4697 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4698 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4699 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4700 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4701 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4702 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4703 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4704 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4705 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4706 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4707 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4708 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4709 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4710 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4711 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4712 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4713 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4714 /* default Intel */
4715 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4716 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4717 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4722 * ALC880 codec presets
4724 static struct alc_config_preset alc880_presets[] = {
4725 [ALC880_3ST] = {
4726 .mixers = { alc880_three_stack_mixer },
4727 .init_verbs = { alc880_volume_init_verbs,
4728 alc880_pin_3stack_init_verbs },
4729 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4730 .dac_nids = alc880_dac_nids,
4731 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4732 .channel_mode = alc880_threestack_modes,
4733 .need_dac_fix = 1,
4734 .input_mux = &alc880_capture_source,
4736 [ALC880_3ST_DIG] = {
4737 .mixers = { alc880_three_stack_mixer },
4738 .init_verbs = { alc880_volume_init_verbs,
4739 alc880_pin_3stack_init_verbs },
4740 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4741 .dac_nids = alc880_dac_nids,
4742 .dig_out_nid = ALC880_DIGOUT_NID,
4743 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4744 .channel_mode = alc880_threestack_modes,
4745 .need_dac_fix = 1,
4746 .input_mux = &alc880_capture_source,
4748 [ALC880_TCL_S700] = {
4749 .mixers = { alc880_tcl_s700_mixer },
4750 .init_verbs = { alc880_volume_init_verbs,
4751 alc880_pin_tcl_S700_init_verbs,
4752 alc880_gpio2_init_verbs },
4753 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4754 .dac_nids = alc880_dac_nids,
4755 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4756 .num_adc_nids = 1, /* single ADC */
4757 .hp_nid = 0x03,
4758 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4759 .channel_mode = alc880_2_jack_modes,
4760 .input_mux = &alc880_capture_source,
4762 [ALC880_5ST] = {
4763 .mixers = { alc880_three_stack_mixer,
4764 alc880_five_stack_mixer},
4765 .init_verbs = { alc880_volume_init_verbs,
4766 alc880_pin_5stack_init_verbs },
4767 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4768 .dac_nids = alc880_dac_nids,
4769 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4770 .channel_mode = alc880_fivestack_modes,
4771 .input_mux = &alc880_capture_source,
4773 [ALC880_5ST_DIG] = {
4774 .mixers = { alc880_three_stack_mixer,
4775 alc880_five_stack_mixer },
4776 .init_verbs = { alc880_volume_init_verbs,
4777 alc880_pin_5stack_init_verbs },
4778 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4779 .dac_nids = alc880_dac_nids,
4780 .dig_out_nid = ALC880_DIGOUT_NID,
4781 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4782 .channel_mode = alc880_fivestack_modes,
4783 .input_mux = &alc880_capture_source,
4785 [ALC880_6ST] = {
4786 .mixers = { alc880_six_stack_mixer },
4787 .init_verbs = { alc880_volume_init_verbs,
4788 alc880_pin_6stack_init_verbs },
4789 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4790 .dac_nids = alc880_6st_dac_nids,
4791 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4792 .channel_mode = alc880_sixstack_modes,
4793 .input_mux = &alc880_6stack_capture_source,
4795 [ALC880_6ST_DIG] = {
4796 .mixers = { alc880_six_stack_mixer },
4797 .init_verbs = { alc880_volume_init_verbs,
4798 alc880_pin_6stack_init_verbs },
4799 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4800 .dac_nids = alc880_6st_dac_nids,
4801 .dig_out_nid = ALC880_DIGOUT_NID,
4802 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4803 .channel_mode = alc880_sixstack_modes,
4804 .input_mux = &alc880_6stack_capture_source,
4806 [ALC880_W810] = {
4807 .mixers = { alc880_w810_base_mixer },
4808 .init_verbs = { alc880_volume_init_verbs,
4809 alc880_pin_w810_init_verbs,
4810 alc880_gpio2_init_verbs },
4811 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4812 .dac_nids = alc880_w810_dac_nids,
4813 .dig_out_nid = ALC880_DIGOUT_NID,
4814 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4815 .channel_mode = alc880_w810_modes,
4816 .input_mux = &alc880_capture_source,
4818 [ALC880_Z71V] = {
4819 .mixers = { alc880_z71v_mixer },
4820 .init_verbs = { alc880_volume_init_verbs,
4821 alc880_pin_z71v_init_verbs },
4822 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4823 .dac_nids = alc880_z71v_dac_nids,
4824 .dig_out_nid = ALC880_DIGOUT_NID,
4825 .hp_nid = 0x03,
4826 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4827 .channel_mode = alc880_2_jack_modes,
4828 .input_mux = &alc880_capture_source,
4830 [ALC880_F1734] = {
4831 .mixers = { alc880_f1734_mixer },
4832 .init_verbs = { alc880_volume_init_verbs,
4833 alc880_pin_f1734_init_verbs },
4834 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4835 .dac_nids = alc880_f1734_dac_nids,
4836 .hp_nid = 0x02,
4837 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4838 .channel_mode = alc880_2_jack_modes,
4839 .input_mux = &alc880_f1734_capture_source,
4840 .unsol_event = alc880_uniwill_p53_unsol_event,
4841 .setup = alc880_uniwill_p53_setup,
4842 .init_hook = alc_automute_amp,
4844 [ALC880_ASUS] = {
4845 .mixers = { alc880_asus_mixer },
4846 .init_verbs = { alc880_volume_init_verbs,
4847 alc880_pin_asus_init_verbs,
4848 alc880_gpio1_init_verbs },
4849 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4850 .dac_nids = alc880_asus_dac_nids,
4851 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4852 .channel_mode = alc880_asus_modes,
4853 .need_dac_fix = 1,
4854 .input_mux = &alc880_capture_source,
4856 [ALC880_ASUS_DIG] = {
4857 .mixers = { alc880_asus_mixer },
4858 .init_verbs = { alc880_volume_init_verbs,
4859 alc880_pin_asus_init_verbs,
4860 alc880_gpio1_init_verbs },
4861 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4862 .dac_nids = alc880_asus_dac_nids,
4863 .dig_out_nid = ALC880_DIGOUT_NID,
4864 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4865 .channel_mode = alc880_asus_modes,
4866 .need_dac_fix = 1,
4867 .input_mux = &alc880_capture_source,
4869 [ALC880_ASUS_DIG2] = {
4870 .mixers = { alc880_asus_mixer },
4871 .init_verbs = { alc880_volume_init_verbs,
4872 alc880_pin_asus_init_verbs,
4873 alc880_gpio2_init_verbs }, /* use GPIO2 */
4874 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4875 .dac_nids = alc880_asus_dac_nids,
4876 .dig_out_nid = ALC880_DIGOUT_NID,
4877 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4878 .channel_mode = alc880_asus_modes,
4879 .need_dac_fix = 1,
4880 .input_mux = &alc880_capture_source,
4882 [ALC880_ASUS_W1V] = {
4883 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4884 .init_verbs = { alc880_volume_init_verbs,
4885 alc880_pin_asus_init_verbs,
4886 alc880_gpio1_init_verbs },
4887 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4888 .dac_nids = alc880_asus_dac_nids,
4889 .dig_out_nid = ALC880_DIGOUT_NID,
4890 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4891 .channel_mode = alc880_asus_modes,
4892 .need_dac_fix = 1,
4893 .input_mux = &alc880_capture_source,
4895 [ALC880_UNIWILL_DIG] = {
4896 .mixers = { alc880_asus_mixer },
4897 .init_verbs = { alc880_volume_init_verbs,
4898 alc880_pin_asus_init_verbs },
4899 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4900 .dac_nids = alc880_asus_dac_nids,
4901 .dig_out_nid = ALC880_DIGOUT_NID,
4902 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4903 .channel_mode = alc880_asus_modes,
4904 .need_dac_fix = 1,
4905 .input_mux = &alc880_capture_source,
4907 [ALC880_UNIWILL] = {
4908 .mixers = { alc880_uniwill_mixer },
4909 .init_verbs = { alc880_volume_init_verbs,
4910 alc880_uniwill_init_verbs },
4911 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4912 .dac_nids = alc880_asus_dac_nids,
4913 .dig_out_nid = ALC880_DIGOUT_NID,
4914 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4915 .channel_mode = alc880_threestack_modes,
4916 .need_dac_fix = 1,
4917 .input_mux = &alc880_capture_source,
4918 .unsol_event = alc880_uniwill_unsol_event,
4919 .setup = alc880_uniwill_setup,
4920 .init_hook = alc880_uniwill_init_hook,
4922 [ALC880_UNIWILL_P53] = {
4923 .mixers = { alc880_uniwill_p53_mixer },
4924 .init_verbs = { alc880_volume_init_verbs,
4925 alc880_uniwill_p53_init_verbs },
4926 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4927 .dac_nids = alc880_asus_dac_nids,
4928 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4929 .channel_mode = alc880_threestack_modes,
4930 .input_mux = &alc880_capture_source,
4931 .unsol_event = alc880_uniwill_p53_unsol_event,
4932 .setup = alc880_uniwill_p53_setup,
4933 .init_hook = alc_automute_amp,
4935 [ALC880_FUJITSU] = {
4936 .mixers = { alc880_fujitsu_mixer },
4937 .init_verbs = { alc880_volume_init_verbs,
4938 alc880_uniwill_p53_init_verbs,
4939 alc880_beep_init_verbs },
4940 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4941 .dac_nids = alc880_dac_nids,
4942 .dig_out_nid = ALC880_DIGOUT_NID,
4943 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4944 .channel_mode = alc880_2_jack_modes,
4945 .input_mux = &alc880_capture_source,
4946 .unsol_event = alc880_uniwill_p53_unsol_event,
4947 .setup = alc880_uniwill_p53_setup,
4948 .init_hook = alc_automute_amp,
4950 [ALC880_CLEVO] = {
4951 .mixers = { alc880_three_stack_mixer },
4952 .init_verbs = { alc880_volume_init_verbs,
4953 alc880_pin_clevo_init_verbs },
4954 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4955 .dac_nids = alc880_dac_nids,
4956 .hp_nid = 0x03,
4957 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4958 .channel_mode = alc880_threestack_modes,
4959 .need_dac_fix = 1,
4960 .input_mux = &alc880_capture_source,
4962 [ALC880_LG] = {
4963 .mixers = { alc880_lg_mixer },
4964 .init_verbs = { alc880_volume_init_verbs,
4965 alc880_lg_init_verbs },
4966 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4967 .dac_nids = alc880_lg_dac_nids,
4968 .dig_out_nid = ALC880_DIGOUT_NID,
4969 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4970 .channel_mode = alc880_lg_ch_modes,
4971 .need_dac_fix = 1,
4972 .input_mux = &alc880_lg_capture_source,
4973 .unsol_event = alc_automute_amp_unsol_event,
4974 .setup = alc880_lg_setup,
4975 .init_hook = alc_automute_amp,
4976 #ifdef CONFIG_SND_HDA_POWER_SAVE
4977 .loopbacks = alc880_lg_loopbacks,
4978 #endif
4980 [ALC880_LG_LW] = {
4981 .mixers = { alc880_lg_lw_mixer },
4982 .init_verbs = { alc880_volume_init_verbs,
4983 alc880_lg_lw_init_verbs },
4984 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4985 .dac_nids = alc880_dac_nids,
4986 .dig_out_nid = ALC880_DIGOUT_NID,
4987 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4988 .channel_mode = alc880_lg_lw_modes,
4989 .input_mux = &alc880_lg_lw_capture_source,
4990 .unsol_event = alc_automute_amp_unsol_event,
4991 .setup = alc880_lg_lw_setup,
4992 .init_hook = alc_automute_amp,
4994 [ALC880_MEDION_RIM] = {
4995 .mixers = { alc880_medion_rim_mixer },
4996 .init_verbs = { alc880_volume_init_verbs,
4997 alc880_medion_rim_init_verbs,
4998 alc_gpio2_init_verbs },
4999 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5000 .dac_nids = alc880_dac_nids,
5001 .dig_out_nid = ALC880_DIGOUT_NID,
5002 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5003 .channel_mode = alc880_2_jack_modes,
5004 .input_mux = &alc880_medion_rim_capture_source,
5005 .unsol_event = alc880_medion_rim_unsol_event,
5006 .setup = alc880_medion_rim_setup,
5007 .init_hook = alc880_medion_rim_automute,
5009 #ifdef CONFIG_SND_DEBUG
5010 [ALC880_TEST] = {
5011 .mixers = { alc880_test_mixer },
5012 .init_verbs = { alc880_test_init_verbs },
5013 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5014 .dac_nids = alc880_test_dac_nids,
5015 .dig_out_nid = ALC880_DIGOUT_NID,
5016 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5017 .channel_mode = alc880_test_modes,
5018 .input_mux = &alc880_test_capture_source,
5020 #endif
5024 * Automatic parse of I/O pins from the BIOS configuration
5027 enum {
5028 ALC_CTL_WIDGET_VOL,
5029 ALC_CTL_WIDGET_MUTE,
5030 ALC_CTL_BIND_MUTE,
5032 static struct snd_kcontrol_new alc880_control_templates[] = {
5033 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5034 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5035 HDA_BIND_MUTE(NULL, 0, 0, 0),
5038 /* add dynamic controls */
5039 static int add_control(struct alc_spec *spec, int type, const char *name,
5040 int cidx, unsigned long val)
5042 struct snd_kcontrol_new *knew;
5044 snd_array_init(&spec->kctls, sizeof(*knew), 32);
5045 knew = snd_array_new(&spec->kctls);
5046 if (!knew)
5047 return -ENOMEM;
5048 *knew = alc880_control_templates[type];
5049 knew->name = kstrdup(name, GFP_KERNEL);
5050 if (!knew->name)
5051 return -ENOMEM;
5052 knew->index = cidx;
5053 if (get_amp_nid_(val))
5054 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5055 knew->private_value = val;
5056 return 0;
5059 static int add_control_with_pfx(struct alc_spec *spec, int type,
5060 const char *pfx, const char *dir,
5061 const char *sfx, int cidx, unsigned long val)
5063 char name[32];
5064 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5065 return add_control(spec, type, name, cidx, val);
5068 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5069 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5070 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5071 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5072 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5073 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5074 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5075 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5077 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5078 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5079 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5080 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5081 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5082 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5083 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5084 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5085 #define ALC880_PIN_CD_NID 0x1c
5087 /* fill in the dac_nids table from the parsed pin configuration */
5088 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5089 const struct auto_pin_cfg *cfg)
5091 hda_nid_t nid;
5092 int assigned[4];
5093 int i, j;
5095 memset(assigned, 0, sizeof(assigned));
5096 spec->multiout.dac_nids = spec->private_dac_nids;
5098 /* check the pins hardwired to audio widget */
5099 for (i = 0; i < cfg->line_outs; i++) {
5100 nid = cfg->line_out_pins[i];
5101 if (alc880_is_fixed_pin(nid)) {
5102 int idx = alc880_fixed_pin_idx(nid);
5103 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
5104 assigned[idx] = 1;
5107 /* left pins can be connect to any audio widget */
5108 for (i = 0; i < cfg->line_outs; i++) {
5109 nid = cfg->line_out_pins[i];
5110 if (alc880_is_fixed_pin(nid))
5111 continue;
5112 /* search for an empty channel */
5113 for (j = 0; j < cfg->line_outs; j++) {
5114 if (!assigned[j]) {
5115 spec->multiout.dac_nids[i] =
5116 alc880_idx_to_dac(j);
5117 assigned[j] = 1;
5118 break;
5122 spec->multiout.num_dacs = cfg->line_outs;
5123 return 0;
5126 static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5127 bool can_be_master)
5129 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5130 return "Master";
5132 switch (cfg->line_out_type) {
5133 case AUTO_PIN_SPEAKER_OUT:
5134 return "Speaker";
5135 case AUTO_PIN_HP_OUT:
5136 return "Headphone";
5137 default:
5138 if (cfg->line_outs == 1)
5139 return "PCM";
5140 break;
5142 return NULL;
5145 /* add playback controls from the parsed DAC table */
5146 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5147 const struct auto_pin_cfg *cfg)
5149 static const char * const chname[4] = {
5150 "Front", "Surround", NULL /*CLFE*/, "Side"
5152 const char *pfx = alc_get_line_out_pfx(cfg, false);
5153 hda_nid_t nid;
5154 int i, err;
5156 for (i = 0; i < cfg->line_outs; i++) {
5157 if (!spec->multiout.dac_nids[i])
5158 continue;
5159 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5160 if (!pfx && i == 2) {
5161 /* Center/LFE */
5162 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5163 "Center",
5164 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5165 HDA_OUTPUT));
5166 if (err < 0)
5167 return err;
5168 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5169 "LFE",
5170 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5171 HDA_OUTPUT));
5172 if (err < 0)
5173 return err;
5174 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5175 "Center",
5176 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5177 HDA_INPUT));
5178 if (err < 0)
5179 return err;
5180 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5181 "LFE",
5182 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5183 HDA_INPUT));
5184 if (err < 0)
5185 return err;
5186 } else {
5187 const char *name = pfx;
5188 if (!name)
5189 name = chname[i];
5190 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5191 name, i,
5192 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5193 HDA_OUTPUT));
5194 if (err < 0)
5195 return err;
5196 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5197 name, i,
5198 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5199 HDA_INPUT));
5200 if (err < 0)
5201 return err;
5204 return 0;
5207 /* add playback controls for speaker and HP outputs */
5208 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5209 const char *pfx)
5211 hda_nid_t nid;
5212 int err;
5214 if (!pin)
5215 return 0;
5217 if (alc880_is_fixed_pin(pin)) {
5218 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5219 /* specify the DAC as the extra output */
5220 if (!spec->multiout.hp_nid)
5221 spec->multiout.hp_nid = nid;
5222 else
5223 spec->multiout.extra_out_nid[0] = nid;
5224 /* control HP volume/switch on the output mixer amp */
5225 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5226 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5227 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5228 if (err < 0)
5229 return err;
5230 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5231 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5232 if (err < 0)
5233 return err;
5234 } else if (alc880_is_multi_pin(pin)) {
5235 /* set manual connection */
5236 /* we have only a switch on HP-out PIN */
5237 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5238 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5239 if (err < 0)
5240 return err;
5242 return 0;
5245 /* create input playback/capture controls for the given pin */
5246 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5247 const char *ctlname, int ctlidx,
5248 int idx, hda_nid_t mix_nid)
5250 int err;
5252 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5253 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5254 if (err < 0)
5255 return err;
5256 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5257 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5258 if (err < 0)
5259 return err;
5260 return 0;
5263 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5265 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5266 return (pincap & AC_PINCAP_IN) != 0;
5269 /* create playback/capture controls for input pins */
5270 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5271 const struct auto_pin_cfg *cfg,
5272 hda_nid_t mixer,
5273 hda_nid_t cap1, hda_nid_t cap2)
5275 struct alc_spec *spec = codec->spec;
5276 struct hda_input_mux *imux = &spec->private_imux[0];
5277 int i, err, idx, type_idx = 0;
5278 const char *prev_label = NULL;
5280 for (i = 0; i < cfg->num_inputs; i++) {
5281 hda_nid_t pin;
5282 const char *label;
5284 pin = cfg->inputs[i].pin;
5285 if (!alc_is_input_pin(codec, pin))
5286 continue;
5288 label = hda_get_autocfg_input_label(codec, cfg, i);
5289 if (prev_label && !strcmp(label, prev_label))
5290 type_idx++;
5291 else
5292 type_idx = 0;
5293 prev_label = label;
5295 if (mixer) {
5296 idx = get_connection_index(codec, mixer, pin);
5297 if (idx >= 0) {
5298 err = new_analog_input(spec, pin,
5299 label, type_idx,
5300 idx, mixer);
5301 if (err < 0)
5302 return err;
5306 if (!cap1)
5307 continue;
5308 idx = get_connection_index(codec, cap1, pin);
5309 if (idx < 0 && cap2)
5310 idx = get_connection_index(codec, cap2, pin);
5311 if (idx >= 0)
5312 snd_hda_add_imux_item(imux, label, idx, NULL);
5314 return 0;
5317 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5318 const struct auto_pin_cfg *cfg)
5320 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5323 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5324 unsigned int pin_type)
5326 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5327 pin_type);
5328 /* unmute pin */
5329 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5330 AMP_OUT_UNMUTE);
5333 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5334 hda_nid_t nid, int pin_type,
5335 int dac_idx)
5337 alc_set_pin_output(codec, nid, pin_type);
5338 /* need the manual connection? */
5339 if (alc880_is_multi_pin(nid)) {
5340 struct alc_spec *spec = codec->spec;
5341 int idx = alc880_multi_pin_idx(nid);
5342 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5343 AC_VERB_SET_CONNECT_SEL,
5344 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5348 static int get_pin_type(int line_out_type)
5350 if (line_out_type == AUTO_PIN_HP_OUT)
5351 return PIN_HP;
5352 else
5353 return PIN_OUT;
5356 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5358 struct alc_spec *spec = codec->spec;
5359 int i;
5361 for (i = 0; i < spec->autocfg.line_outs; i++) {
5362 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5363 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5364 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5368 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5370 struct alc_spec *spec = codec->spec;
5371 hda_nid_t pin;
5373 pin = spec->autocfg.speaker_pins[0];
5374 if (pin) /* connect to front */
5375 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5376 pin = spec->autocfg.hp_pins[0];
5377 if (pin) /* connect to front */
5378 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5381 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5383 struct alc_spec *spec = codec->spec;
5384 struct auto_pin_cfg *cfg = &spec->autocfg;
5385 int i;
5387 for (i = 0; i < cfg->num_inputs; i++) {
5388 hda_nid_t nid = cfg->inputs[i].pin;
5389 if (alc_is_input_pin(codec, nid)) {
5390 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5391 if (nid != ALC880_PIN_CD_NID &&
5392 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5393 snd_hda_codec_write(codec, nid, 0,
5394 AC_VERB_SET_AMP_GAIN_MUTE,
5395 AMP_OUT_MUTE);
5400 static void alc880_auto_init_input_src(struct hda_codec *codec)
5402 struct alc_spec *spec = codec->spec;
5403 int c;
5405 for (c = 0; c < spec->num_adc_nids; c++) {
5406 unsigned int mux_idx;
5407 const struct hda_input_mux *imux;
5408 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5409 imux = &spec->input_mux[mux_idx];
5410 if (!imux->num_items && mux_idx > 0)
5411 imux = &spec->input_mux[0];
5412 if (imux)
5413 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5414 AC_VERB_SET_CONNECT_SEL,
5415 imux->items[0].index);
5419 /* parse the BIOS configuration and set up the alc_spec */
5420 /* return 1 if successful, 0 if the proper config is not found,
5421 * or a negative error code
5423 static int alc880_parse_auto_config(struct hda_codec *codec)
5425 struct alc_spec *spec = codec->spec;
5426 int err;
5427 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5429 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5430 alc880_ignore);
5431 if (err < 0)
5432 return err;
5433 if (!spec->autocfg.line_outs)
5434 return 0; /* can't find valid BIOS pin config */
5436 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5437 if (err < 0)
5438 return err;
5439 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5440 if (err < 0)
5441 return err;
5442 err = alc880_auto_create_extra_out(spec,
5443 spec->autocfg.speaker_pins[0],
5444 "Speaker");
5445 if (err < 0)
5446 return err;
5447 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5448 "Headphone");
5449 if (err < 0)
5450 return err;
5451 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5452 if (err < 0)
5453 return err;
5455 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5457 alc_auto_parse_digital(codec);
5459 if (spec->kctls.list)
5460 add_mixer(spec, spec->kctls.list);
5462 add_verb(spec, alc880_volume_init_verbs);
5464 spec->num_mux_defs = 1;
5465 spec->input_mux = &spec->private_imux[0];
5467 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5469 return 1;
5472 /* additional initialization for auto-configuration model */
5473 static void alc880_auto_init(struct hda_codec *codec)
5475 struct alc_spec *spec = codec->spec;
5476 alc880_auto_init_multi_out(codec);
5477 alc880_auto_init_extra_out(codec);
5478 alc880_auto_init_analog_input(codec);
5479 alc880_auto_init_input_src(codec);
5480 alc_auto_init_digital(codec);
5481 if (spec->unsol_event)
5482 alc_inithook(codec);
5485 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5486 * one of two digital mic pins, e.g. on ALC272
5488 static void fixup_automic_adc(struct hda_codec *codec)
5490 struct alc_spec *spec = codec->spec;
5491 int i;
5493 for (i = 0; i < spec->num_adc_nids; i++) {
5494 hda_nid_t cap = spec->capsrc_nids ?
5495 spec->capsrc_nids[i] : spec->adc_nids[i];
5496 int iidx, eidx;
5498 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5499 if (iidx < 0)
5500 continue;
5501 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5502 if (eidx < 0)
5503 continue;
5504 spec->int_mic.mux_idx = iidx;
5505 spec->ext_mic.mux_idx = eidx;
5506 if (spec->capsrc_nids)
5507 spec->capsrc_nids += i;
5508 spec->adc_nids += i;
5509 spec->num_adc_nids = 1;
5510 return;
5512 snd_printd(KERN_INFO "hda_codec: %s: "
5513 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5514 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5515 spec->auto_mic = 0; /* disable auto-mic to be sure */
5518 /* select or unmute the given capsrc route */
5519 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5520 int idx)
5522 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5523 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5524 HDA_AMP_MUTE, 0);
5525 } else {
5526 snd_hda_codec_write_cache(codec, cap, 0,
5527 AC_VERB_SET_CONNECT_SEL, idx);
5531 /* set the default connection to that pin */
5532 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5534 struct alc_spec *spec = codec->spec;
5535 int i;
5537 for (i = 0; i < spec->num_adc_nids; i++) {
5538 hda_nid_t cap = spec->capsrc_nids ?
5539 spec->capsrc_nids[i] : spec->adc_nids[i];
5540 int idx;
5542 idx = get_connection_index(codec, cap, pin);
5543 if (idx < 0)
5544 continue;
5545 select_or_unmute_capsrc(codec, cap, idx);
5546 return i; /* return the found index */
5548 return -1; /* not found */
5551 /* choose the ADC/MUX containing the input pin and initialize the setup */
5552 static void fixup_single_adc(struct hda_codec *codec)
5554 struct alc_spec *spec = codec->spec;
5555 struct auto_pin_cfg *cfg = &spec->autocfg;
5556 int i;
5558 /* search for the input pin; there must be only one */
5559 if (cfg->num_inputs != 1)
5560 return;
5561 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5562 if (i >= 0) {
5563 /* use only this ADC */
5564 if (spec->capsrc_nids)
5565 spec->capsrc_nids += i;
5566 spec->adc_nids += i;
5567 spec->num_adc_nids = 1;
5571 /* initialize dual adcs */
5572 static void fixup_dual_adc_switch(struct hda_codec *codec)
5574 struct alc_spec *spec = codec->spec;
5575 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5576 init_capsrc_for_pin(codec, spec->int_mic.pin);
5579 static void set_capture_mixer(struct hda_codec *codec)
5581 struct alc_spec *spec = codec->spec;
5582 static struct snd_kcontrol_new *caps[2][3] = {
5583 { alc_capture_mixer_nosrc1,
5584 alc_capture_mixer_nosrc2,
5585 alc_capture_mixer_nosrc3 },
5586 { alc_capture_mixer1,
5587 alc_capture_mixer2,
5588 alc_capture_mixer3 },
5590 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5591 int mux = 0;
5592 int num_adcs = spec->num_adc_nids;
5593 if (spec->dual_adc_switch)
5594 fixup_dual_adc_switch(codec);
5595 else if (spec->auto_mic)
5596 fixup_automic_adc(codec);
5597 else if (spec->input_mux) {
5598 if (spec->input_mux->num_items > 1)
5599 mux = 1;
5600 else if (spec->input_mux->num_items == 1)
5601 fixup_single_adc(codec);
5603 if (spec->dual_adc_switch)
5604 num_adcs = 1;
5605 spec->cap_mixer = caps[mux][num_adcs - 1];
5609 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5610 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5611 int num_nids)
5613 struct alc_spec *spec = codec->spec;
5614 struct auto_pin_cfg *cfg = &spec->autocfg;
5615 int n;
5616 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5618 for (n = 0; n < num_nids; n++) {
5619 hda_nid_t adc, cap;
5620 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5621 int nconns, i, j;
5623 adc = nids[n];
5624 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5625 continue;
5626 cap = adc;
5627 nconns = snd_hda_get_connections(codec, cap, conn,
5628 ARRAY_SIZE(conn));
5629 if (nconns == 1) {
5630 cap = conn[0];
5631 nconns = snd_hda_get_connections(codec, cap, conn,
5632 ARRAY_SIZE(conn));
5634 if (nconns <= 0)
5635 continue;
5636 if (!fallback_adc) {
5637 fallback_adc = adc;
5638 fallback_cap = cap;
5640 for (i = 0; i < cfg->num_inputs; i++) {
5641 hda_nid_t nid = cfg->inputs[i].pin;
5642 for (j = 0; j < nconns; j++) {
5643 if (conn[j] == nid)
5644 break;
5646 if (j >= nconns)
5647 break;
5649 if (i >= cfg->num_inputs) {
5650 int num_adcs = spec->num_adc_nids;
5651 spec->private_adc_nids[num_adcs] = adc;
5652 spec->private_capsrc_nids[num_adcs] = cap;
5653 spec->num_adc_nids++;
5654 spec->adc_nids = spec->private_adc_nids;
5655 if (adc != cap)
5656 spec->capsrc_nids = spec->private_capsrc_nids;
5659 if (!spec->num_adc_nids) {
5660 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5661 " using fallback 0x%x\n",
5662 codec->chip_name, fallback_adc);
5663 spec->private_adc_nids[0] = fallback_adc;
5664 spec->adc_nids = spec->private_adc_nids;
5665 if (fallback_adc != fallback_cap) {
5666 spec->private_capsrc_nids[0] = fallback_cap;
5667 spec->capsrc_nids = spec->private_adc_nids;
5672 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5673 #define set_beep_amp(spec, nid, idx, dir) \
5674 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5676 static struct snd_pci_quirk beep_white_list[] = {
5677 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5678 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5679 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5683 static inline int has_cdefine_beep(struct hda_codec *codec)
5685 struct alc_spec *spec = codec->spec;
5686 const struct snd_pci_quirk *q;
5687 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5688 if (q)
5689 return q->value;
5690 return spec->cdefine.enable_pcbeep;
5692 #else
5693 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5694 #define has_cdefine_beep(codec) 0
5695 #endif
5698 * OK, here we have finally the patch for ALC880
5701 static int patch_alc880(struct hda_codec *codec)
5703 struct alc_spec *spec;
5704 int board_config;
5705 int err;
5707 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5708 if (spec == NULL)
5709 return -ENOMEM;
5711 codec->spec = spec;
5713 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5714 alc880_models,
5715 alc880_cfg_tbl);
5716 if (board_config < 0) {
5717 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5718 codec->chip_name);
5719 board_config = ALC880_AUTO;
5722 if (board_config == ALC880_AUTO) {
5723 /* automatic parse from the BIOS config */
5724 err = alc880_parse_auto_config(codec);
5725 if (err < 0) {
5726 alc_free(codec);
5727 return err;
5728 } else if (!err) {
5729 printk(KERN_INFO
5730 "hda_codec: Cannot set up configuration "
5731 "from BIOS. Using 3-stack mode...\n");
5732 board_config = ALC880_3ST;
5736 err = snd_hda_attach_beep_device(codec, 0x1);
5737 if (err < 0) {
5738 alc_free(codec);
5739 return err;
5742 if (board_config != ALC880_AUTO)
5743 setup_preset(codec, &alc880_presets[board_config]);
5745 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5746 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5747 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5749 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5750 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5752 if (!spec->adc_nids && spec->input_mux) {
5753 /* check whether NID 0x07 is valid */
5754 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5755 /* get type */
5756 wcap = get_wcaps_type(wcap);
5757 if (wcap != AC_WID_AUD_IN) {
5758 spec->adc_nids = alc880_adc_nids_alt;
5759 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5760 } else {
5761 spec->adc_nids = alc880_adc_nids;
5762 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5765 set_capture_mixer(codec);
5766 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5768 spec->vmaster_nid = 0x0c;
5770 codec->patch_ops = alc_patch_ops;
5771 if (board_config == ALC880_AUTO)
5772 spec->init_hook = alc880_auto_init;
5773 #ifdef CONFIG_SND_HDA_POWER_SAVE
5774 if (!spec->loopback.amplist)
5775 spec->loopback.amplist = alc880_loopbacks;
5776 #endif
5778 return 0;
5783 * ALC260 support
5786 static hda_nid_t alc260_dac_nids[1] = {
5787 /* front */
5788 0x02,
5791 static hda_nid_t alc260_adc_nids[1] = {
5792 /* ADC0 */
5793 0x04,
5796 static hda_nid_t alc260_adc_nids_alt[1] = {
5797 /* ADC1 */
5798 0x05,
5801 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5802 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5804 static hda_nid_t alc260_dual_adc_nids[2] = {
5805 /* ADC0, ADC1 */
5806 0x04, 0x05
5809 #define ALC260_DIGOUT_NID 0x03
5810 #define ALC260_DIGIN_NID 0x06
5812 static struct hda_input_mux alc260_capture_source = {
5813 .num_items = 4,
5814 .items = {
5815 { "Mic", 0x0 },
5816 { "Front Mic", 0x1 },
5817 { "Line", 0x2 },
5818 { "CD", 0x4 },
5822 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5823 * headphone jack and the internal CD lines since these are the only pins at
5824 * which audio can appear. For flexibility, also allow the option of
5825 * recording the mixer output on the second ADC (ADC0 doesn't have a
5826 * connection to the mixer output).
5828 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5830 .num_items = 3,
5831 .items = {
5832 { "Mic/Line", 0x0 },
5833 { "CD", 0x4 },
5834 { "Headphone", 0x2 },
5838 .num_items = 4,
5839 .items = {
5840 { "Mic/Line", 0x0 },
5841 { "CD", 0x4 },
5842 { "Headphone", 0x2 },
5843 { "Mixer", 0x5 },
5849 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5850 * the Fujitsu S702x, but jacks are marked differently.
5852 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5854 .num_items = 4,
5855 .items = {
5856 { "Mic", 0x0 },
5857 { "Line", 0x2 },
5858 { "CD", 0x4 },
5859 { "Headphone", 0x5 },
5863 .num_items = 5,
5864 .items = {
5865 { "Mic", 0x0 },
5866 { "Line", 0x2 },
5867 { "CD", 0x4 },
5868 { "Headphone", 0x6 },
5869 { "Mixer", 0x5 },
5874 /* Maxdata Favorit 100XS */
5875 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5877 .num_items = 2,
5878 .items = {
5879 { "Line/Mic", 0x0 },
5880 { "CD", 0x4 },
5884 .num_items = 3,
5885 .items = {
5886 { "Line/Mic", 0x0 },
5887 { "CD", 0x4 },
5888 { "Mixer", 0x5 },
5894 * This is just place-holder, so there's something for alc_build_pcms to look
5895 * at when it calculates the maximum number of channels. ALC260 has no mixer
5896 * element which allows changing the channel mode, so the verb list is
5897 * never used.
5899 static struct hda_channel_mode alc260_modes[1] = {
5900 { 2, NULL },
5904 /* Mixer combinations
5906 * basic: base_output + input + pc_beep + capture
5907 * HP: base_output + input + capture_alt
5908 * HP_3013: hp_3013 + input + capture
5909 * fujitsu: fujitsu + capture
5910 * acer: acer + capture
5913 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5914 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5915 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5917 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5918 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5919 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5920 { } /* end */
5923 static struct snd_kcontrol_new alc260_input_mixer[] = {
5924 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5925 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5926 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5927 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5929 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5930 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5931 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5932 { } /* end */
5935 /* update HP, line and mono out pins according to the master switch */
5936 static void alc260_hp_master_update(struct hda_codec *codec,
5937 hda_nid_t hp, hda_nid_t line,
5938 hda_nid_t mono)
5940 struct alc_spec *spec = codec->spec;
5941 unsigned int val = spec->master_sw ? PIN_HP : 0;
5942 /* change HP and line-out pins */
5943 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5944 val);
5945 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5946 val);
5947 /* mono (speaker) depending on the HP jack sense */
5948 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5949 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5950 val);
5953 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5954 struct snd_ctl_elem_value *ucontrol)
5956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5957 struct alc_spec *spec = codec->spec;
5958 *ucontrol->value.integer.value = spec->master_sw;
5959 return 0;
5962 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5963 struct snd_ctl_elem_value *ucontrol)
5965 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5966 struct alc_spec *spec = codec->spec;
5967 int val = !!*ucontrol->value.integer.value;
5968 hda_nid_t hp, line, mono;
5970 if (val == spec->master_sw)
5971 return 0;
5972 spec->master_sw = val;
5973 hp = (kcontrol->private_value >> 16) & 0xff;
5974 line = (kcontrol->private_value >> 8) & 0xff;
5975 mono = kcontrol->private_value & 0xff;
5976 alc260_hp_master_update(codec, hp, line, mono);
5977 return 1;
5980 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5983 .name = "Master Playback Switch",
5984 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5985 .info = snd_ctl_boolean_mono_info,
5986 .get = alc260_hp_master_sw_get,
5987 .put = alc260_hp_master_sw_put,
5988 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5990 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5991 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5992 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5993 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5994 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5995 HDA_OUTPUT),
5996 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5997 { } /* end */
6000 static struct hda_verb alc260_hp_unsol_verbs[] = {
6001 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6005 static void alc260_hp_automute(struct hda_codec *codec)
6007 struct alc_spec *spec = codec->spec;
6009 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
6010 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
6013 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
6015 if ((res >> 26) == ALC880_HP_EVENT)
6016 alc260_hp_automute(codec);
6019 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6022 .name = "Master Playback Switch",
6023 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6024 .info = snd_ctl_boolean_mono_info,
6025 .get = alc260_hp_master_sw_get,
6026 .put = alc260_hp_master_sw_put,
6027 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
6029 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6030 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6031 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6032 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6033 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6035 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6036 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6037 { } /* end */
6040 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6041 .ops = &snd_hda_bind_vol,
6042 .values = {
6043 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6044 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6045 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6050 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
6051 .ops = &snd_hda_bind_sw,
6052 .values = {
6053 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6054 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6059 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6060 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6061 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6062 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6064 { } /* end */
6067 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6068 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6072 static void alc260_hp_3013_automute(struct hda_codec *codec)
6074 struct alc_spec *spec = codec->spec;
6076 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
6077 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
6080 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
6081 unsigned int res)
6083 if ((res >> 26) == ALC880_HP_EVENT)
6084 alc260_hp_3013_automute(codec);
6087 static void alc260_hp_3012_automute(struct hda_codec *codec)
6089 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
6091 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6092 bits);
6093 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6094 bits);
6095 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
6096 bits);
6099 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
6100 unsigned int res)
6102 if ((res >> 26) == ALC880_HP_EVENT)
6103 alc260_hp_3012_automute(codec);
6106 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6107 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6109 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6110 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6111 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6112 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6113 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6114 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6115 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6116 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6117 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6118 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6119 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6120 { } /* end */
6123 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6124 * versions of the ALC260 don't act on requests to enable mic bias from NID
6125 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6126 * datasheet doesn't mention this restriction. At this stage it's not clear
6127 * whether this behaviour is intentional or is a hardware bug in chip
6128 * revisions available in early 2006. Therefore for now allow the
6129 * "Headphone Jack Mode" control to span all choices, but if it turns out
6130 * that the lack of mic bias for this NID is intentional we could change the
6131 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6133 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6134 * don't appear to make the mic bias available from the "line" jack, even
6135 * though the NID used for this jack (0x14) can supply it. The theory is
6136 * that perhaps Acer have included blocking capacitors between the ALC260
6137 * and the output jack. If this turns out to be the case for all such
6138 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6139 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6141 * The C20x Tablet series have a mono internal speaker which is controlled
6142 * via the chip's Mono sum widget and pin complex, so include the necessary
6143 * controls for such models. On models without a "mono speaker" the control
6144 * won't do anything.
6146 static struct snd_kcontrol_new alc260_acer_mixer[] = {
6147 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6148 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6149 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6150 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6151 HDA_OUTPUT),
6152 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6153 HDA_INPUT),
6154 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6155 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6157 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6158 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6159 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6160 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6161 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6162 { } /* end */
6165 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6167 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6168 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6169 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6170 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6171 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6172 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6173 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6174 { } /* end */
6177 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6178 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6180 static struct snd_kcontrol_new alc260_will_mixer[] = {
6181 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6182 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6184 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6185 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6186 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6187 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6188 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6189 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6190 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6191 { } /* end */
6194 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6195 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6197 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6198 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6199 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6201 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6202 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6203 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6204 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6205 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6206 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6207 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6208 { } /* end */
6212 * initialization verbs
6214 static struct hda_verb alc260_init_verbs[] = {
6215 /* Line In pin widget for input */
6216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6217 /* CD pin widget for input */
6218 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6219 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6220 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6221 /* Mic2 (front panel) pin widget for input and vref at 80% */
6222 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6223 /* LINE-2 is used for line-out in rear */
6224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6225 /* select line-out */
6226 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6227 /* LINE-OUT pin */
6228 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6229 /* enable HP */
6230 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6231 /* enable Mono */
6232 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6233 /* mute capture amp left and right */
6234 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6235 /* set connection select to line in (default select for this ADC) */
6236 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6237 /* mute capture amp left and right */
6238 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6239 /* set connection select to line in (default select for this ADC) */
6240 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6241 /* set vol=0 Line-Out mixer amp left and right */
6242 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6243 /* unmute pin widget amp left and right (no gain on this amp) */
6244 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6245 /* set vol=0 HP mixer amp left and right */
6246 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6247 /* unmute pin widget amp left and right (no gain on this amp) */
6248 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6249 /* set vol=0 Mono mixer amp left and right */
6250 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6251 /* unmute pin widget amp left and right (no gain on this amp) */
6252 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6253 /* unmute LINE-2 out pin */
6254 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6255 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6256 * Line In 2 = 0x03
6258 /* mute analog inputs */
6259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6260 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6261 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6264 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6265 /* mute Front out path */
6266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6267 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6268 /* mute Headphone out path */
6269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6270 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6271 /* mute Mono out path */
6272 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6273 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6277 #if 0 /* should be identical with alc260_init_verbs? */
6278 static struct hda_verb alc260_hp_init_verbs[] = {
6279 /* Headphone and output */
6280 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6281 /* mono output */
6282 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6283 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6284 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6285 /* Mic2 (front panel) pin widget for input and vref at 80% */
6286 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6287 /* Line In pin widget for input */
6288 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6289 /* Line-2 pin widget for output */
6290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6291 /* CD pin widget for input */
6292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6293 /* unmute amp left and right */
6294 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6295 /* set connection select to line in (default select for this ADC) */
6296 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6297 /* unmute Line-Out mixer amp left and right (volume = 0) */
6298 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6299 /* mute pin widget amp left and right (no gain on this amp) */
6300 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6301 /* unmute HP mixer amp left and right (volume = 0) */
6302 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6303 /* mute pin widget amp left and right (no gain on this amp) */
6304 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6305 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6306 * Line In 2 = 0x03
6308 /* mute analog inputs */
6309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6312 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6313 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6314 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6315 /* Unmute Front out path */
6316 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6318 /* Unmute Headphone out path */
6319 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6320 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6321 /* Unmute Mono out path */
6322 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6323 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6326 #endif
6328 static struct hda_verb alc260_hp_3013_init_verbs[] = {
6329 /* Line out and output */
6330 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6331 /* mono output */
6332 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6333 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6334 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6335 /* Mic2 (front panel) pin widget for input and vref at 80% */
6336 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6337 /* Line In pin widget for input */
6338 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6339 /* Headphone pin widget for output */
6340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6341 /* CD pin widget for input */
6342 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6343 /* unmute amp left and right */
6344 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6345 /* set connection select to line in (default select for this ADC) */
6346 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6347 /* unmute Line-Out mixer amp left and right (volume = 0) */
6348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6349 /* mute pin widget amp left and right (no gain on this amp) */
6350 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6351 /* unmute HP mixer amp left and right (volume = 0) */
6352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6353 /* mute pin widget amp left and right (no gain on this amp) */
6354 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6355 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6356 * Line In 2 = 0x03
6358 /* mute analog inputs */
6359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6360 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6361 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6363 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6364 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6365 /* Unmute Front out path */
6366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6367 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6368 /* Unmute Headphone out path */
6369 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6370 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6371 /* Unmute Mono out path */
6372 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6373 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6377 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6378 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6379 * audio = 0x16, internal speaker = 0x10.
6381 static struct hda_verb alc260_fujitsu_init_verbs[] = {
6382 /* Disable all GPIOs */
6383 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6384 /* Internal speaker is connected to headphone pin */
6385 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6386 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6387 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6388 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6389 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6390 /* Ensure all other unused pins are disabled and muted. */
6391 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6393 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6394 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6395 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6396 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6397 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6398 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6400 /* Disable digital (SPDIF) pins */
6401 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6402 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6404 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6405 * when acting as an output.
6407 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6409 /* Start with output sum widgets muted and their output gains at min */
6410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6411 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6412 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6413 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6416 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6417 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6420 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6421 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6422 /* Unmute Line1 pin widget output buffer since it starts as an output.
6423 * If the pin mode is changed by the user the pin mode control will
6424 * take care of enabling the pin's input/output buffers as needed.
6425 * Therefore there's no need to enable the input buffer at this
6426 * stage.
6428 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6429 /* Unmute input buffer of pin widget used for Line-in (no equiv
6430 * mixer ctrl)
6432 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6434 /* Mute capture amp left and right */
6435 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6436 /* Set ADC connection select to match default mixer setting - line
6437 * in (on mic1 pin)
6439 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6441 /* Do the same for the second ADC: mute capture input amp and
6442 * set ADC connection to line in (on mic1 pin)
6444 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6445 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6447 /* Mute all inputs to mixer widget (even unconnected ones) */
6448 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6449 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6460 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6461 * similar laptops (adapted from Fujitsu init verbs).
6463 static struct hda_verb alc260_acer_init_verbs[] = {
6464 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6465 * the headphone jack. Turn this on and rely on the standard mute
6466 * methods whenever the user wants to turn these outputs off.
6468 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6469 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6470 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6471 /* Internal speaker/Headphone jack is connected to Line-out pin */
6472 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6473 /* Internal microphone/Mic jack is connected to Mic1 pin */
6474 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6475 /* Line In jack is connected to Line1 pin */
6476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6477 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6478 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6479 /* Ensure all other unused pins are disabled and muted. */
6480 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6481 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6482 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6483 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6485 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6486 /* Disable digital (SPDIF) pins */
6487 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6488 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6490 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6491 * bus when acting as outputs.
6493 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6494 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6496 /* Start with output sum widgets muted and their output gains at min */
6497 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6498 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6499 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6500 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6501 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6502 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6503 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6504 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6505 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6507 /* Unmute Line-out pin widget amp left and right
6508 * (no equiv mixer ctrl)
6510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6511 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6512 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6513 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6514 * inputs. If the pin mode is changed by the user the pin mode control
6515 * will take care of enabling the pin's input/output buffers as needed.
6516 * Therefore there's no need to enable the input buffer at this
6517 * stage.
6519 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6522 /* Mute capture amp left and right */
6523 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6524 /* Set ADC connection select to match default mixer setting - mic
6525 * (on mic1 pin)
6527 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6529 /* Do similar with the second ADC: mute capture input amp and
6530 * set ADC connection to mic to match ALSA's default state.
6532 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6533 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6535 /* Mute all inputs to mixer widget (even unconnected ones) */
6536 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6537 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6538 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6539 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6540 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6541 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6542 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6548 /* Initialisation sequence for Maxdata Favorit 100XS
6549 * (adapted from Acer init verbs).
6551 static struct hda_verb alc260_favorit100_init_verbs[] = {
6552 /* GPIO 0 enables the output jack.
6553 * Turn this on and rely on the standard mute
6554 * methods whenever the user wants to turn these outputs off.
6556 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6557 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6558 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6559 /* Line/Mic input jack is connected to Mic1 pin */
6560 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6561 /* Ensure all other unused pins are disabled and muted. */
6562 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6563 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6564 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6565 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6566 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6567 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6569 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6572 /* Disable digital (SPDIF) pins */
6573 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6574 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6576 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6577 * bus when acting as outputs.
6579 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6580 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6582 /* Start with output sum widgets muted and their output gains at min */
6583 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6584 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6585 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6586 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6587 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6588 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6589 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6590 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6591 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6593 /* Unmute Line-out pin widget amp left and right
6594 * (no equiv mixer ctrl)
6596 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6597 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6598 * inputs. If the pin mode is changed by the user the pin mode control
6599 * will take care of enabling the pin's input/output buffers as needed.
6600 * Therefore there's no need to enable the input buffer at this
6601 * stage.
6603 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6605 /* Mute capture amp left and right */
6606 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6607 /* Set ADC connection select to match default mixer setting - mic
6608 * (on mic1 pin)
6610 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6612 /* Do similar with the second ADC: mute capture input amp and
6613 * set ADC connection to mic to match ALSA's default state.
6615 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6616 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6618 /* Mute all inputs to mixer widget (even unconnected ones) */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6631 static struct hda_verb alc260_will_verbs[] = {
6632 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6633 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6634 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6635 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6636 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6637 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6641 static struct hda_verb alc260_replacer_672v_verbs[] = {
6642 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6643 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6644 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6646 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6647 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6648 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6650 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6654 /* toggle speaker-output according to the hp-jack state */
6655 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6657 unsigned int present;
6659 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6660 present = snd_hda_jack_detect(codec, 0x0f);
6661 if (present) {
6662 snd_hda_codec_write_cache(codec, 0x01, 0,
6663 AC_VERB_SET_GPIO_DATA, 1);
6664 snd_hda_codec_write_cache(codec, 0x0f, 0,
6665 AC_VERB_SET_PIN_WIDGET_CONTROL,
6666 PIN_HP);
6667 } else {
6668 snd_hda_codec_write_cache(codec, 0x01, 0,
6669 AC_VERB_SET_GPIO_DATA, 0);
6670 snd_hda_codec_write_cache(codec, 0x0f, 0,
6671 AC_VERB_SET_PIN_WIDGET_CONTROL,
6672 PIN_OUT);
6676 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6677 unsigned int res)
6679 if ((res >> 26) == ALC880_HP_EVENT)
6680 alc260_replacer_672v_automute(codec);
6683 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6684 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6686 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6687 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6688 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6690 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6691 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6692 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6693 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6697 /* Test configuration for debugging, modelled after the ALC880 test
6698 * configuration.
6700 #ifdef CONFIG_SND_DEBUG
6701 static hda_nid_t alc260_test_dac_nids[1] = {
6702 0x02,
6704 static hda_nid_t alc260_test_adc_nids[2] = {
6705 0x04, 0x05,
6707 /* For testing the ALC260, each input MUX needs its own definition since
6708 * the signal assignments are different. This assumes that the first ADC
6709 * is NID 0x04.
6711 static struct hda_input_mux alc260_test_capture_sources[2] = {
6713 .num_items = 7,
6714 .items = {
6715 { "MIC1 pin", 0x0 },
6716 { "MIC2 pin", 0x1 },
6717 { "LINE1 pin", 0x2 },
6718 { "LINE2 pin", 0x3 },
6719 { "CD pin", 0x4 },
6720 { "LINE-OUT pin", 0x5 },
6721 { "HP-OUT pin", 0x6 },
6725 .num_items = 8,
6726 .items = {
6727 { "MIC1 pin", 0x0 },
6728 { "MIC2 pin", 0x1 },
6729 { "LINE1 pin", 0x2 },
6730 { "LINE2 pin", 0x3 },
6731 { "CD pin", 0x4 },
6732 { "Mixer", 0x5 },
6733 { "LINE-OUT pin", 0x6 },
6734 { "HP-OUT pin", 0x7 },
6738 static struct snd_kcontrol_new alc260_test_mixer[] = {
6739 /* Output driver widgets */
6740 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6741 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6742 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6743 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6744 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6745 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6747 /* Modes for retasking pin widgets
6748 * Note: the ALC260 doesn't seem to act on requests to enable mic
6749 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6750 * mention this restriction. At this stage it's not clear whether
6751 * this behaviour is intentional or is a hardware bug in chip
6752 * revisions available at least up until early 2006. Therefore for
6753 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6754 * choices, but if it turns out that the lack of mic bias for these
6755 * NIDs is intentional we could change their modes from
6756 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6758 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6759 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6760 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6761 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6762 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6763 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6765 /* Loopback mixer controls */
6766 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6767 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6768 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6769 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6770 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6771 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6772 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6773 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6774 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6775 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6776 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6777 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6778 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6779 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6781 /* Controls for GPIO pins, assuming they are configured as outputs */
6782 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6783 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6784 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6785 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6787 /* Switches to allow the digital IO pins to be enabled. The datasheet
6788 * is ambigious as to which NID is which; testing on laptops which
6789 * make this output available should provide clarification.
6791 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6792 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6794 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6795 * this output to turn on an external amplifier.
6797 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6798 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6800 { } /* end */
6802 static struct hda_verb alc260_test_init_verbs[] = {
6803 /* Enable all GPIOs as outputs with an initial value of 0 */
6804 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6805 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6806 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6808 /* Enable retasking pins as output, initially without power amp */
6809 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6810 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6813 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6814 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6816 /* Disable digital (SPDIF) pins initially, but users can enable
6817 * them via a mixer switch. In the case of SPDIF-out, this initverb
6818 * payload also sets the generation to 0, output to be in "consumer"
6819 * PCM format, copyright asserted, no pre-emphasis and no validity
6820 * control.
6822 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6823 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6825 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6826 * OUT1 sum bus when acting as an output.
6828 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6829 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6830 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6831 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6833 /* Start with output sum widgets muted and their output gains at min */
6834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6835 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6836 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6837 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6838 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6839 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6840 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6841 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6842 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6844 /* Unmute retasking pin widget output buffers since the default
6845 * state appears to be output. As the pin mode is changed by the
6846 * user the pin mode control will take care of enabling the pin's
6847 * input/output buffers as needed.
6849 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6853 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6854 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6855 /* Also unmute the mono-out pin widget */
6856 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6858 /* Mute capture amp left and right */
6859 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6860 /* Set ADC connection select to match default mixer setting (mic1
6861 * pin)
6863 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6865 /* Do the same for the second ADC: mute capture input amp and
6866 * set ADC connection to mic1 pin
6868 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6869 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6871 /* Mute all inputs to mixer widget (even unconnected ones) */
6872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6879 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6883 #endif
6885 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6886 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6888 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6889 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6892 * for BIOS auto-configuration
6895 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6896 const char *pfx, int *vol_bits)
6898 hda_nid_t nid_vol;
6899 unsigned long vol_val, sw_val;
6900 int err;
6902 if (nid >= 0x0f && nid < 0x11) {
6903 nid_vol = nid - 0x7;
6904 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6905 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6906 } else if (nid == 0x11) {
6907 nid_vol = nid - 0x7;
6908 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6909 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6910 } else if (nid >= 0x12 && nid <= 0x15) {
6911 nid_vol = 0x08;
6912 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6913 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6914 } else
6915 return 0; /* N/A */
6917 if (!(*vol_bits & (1 << nid_vol))) {
6918 /* first control for the volume widget */
6919 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6920 if (err < 0)
6921 return err;
6922 *vol_bits |= (1 << nid_vol);
6924 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6925 if (err < 0)
6926 return err;
6927 return 1;
6930 /* add playback controls from the parsed DAC table */
6931 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6932 const struct auto_pin_cfg *cfg)
6934 hda_nid_t nid;
6935 int err;
6936 int vols = 0;
6938 spec->multiout.num_dacs = 1;
6939 spec->multiout.dac_nids = spec->private_dac_nids;
6940 spec->multiout.dac_nids[0] = 0x02;
6942 nid = cfg->line_out_pins[0];
6943 if (nid) {
6944 const char *pfx;
6945 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6946 pfx = "Master";
6947 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6948 pfx = "Speaker";
6949 else
6950 pfx = "Front";
6951 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6952 if (err < 0)
6953 return err;
6956 nid = cfg->speaker_pins[0];
6957 if (nid) {
6958 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6959 if (err < 0)
6960 return err;
6963 nid = cfg->hp_pins[0];
6964 if (nid) {
6965 err = alc260_add_playback_controls(spec, nid, "Headphone",
6966 &vols);
6967 if (err < 0)
6968 return err;
6970 return 0;
6973 /* create playback/capture controls for input pins */
6974 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6975 const struct auto_pin_cfg *cfg)
6977 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6980 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6981 hda_nid_t nid, int pin_type,
6982 int sel_idx)
6984 alc_set_pin_output(codec, nid, pin_type);
6985 /* need the manual connection? */
6986 if (nid >= 0x12) {
6987 int idx = nid - 0x12;
6988 snd_hda_codec_write(codec, idx + 0x0b, 0,
6989 AC_VERB_SET_CONNECT_SEL, sel_idx);
6993 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6995 struct alc_spec *spec = codec->spec;
6996 hda_nid_t nid;
6998 nid = spec->autocfg.line_out_pins[0];
6999 if (nid) {
7000 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7001 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7004 nid = spec->autocfg.speaker_pins[0];
7005 if (nid)
7006 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7008 nid = spec->autocfg.hp_pins[0];
7009 if (nid)
7010 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7013 #define ALC260_PIN_CD_NID 0x16
7014 static void alc260_auto_init_analog_input(struct hda_codec *codec)
7016 struct alc_spec *spec = codec->spec;
7017 struct auto_pin_cfg *cfg = &spec->autocfg;
7018 int i;
7020 for (i = 0; i < cfg->num_inputs; i++) {
7021 hda_nid_t nid = cfg->inputs[i].pin;
7022 if (nid >= 0x12) {
7023 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7024 if (nid != ALC260_PIN_CD_NID &&
7025 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7026 snd_hda_codec_write(codec, nid, 0,
7027 AC_VERB_SET_AMP_GAIN_MUTE,
7028 AMP_OUT_MUTE);
7033 #define alc260_auto_init_input_src alc880_auto_init_input_src
7036 * generic initialization of ADC, input mixers and output mixers
7038 static struct hda_verb alc260_volume_init_verbs[] = {
7040 * Unmute ADC0-1 and set the default input to mic-in
7042 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7043 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7044 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7045 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7047 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7048 * mixer widget
7049 * Note: PASD motherboards uses the Line In 2 as the input for
7050 * front panel mic (mic 2)
7052 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7053 /* mute analog inputs */
7054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7061 * Set up output mixers (0x08 - 0x0a)
7063 /* set vol=0 to output mixers */
7064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7066 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7067 /* set up input amps for analog loopback */
7068 /* Amp Indices: DAC = 0, mixer = 1 */
7069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7070 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7071 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7072 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7073 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7074 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7079 static int alc260_parse_auto_config(struct hda_codec *codec)
7081 struct alc_spec *spec = codec->spec;
7082 int err;
7083 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
7085 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7086 alc260_ignore);
7087 if (err < 0)
7088 return err;
7089 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7090 if (err < 0)
7091 return err;
7092 if (!spec->kctls.list)
7093 return 0; /* can't find valid BIOS pin config */
7094 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7095 if (err < 0)
7096 return err;
7098 spec->multiout.max_channels = 2;
7100 if (spec->autocfg.dig_outs)
7101 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7102 if (spec->kctls.list)
7103 add_mixer(spec, spec->kctls.list);
7105 add_verb(spec, alc260_volume_init_verbs);
7107 spec->num_mux_defs = 1;
7108 spec->input_mux = &spec->private_imux[0];
7110 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7112 return 1;
7115 /* additional initialization for auto-configuration model */
7116 static void alc260_auto_init(struct hda_codec *codec)
7118 struct alc_spec *spec = codec->spec;
7119 alc260_auto_init_multi_out(codec);
7120 alc260_auto_init_analog_input(codec);
7121 alc260_auto_init_input_src(codec);
7122 alc_auto_init_digital(codec);
7123 if (spec->unsol_event)
7124 alc_inithook(codec);
7127 #ifdef CONFIG_SND_HDA_POWER_SAVE
7128 static struct hda_amp_list alc260_loopbacks[] = {
7129 { 0x07, HDA_INPUT, 0 },
7130 { 0x07, HDA_INPUT, 1 },
7131 { 0x07, HDA_INPUT, 2 },
7132 { 0x07, HDA_INPUT, 3 },
7133 { 0x07, HDA_INPUT, 4 },
7134 { } /* end */
7136 #endif
7139 * Pin config fixes
7141 enum {
7142 PINFIX_HP_DC5750,
7145 static const struct alc_fixup alc260_fixups[] = {
7146 [PINFIX_HP_DC5750] = {
7147 .type = ALC_FIXUP_PINS,
7148 .v.pins = (const struct alc_pincfg[]) {
7149 { 0x11, 0x90130110 }, /* speaker */
7155 static struct snd_pci_quirk alc260_fixup_tbl[] = {
7156 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7161 * ALC260 configurations
7163 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7164 [ALC260_BASIC] = "basic",
7165 [ALC260_HP] = "hp",
7166 [ALC260_HP_3013] = "hp-3013",
7167 [ALC260_HP_DC7600] = "hp-dc7600",
7168 [ALC260_FUJITSU_S702X] = "fujitsu",
7169 [ALC260_ACER] = "acer",
7170 [ALC260_WILL] = "will",
7171 [ALC260_REPLACER_672V] = "replacer",
7172 [ALC260_FAVORIT100] = "favorit100",
7173 #ifdef CONFIG_SND_DEBUG
7174 [ALC260_TEST] = "test",
7175 #endif
7176 [ALC260_AUTO] = "auto",
7179 static struct snd_pci_quirk alc260_cfg_tbl[] = {
7180 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7181 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7182 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7183 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7184 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7185 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7186 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7187 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7188 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7189 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7190 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7191 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7192 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7193 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7194 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7195 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7196 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7197 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7198 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7199 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7203 static struct alc_config_preset alc260_presets[] = {
7204 [ALC260_BASIC] = {
7205 .mixers = { alc260_base_output_mixer,
7206 alc260_input_mixer },
7207 .init_verbs = { alc260_init_verbs },
7208 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7209 .dac_nids = alc260_dac_nids,
7210 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7211 .adc_nids = alc260_dual_adc_nids,
7212 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7213 .channel_mode = alc260_modes,
7214 .input_mux = &alc260_capture_source,
7216 [ALC260_HP] = {
7217 .mixers = { alc260_hp_output_mixer,
7218 alc260_input_mixer },
7219 .init_verbs = { alc260_init_verbs,
7220 alc260_hp_unsol_verbs },
7221 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7222 .dac_nids = alc260_dac_nids,
7223 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7224 .adc_nids = alc260_adc_nids_alt,
7225 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7226 .channel_mode = alc260_modes,
7227 .input_mux = &alc260_capture_source,
7228 .unsol_event = alc260_hp_unsol_event,
7229 .init_hook = alc260_hp_automute,
7231 [ALC260_HP_DC7600] = {
7232 .mixers = { alc260_hp_dc7600_mixer,
7233 alc260_input_mixer },
7234 .init_verbs = { alc260_init_verbs,
7235 alc260_hp_dc7600_verbs },
7236 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7237 .dac_nids = alc260_dac_nids,
7238 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7239 .adc_nids = alc260_adc_nids_alt,
7240 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7241 .channel_mode = alc260_modes,
7242 .input_mux = &alc260_capture_source,
7243 .unsol_event = alc260_hp_3012_unsol_event,
7244 .init_hook = alc260_hp_3012_automute,
7246 [ALC260_HP_3013] = {
7247 .mixers = { alc260_hp_3013_mixer,
7248 alc260_input_mixer },
7249 .init_verbs = { alc260_hp_3013_init_verbs,
7250 alc260_hp_3013_unsol_verbs },
7251 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7252 .dac_nids = alc260_dac_nids,
7253 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7254 .adc_nids = alc260_adc_nids_alt,
7255 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7256 .channel_mode = alc260_modes,
7257 .input_mux = &alc260_capture_source,
7258 .unsol_event = alc260_hp_3013_unsol_event,
7259 .init_hook = alc260_hp_3013_automute,
7261 [ALC260_FUJITSU_S702X] = {
7262 .mixers = { alc260_fujitsu_mixer },
7263 .init_verbs = { alc260_fujitsu_init_verbs },
7264 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7265 .dac_nids = alc260_dac_nids,
7266 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7267 .adc_nids = alc260_dual_adc_nids,
7268 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7269 .channel_mode = alc260_modes,
7270 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7271 .input_mux = alc260_fujitsu_capture_sources,
7273 [ALC260_ACER] = {
7274 .mixers = { alc260_acer_mixer },
7275 .init_verbs = { alc260_acer_init_verbs },
7276 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7277 .dac_nids = alc260_dac_nids,
7278 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7279 .adc_nids = alc260_dual_adc_nids,
7280 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7281 .channel_mode = alc260_modes,
7282 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7283 .input_mux = alc260_acer_capture_sources,
7285 [ALC260_FAVORIT100] = {
7286 .mixers = { alc260_favorit100_mixer },
7287 .init_verbs = { alc260_favorit100_init_verbs },
7288 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7289 .dac_nids = alc260_dac_nids,
7290 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7291 .adc_nids = alc260_dual_adc_nids,
7292 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7293 .channel_mode = alc260_modes,
7294 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7295 .input_mux = alc260_favorit100_capture_sources,
7297 [ALC260_WILL] = {
7298 .mixers = { alc260_will_mixer },
7299 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7300 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7301 .dac_nids = alc260_dac_nids,
7302 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7303 .adc_nids = alc260_adc_nids,
7304 .dig_out_nid = ALC260_DIGOUT_NID,
7305 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7306 .channel_mode = alc260_modes,
7307 .input_mux = &alc260_capture_source,
7309 [ALC260_REPLACER_672V] = {
7310 .mixers = { alc260_replacer_672v_mixer },
7311 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7312 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7313 .dac_nids = alc260_dac_nids,
7314 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7315 .adc_nids = alc260_adc_nids,
7316 .dig_out_nid = ALC260_DIGOUT_NID,
7317 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7318 .channel_mode = alc260_modes,
7319 .input_mux = &alc260_capture_source,
7320 .unsol_event = alc260_replacer_672v_unsol_event,
7321 .init_hook = alc260_replacer_672v_automute,
7323 #ifdef CONFIG_SND_DEBUG
7324 [ALC260_TEST] = {
7325 .mixers = { alc260_test_mixer },
7326 .init_verbs = { alc260_test_init_verbs },
7327 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7328 .dac_nids = alc260_test_dac_nids,
7329 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7330 .adc_nids = alc260_test_adc_nids,
7331 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7332 .channel_mode = alc260_modes,
7333 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7334 .input_mux = alc260_test_capture_sources,
7336 #endif
7339 static int patch_alc260(struct hda_codec *codec)
7341 struct alc_spec *spec;
7342 int err, board_config;
7344 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7345 if (spec == NULL)
7346 return -ENOMEM;
7348 codec->spec = spec;
7350 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7351 alc260_models,
7352 alc260_cfg_tbl);
7353 if (board_config < 0) {
7354 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7355 codec->chip_name);
7356 board_config = ALC260_AUTO;
7359 if (board_config == ALC260_AUTO) {
7360 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7361 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7364 if (board_config == ALC260_AUTO) {
7365 /* automatic parse from the BIOS config */
7366 err = alc260_parse_auto_config(codec);
7367 if (err < 0) {
7368 alc_free(codec);
7369 return err;
7370 } else if (!err) {
7371 printk(KERN_INFO
7372 "hda_codec: Cannot set up configuration "
7373 "from BIOS. Using base mode...\n");
7374 board_config = ALC260_BASIC;
7378 err = snd_hda_attach_beep_device(codec, 0x1);
7379 if (err < 0) {
7380 alc_free(codec);
7381 return err;
7384 if (board_config != ALC260_AUTO)
7385 setup_preset(codec, &alc260_presets[board_config]);
7387 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7388 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7389 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7391 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7392 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7394 if (!spec->adc_nids && spec->input_mux) {
7395 /* check whether NID 0x04 is valid */
7396 unsigned int wcap = get_wcaps(codec, 0x04);
7397 wcap = get_wcaps_type(wcap);
7398 /* get type */
7399 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7400 spec->adc_nids = alc260_adc_nids_alt;
7401 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7402 } else {
7403 spec->adc_nids = alc260_adc_nids;
7404 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7407 set_capture_mixer(codec);
7408 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7410 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7412 spec->vmaster_nid = 0x08;
7414 codec->patch_ops = alc_patch_ops;
7415 if (board_config == ALC260_AUTO)
7416 spec->init_hook = alc260_auto_init;
7417 #ifdef CONFIG_SND_HDA_POWER_SAVE
7418 if (!spec->loopback.amplist)
7419 spec->loopback.amplist = alc260_loopbacks;
7420 #endif
7422 return 0;
7427 * ALC882/883/885/888/889 support
7429 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7430 * configuration. Each pin widget can choose any input DACs and a mixer.
7431 * Each ADC is connected from a mixer of all inputs. This makes possible
7432 * 6-channel independent captures.
7434 * In addition, an independent DAC for the multi-playback (not used in this
7435 * driver yet).
7437 #define ALC882_DIGOUT_NID 0x06
7438 #define ALC882_DIGIN_NID 0x0a
7439 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7440 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7441 #define ALC1200_DIGOUT_NID 0x10
7444 static struct hda_channel_mode alc882_ch_modes[1] = {
7445 { 8, NULL }
7448 /* DACs */
7449 static hda_nid_t alc882_dac_nids[4] = {
7450 /* front, rear, clfe, rear_surr */
7451 0x02, 0x03, 0x04, 0x05
7453 #define alc883_dac_nids alc882_dac_nids
7455 /* ADCs */
7456 #define alc882_adc_nids alc880_adc_nids
7457 #define alc882_adc_nids_alt alc880_adc_nids_alt
7458 #define alc883_adc_nids alc882_adc_nids_alt
7459 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7460 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7461 #define alc889_adc_nids alc880_adc_nids
7463 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7464 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7465 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7466 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7467 #define alc889_capsrc_nids alc882_capsrc_nids
7469 /* input MUX */
7470 /* FIXME: should be a matrix-type input source selection */
7472 static struct hda_input_mux alc882_capture_source = {
7473 .num_items = 4,
7474 .items = {
7475 { "Mic", 0x0 },
7476 { "Front Mic", 0x1 },
7477 { "Line", 0x2 },
7478 { "CD", 0x4 },
7482 #define alc883_capture_source alc882_capture_source
7484 static struct hda_input_mux alc889_capture_source = {
7485 .num_items = 3,
7486 .items = {
7487 { "Front Mic", 0x0 },
7488 { "Mic", 0x3 },
7489 { "Line", 0x2 },
7493 static struct hda_input_mux mb5_capture_source = {
7494 .num_items = 3,
7495 .items = {
7496 { "Mic", 0x1 },
7497 { "Line", 0x7 },
7498 { "CD", 0x4 },
7502 static struct hda_input_mux macmini3_capture_source = {
7503 .num_items = 2,
7504 .items = {
7505 { "Line", 0x2 },
7506 { "CD", 0x4 },
7510 static struct hda_input_mux alc883_3stack_6ch_intel = {
7511 .num_items = 4,
7512 .items = {
7513 { "Mic", 0x1 },
7514 { "Front Mic", 0x0 },
7515 { "Line", 0x2 },
7516 { "CD", 0x4 },
7520 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7521 .num_items = 2,
7522 .items = {
7523 { "Mic", 0x1 },
7524 { "Line", 0x2 },
7528 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7529 .num_items = 4,
7530 .items = {
7531 { "Mic", 0x0 },
7532 { "Internal Mic", 0x1 },
7533 { "Line", 0x2 },
7534 { "CD", 0x4 },
7538 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7539 .num_items = 2,
7540 .items = {
7541 { "Mic", 0x0 },
7542 { "Internal Mic", 0x1 },
7546 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7547 .num_items = 3,
7548 .items = {
7549 { "Mic", 0x0 },
7550 { "Front Mic", 0x1 },
7551 { "Line", 0x4 },
7555 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7556 .num_items = 2,
7557 .items = {
7558 { "Mic", 0x0 },
7559 { "Line", 0x2 },
7563 static struct hda_input_mux alc889A_mb31_capture_source = {
7564 .num_items = 2,
7565 .items = {
7566 { "Mic", 0x0 },
7567 /* Front Mic (0x01) unused */
7568 { "Line", 0x2 },
7569 /* Line 2 (0x03) unused */
7570 /* CD (0x04) unused? */
7574 static struct hda_input_mux alc889A_imac91_capture_source = {
7575 .num_items = 2,
7576 .items = {
7577 { "Mic", 0x01 },
7578 { "Line", 0x2 }, /* Not sure! */
7583 * 2ch mode
7585 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7586 { 2, NULL }
7590 * 2ch mode
7592 static struct hda_verb alc882_3ST_ch2_init[] = {
7593 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7594 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7595 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7596 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7597 { } /* end */
7601 * 4ch mode
7603 static struct hda_verb alc882_3ST_ch4_init[] = {
7604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7606 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7607 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7608 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7609 { } /* end */
7613 * 6ch mode
7615 static struct hda_verb alc882_3ST_ch6_init[] = {
7616 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7617 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7618 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7619 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7620 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7621 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7622 { } /* end */
7625 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7626 { 2, alc882_3ST_ch2_init },
7627 { 4, alc882_3ST_ch4_init },
7628 { 6, alc882_3ST_ch6_init },
7631 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7634 * 2ch mode
7636 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7637 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7638 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7639 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7640 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7641 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7642 { } /* end */
7646 * 4ch mode
7648 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7649 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7650 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7651 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7652 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7653 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7654 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7655 { } /* end */
7659 * 6ch mode
7661 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7662 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7663 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7665 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7666 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7667 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7668 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7669 { } /* end */
7672 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7673 { 2, alc883_3ST_ch2_clevo_init },
7674 { 4, alc883_3ST_ch4_clevo_init },
7675 { 6, alc883_3ST_ch6_clevo_init },
7680 * 6ch mode
7682 static struct hda_verb alc882_sixstack_ch6_init[] = {
7683 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7684 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7685 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7686 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7687 { } /* end */
7691 * 8ch mode
7693 static struct hda_verb alc882_sixstack_ch8_init[] = {
7694 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7695 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7696 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7697 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7698 { } /* end */
7701 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7702 { 6, alc882_sixstack_ch6_init },
7703 { 8, alc882_sixstack_ch8_init },
7707 /* Macbook Air 2,1 */
7709 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7710 { 2, NULL },
7714 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7718 * 2ch mode
7720 static struct hda_verb alc885_mbp_ch2_init[] = {
7721 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7722 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7723 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7724 { } /* end */
7728 * 4ch mode
7730 static struct hda_verb alc885_mbp_ch4_init[] = {
7731 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7732 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7733 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7734 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7735 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7736 { } /* end */
7739 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7740 { 2, alc885_mbp_ch2_init },
7741 { 4, alc885_mbp_ch4_init },
7745 * 2ch
7746 * Speakers/Woofer/HP = Front
7747 * LineIn = Input
7749 static struct hda_verb alc885_mb5_ch2_init[] = {
7750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7751 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7752 { } /* end */
7756 * 6ch mode
7757 * Speakers/HP = Front
7758 * Woofer = LFE
7759 * LineIn = Surround
7761 static struct hda_verb alc885_mb5_ch6_init[] = {
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 { } /* end */
7768 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7769 { 2, alc885_mb5_ch2_init },
7770 { 6, alc885_mb5_ch6_init },
7773 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7776 * 2ch mode
7778 static struct hda_verb alc883_4ST_ch2_init[] = {
7779 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7780 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7781 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7782 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7783 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7784 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7785 { } /* end */
7789 * 4ch mode
7791 static struct hda_verb alc883_4ST_ch4_init[] = {
7792 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7793 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7794 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7795 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7796 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7797 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7798 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7799 { } /* end */
7803 * 6ch mode
7805 static struct hda_verb alc883_4ST_ch6_init[] = {
7806 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7807 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7808 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7809 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7810 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7811 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7812 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7813 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7814 { } /* end */
7818 * 8ch mode
7820 static struct hda_verb alc883_4ST_ch8_init[] = {
7821 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7822 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7823 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7824 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7825 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7826 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7827 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7828 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7829 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7830 { } /* end */
7833 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7834 { 2, alc883_4ST_ch2_init },
7835 { 4, alc883_4ST_ch4_init },
7836 { 6, alc883_4ST_ch6_init },
7837 { 8, alc883_4ST_ch8_init },
7842 * 2ch mode
7844 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7845 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7846 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7847 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7848 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7849 { } /* end */
7853 * 4ch mode
7855 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7856 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7857 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7860 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7861 { } /* end */
7865 * 6ch mode
7867 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7868 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7869 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7870 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7871 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7873 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7874 { } /* end */
7877 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7878 { 2, alc883_3ST_ch2_intel_init },
7879 { 4, alc883_3ST_ch4_intel_init },
7880 { 6, alc883_3ST_ch6_intel_init },
7884 * 2ch mode
7886 static struct hda_verb alc889_ch2_intel_init[] = {
7887 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7888 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7889 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7890 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7891 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7892 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7893 { } /* end */
7897 * 6ch mode
7899 static struct hda_verb alc889_ch6_intel_init[] = {
7900 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7901 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7902 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7903 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7904 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7905 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7906 { } /* end */
7910 * 8ch mode
7912 static struct hda_verb alc889_ch8_intel_init[] = {
7913 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7914 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7915 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7916 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7917 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7918 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7919 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7920 { } /* end */
7923 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7924 { 2, alc889_ch2_intel_init },
7925 { 6, alc889_ch6_intel_init },
7926 { 8, alc889_ch8_intel_init },
7930 * 6ch mode
7932 static struct hda_verb alc883_sixstack_ch6_init[] = {
7933 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7934 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7935 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7936 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7937 { } /* end */
7941 * 8ch mode
7943 static struct hda_verb alc883_sixstack_ch8_init[] = {
7944 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7945 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7946 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7947 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7948 { } /* end */
7951 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7952 { 6, alc883_sixstack_ch6_init },
7953 { 8, alc883_sixstack_ch8_init },
7957 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7958 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7960 static struct snd_kcontrol_new alc882_base_mixer[] = {
7961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7963 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7964 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7965 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7966 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7967 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7968 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7969 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7970 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7972 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7973 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7982 { } /* end */
7985 /* Macbook Air 2,1 same control for HP and internal Speaker */
7987 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7988 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7989 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7994 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7995 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7996 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7997 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7998 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7999 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8000 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8001 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8003 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8004 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8006 { } /* end */
8009 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
8010 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8011 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8012 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8013 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8014 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8015 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8016 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8017 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8018 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8019 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8021 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8024 { } /* end */
8027 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8028 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8029 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8030 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8031 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8032 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8033 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8034 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8035 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8036 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8037 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8038 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8039 { } /* end */
8042 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
8043 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8044 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8045 { } /* end */
8049 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8052 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8053 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8057 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8059 { } /* end */
8062 static struct snd_kcontrol_new alc882_targa_mixer[] = {
8063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8064 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8066 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8067 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8071 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8073 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8074 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8075 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8076 { } /* end */
8079 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8080 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8082 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8083 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8084 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8086 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8092 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8095 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8096 { } /* end */
8099 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8100 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8101 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8102 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8103 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8104 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8108 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8110 { } /* end */
8113 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
8115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8116 .name = "Channel Mode",
8117 .info = alc_ch_mode_info,
8118 .get = alc_ch_mode_get,
8119 .put = alc_ch_mode_put,
8121 { } /* end */
8124 static struct hda_verb alc882_base_init_verbs[] = {
8125 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8128 /* Rear mixer */
8129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8131 /* CLFE mixer */
8132 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8133 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8134 /* Side mixer */
8135 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8136 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8138 /* Front Pin: output 0 (0x0c) */
8139 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8140 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8141 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8142 /* Rear Pin: output 1 (0x0d) */
8143 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8144 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8145 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8146 /* CLFE Pin: output 2 (0x0e) */
8147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8148 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8149 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8150 /* Side Pin: output 3 (0x0f) */
8151 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8152 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8153 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8154 /* Mic (rear) pin: input vref at 80% */
8155 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8156 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8157 /* Front Mic pin: input vref at 80% */
8158 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8159 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8160 /* Line In pin: input */
8161 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8162 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8163 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8164 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8165 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8166 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8167 /* CD pin widget for input */
8168 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8170 /* FIXME: use matrix-type input source selection */
8171 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8172 /* Input mixer2 */
8173 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8174 /* Input mixer3 */
8175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8176 /* ADC2: mute amp left and right */
8177 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8178 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8179 /* ADC3: mute amp left and right */
8180 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8181 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8186 static struct hda_verb alc882_adc1_init_verbs[] = {
8187 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8188 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8189 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8190 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8191 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8192 /* ADC1: mute amp left and right */
8193 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8194 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8198 static struct hda_verb alc882_eapd_verbs[] = {
8199 /* change to EAPD mode */
8200 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8201 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8205 static struct hda_verb alc889_eapd_verbs[] = {
8206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8207 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8211 static struct hda_verb alc_hp15_unsol_verbs[] = {
8212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8217 static struct hda_verb alc885_init_verbs[] = {
8218 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8221 /* Rear mixer */
8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8224 /* CLFE mixer */
8225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8226 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8227 /* Side mixer */
8228 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8229 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8231 /* Front HP Pin: output 0 (0x0c) */
8232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8234 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8235 /* Front Pin: output 0 (0x0c) */
8236 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8237 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8238 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8239 /* Rear Pin: output 1 (0x0d) */
8240 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8241 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8242 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8243 /* CLFE Pin: output 2 (0x0e) */
8244 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8245 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8246 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8247 /* Side Pin: output 3 (0x0f) */
8248 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8249 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8250 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8251 /* Mic (rear) pin: input vref at 80% */
8252 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8253 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8254 /* Front Mic pin: input vref at 80% */
8255 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8256 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8257 /* Line In pin: input */
8258 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8261 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8262 /* Input mixer1 */
8263 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8264 /* Input mixer2 */
8265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8266 /* Input mixer3 */
8267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268 /* ADC2: mute amp left and right */
8269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8270 /* ADC3: mute amp left and right */
8271 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8276 static struct hda_verb alc885_init_input_verbs[] = {
8277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8278 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8279 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8284 /* Unmute Selector 24h and set the default input to front mic */
8285 static struct hda_verb alc889_init_input_verbs[] = {
8286 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8287 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8292 #define alc883_init_verbs alc882_base_init_verbs
8294 /* Mac Pro test */
8295 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
8296 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8297 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8298 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8301 /* FIXME: this looks suspicious...
8302 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8303 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8305 { } /* end */
8308 static struct hda_verb alc882_macpro_init_verbs[] = {
8309 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8310 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8313 /* Front Pin: output 0 (0x0c) */
8314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8316 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8317 /* Front Mic pin: input vref at 80% */
8318 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8319 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8320 /* Speaker: output */
8321 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8322 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8323 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8324 /* Headphone output (output 0 - 0x0c) */
8325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8326 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8327 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8329 /* FIXME: use matrix-type input source selection */
8330 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8331 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8332 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8333 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8334 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8335 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8336 /* Input mixer2 */
8337 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8339 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8340 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8341 /* Input mixer3 */
8342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8344 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8346 /* ADC1: mute amp left and right */
8347 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8348 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8349 /* ADC2: mute amp left and right */
8350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8351 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8352 /* ADC3: mute amp left and right */
8353 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8354 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8359 /* Macbook 5,1 */
8360 static struct hda_verb alc885_mb5_init_verbs[] = {
8361 /* DACs */
8362 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8363 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8364 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8365 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8366 /* Front mixer */
8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* Surround mixer */
8371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 /* LFE mixer */
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8378 /* HP mixer */
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8382 /* Front Pin (0x0c) */
8383 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8384 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8386 /* LFE Pin (0x0e) */
8387 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8388 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8390 /* HP Pin (0x0f) */
8391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8395 /* Front Mic pin: input vref at 80% */
8396 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8397 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8398 /* Line In pin */
8399 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8400 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8408 /* Macmini 3,1 */
8409 static struct hda_verb alc885_macmini3_init_verbs[] = {
8410 /* DACs */
8411 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8412 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8413 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8414 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8415 /* Front mixer */
8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8419 /* Surround mixer */
8420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8423 /* LFE mixer */
8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8427 /* HP mixer */
8428 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8430 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8431 /* Front Pin (0x0c) */
8432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8433 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8435 /* LFE Pin (0x0e) */
8436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8438 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8439 /* HP Pin (0x0f) */
8440 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8441 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8442 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8444 /* Line In pin */
8445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8456 static struct hda_verb alc885_mba21_init_verbs[] = {
8457 /*Internal and HP Speaker Mixer*/
8458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8461 /*Internal Speaker Pin (0x0c)*/
8462 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8463 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8464 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8465 /* HP Pin: output 0 (0x0e) */
8466 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8467 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8468 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8469 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8470 /* Line in (is hp when jack connected)*/
8471 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8472 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8478 /* Macbook Pro rev3 */
8479 static struct hda_verb alc885_mbp3_init_verbs[] = {
8480 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8481 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8482 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8483 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8484 /* Rear mixer */
8485 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8486 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8487 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8488 /* HP mixer */
8489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8490 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8492 /* Front Pin: output 0 (0x0c) */
8493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8495 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8496 /* HP Pin: output 0 (0x0e) */
8497 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8500 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8501 /* Mic (rear) pin: input vref at 80% */
8502 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8503 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504 /* Front Mic pin: input vref at 80% */
8505 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8506 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8507 /* Line In pin: use output 1 when in LineOut mode */
8508 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8509 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8510 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8512 /* FIXME: use matrix-type input source selection */
8513 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8514 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8515 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8516 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8517 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8518 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8519 /* Input mixer2 */
8520 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8523 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8524 /* Input mixer3 */
8525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8526 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8528 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8529 /* ADC1: mute amp left and right */
8530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8531 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8532 /* ADC2: mute amp left and right */
8533 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8534 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8535 /* ADC3: mute amp left and right */
8536 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8537 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8542 /* iMac 9,1 */
8543 static struct hda_verb alc885_imac91_init_verbs[] = {
8544 /* Internal Speaker Pin (0x0c) */
8545 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8546 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8547 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8548 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8549 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8550 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8551 /* HP Pin: Rear */
8552 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8554 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8555 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8556 /* Line in Rear */
8557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8559 /* Front Mic pin: input vref at 80% */
8560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8562 /* Rear mixer */
8563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8566 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8570 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8571 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8573 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8575 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8576 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8585 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8586 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8587 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8588 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8589 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8590 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8591 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8593 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8597 /* iMac 24 mixer. */
8598 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8599 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8600 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8601 { } /* end */
8604 /* iMac 24 init verbs. */
8605 static struct hda_verb alc885_imac24_init_verbs[] = {
8606 /* Internal speakers: output 0 (0x0c) */
8607 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8608 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8610 /* Internal speakers: output 0 (0x0c) */
8611 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8612 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8613 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8614 /* Headphone: output 0 (0x0c) */
8615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8616 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8617 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8619 /* Front Mic: input vref at 80% */
8620 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8621 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8625 /* Toggle speaker-output according to the hp-jack state */
8626 static void alc885_imac24_setup(struct hda_codec *codec)
8628 struct alc_spec *spec = codec->spec;
8630 spec->autocfg.hp_pins[0] = 0x14;
8631 spec->autocfg.speaker_pins[0] = 0x18;
8632 spec->autocfg.speaker_pins[1] = 0x1a;
8635 #define alc885_mb5_setup alc885_imac24_setup
8636 #define alc885_macmini3_setup alc885_imac24_setup
8638 /* Macbook Air 2,1 */
8639 static void alc885_mba21_setup(struct hda_codec *codec)
8641 struct alc_spec *spec = codec->spec;
8643 spec->autocfg.hp_pins[0] = 0x14;
8644 spec->autocfg.speaker_pins[0] = 0x18;
8649 static void alc885_mbp3_setup(struct hda_codec *codec)
8651 struct alc_spec *spec = codec->spec;
8653 spec->autocfg.hp_pins[0] = 0x15;
8654 spec->autocfg.speaker_pins[0] = 0x14;
8657 static void alc885_imac91_setup(struct hda_codec *codec)
8659 struct alc_spec *spec = codec->spec;
8661 spec->autocfg.hp_pins[0] = 0x14;
8662 spec->autocfg.speaker_pins[0] = 0x18;
8663 spec->autocfg.speaker_pins[1] = 0x1a;
8666 static struct hda_verb alc882_targa_verbs[] = {
8667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8673 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8674 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8675 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8677 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8678 { } /* end */
8681 /* toggle speaker-output according to the hp-jack state */
8682 static void alc882_targa_automute(struct hda_codec *codec)
8684 struct alc_spec *spec = codec->spec;
8685 alc_automute_amp(codec);
8686 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8687 spec->jack_present ? 1 : 3);
8690 static void alc882_targa_setup(struct hda_codec *codec)
8692 struct alc_spec *spec = codec->spec;
8694 spec->autocfg.hp_pins[0] = 0x14;
8695 spec->autocfg.speaker_pins[0] = 0x1b;
8698 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8700 if ((res >> 26) == ALC880_HP_EVENT)
8701 alc882_targa_automute(codec);
8704 static struct hda_verb alc882_asus_a7j_verbs[] = {
8705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8708 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8710 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8713 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8714 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8716 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8717 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8718 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8719 { } /* end */
8722 static struct hda_verb alc882_asus_a7m_verbs[] = {
8723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8727 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8728 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8730 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8732 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8734 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8735 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8736 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8737 { } /* end */
8740 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8742 unsigned int gpiostate, gpiomask, gpiodir;
8744 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8745 AC_VERB_GET_GPIO_DATA, 0);
8747 if (!muted)
8748 gpiostate |= (1 << pin);
8749 else
8750 gpiostate &= ~(1 << pin);
8752 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8753 AC_VERB_GET_GPIO_MASK, 0);
8754 gpiomask |= (1 << pin);
8756 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8757 AC_VERB_GET_GPIO_DIRECTION, 0);
8758 gpiodir |= (1 << pin);
8761 snd_hda_codec_write(codec, codec->afg, 0,
8762 AC_VERB_SET_GPIO_MASK, gpiomask);
8763 snd_hda_codec_write(codec, codec->afg, 0,
8764 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8766 msleep(1);
8768 snd_hda_codec_write(codec, codec->afg, 0,
8769 AC_VERB_SET_GPIO_DATA, gpiostate);
8772 /* set up GPIO at initialization */
8773 static void alc885_macpro_init_hook(struct hda_codec *codec)
8775 alc882_gpio_mute(codec, 0, 0);
8776 alc882_gpio_mute(codec, 1, 0);
8779 /* set up GPIO and update auto-muting at initialization */
8780 static void alc885_imac24_init_hook(struct hda_codec *codec)
8782 alc885_macpro_init_hook(codec);
8783 alc_automute_amp(codec);
8787 * generic initialization of ADC, input mixers and output mixers
8789 static struct hda_verb alc883_auto_init_verbs[] = {
8791 * Unmute ADC0-2 and set the default input to mic-in
8793 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8795 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8796 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8799 * Set up output mixers (0x0c - 0x0f)
8801 /* set vol=0 to output mixers */
8802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8805 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8806 /* set up input amps for analog loopback */
8807 /* Amp Indices: DAC = 0, mixer = 1 */
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8809 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8810 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8811 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8812 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8813 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8814 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8816 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8817 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8819 /* FIXME: use matrix-type input source selection */
8820 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8821 /* Input mixer2 */
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8823 /* Input mixer3 */
8824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8828 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8829 static struct hda_verb alc889A_mb31_ch2_init[] = {
8830 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8832 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8833 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8834 { } /* end */
8837 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8838 static struct hda_verb alc889A_mb31_ch4_init[] = {
8839 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8840 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8842 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8843 { } /* end */
8846 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8847 static struct hda_verb alc889A_mb31_ch5_init[] = {
8848 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8849 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8850 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8852 { } /* end */
8855 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8856 static struct hda_verb alc889A_mb31_ch6_init[] = {
8857 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8858 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8859 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8860 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8861 { } /* end */
8864 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8865 { 2, alc889A_mb31_ch2_init },
8866 { 4, alc889A_mb31_ch4_init },
8867 { 5, alc889A_mb31_ch5_init },
8868 { 6, alc889A_mb31_ch6_init },
8871 static struct hda_verb alc883_medion_eapd_verbs[] = {
8872 /* eanable EAPD on medion laptop */
8873 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8874 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8878 #define alc883_base_mixer alc882_base_mixer
8880 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8883 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8884 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8885 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8886 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8888 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8889 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8891 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8892 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8893 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8894 { } /* end */
8897 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8898 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8899 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8900 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8901 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8906 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8907 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8908 { } /* end */
8911 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8913 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8914 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8915 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8917 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8920 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8921 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8922 { } /* end */
8925 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8926 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8927 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8930 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8934 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8937 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8938 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8939 { } /* end */
8942 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8943 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8944 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8945 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8946 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8947 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8948 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8949 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8950 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8951 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8952 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8953 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8954 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8955 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8957 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8958 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8959 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8960 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8961 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8962 { } /* end */
8965 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8966 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8967 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8968 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8969 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8970 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8971 HDA_OUTPUT),
8972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8981 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8983 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8984 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8985 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8986 { } /* end */
8989 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8991 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8992 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8993 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8994 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8995 HDA_OUTPUT),
8996 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8997 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8998 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8999 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9000 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9001 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9006 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9007 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9008 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9009 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9010 { } /* end */
9013 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9014 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9015 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9017 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9018 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9019 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9020 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9021 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9022 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9023 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9024 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9028 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9029 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9031 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9032 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9033 { } /* end */
9036 static struct snd_kcontrol_new alc883_targa_mixer[] = {
9037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9038 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9039 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9040 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9044 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9045 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9046 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9047 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9048 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9054 { } /* end */
9057 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9058 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9059 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9061 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9068 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9069 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9070 { } /* end */
9073 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9074 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9075 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9076 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9077 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9078 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9079 { } /* end */
9082 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9083 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9084 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9086 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9089 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9091 { } /* end */
9094 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9095 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9096 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9097 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9098 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9102 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9103 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9104 { } /* end */
9107 static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9109 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9110 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9112 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9113 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9114 { } /* end */
9117 static struct hda_verb alc883_medion_wim2160_verbs[] = {
9118 /* Unmute front mixer */
9119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9122 /* Set speaker pin to front mixer */
9123 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9125 /* Init headphone pin */
9126 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9127 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9128 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9129 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9131 { } /* end */
9134 /* toggle speaker-output according to the hp-jack state */
9135 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9137 struct alc_spec *spec = codec->spec;
9139 spec->autocfg.hp_pins[0] = 0x1a;
9140 spec->autocfg.speaker_pins[0] = 0x15;
9143 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9150 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9152 { } /* end */
9155 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9157 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9158 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9159 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9165 { } /* end */
9168 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9169 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9170 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9172 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9173 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9174 0x0d, 1, 0x0, HDA_OUTPUT),
9175 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9176 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9177 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9178 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9179 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9180 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9181 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9187 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9189 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9190 { } /* end */
9193 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9194 /* Output mixers */
9195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9196 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9197 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9198 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9199 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9200 HDA_OUTPUT),
9201 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9203 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9204 /* Output switches */
9205 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9206 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9207 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9208 /* Boost mixers */
9209 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9210 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9211 /* Input mixers */
9212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9216 { } /* end */
9219 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9226 { } /* end */
9229 static struct hda_bind_ctls alc883_bind_cap_vol = {
9230 .ops = &snd_hda_bind_vol,
9231 .values = {
9232 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9233 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9238 static struct hda_bind_ctls alc883_bind_cap_switch = {
9239 .ops = &snd_hda_bind_sw,
9240 .values = {
9241 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9242 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9247 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9249 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9256 { } /* end */
9259 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9260 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9261 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9264 /* .name = "Capture Source", */
9265 .name = "Input Source",
9266 .count = 1,
9267 .info = alc_mux_enum_info,
9268 .get = alc_mux_enum_get,
9269 .put = alc_mux_enum_put,
9271 { } /* end */
9274 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
9276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9277 .name = "Channel Mode",
9278 .info = alc_ch_mode_info,
9279 .get = alc_ch_mode_get,
9280 .put = alc_ch_mode_put,
9282 { } /* end */
9285 /* toggle speaker-output according to the hp-jack state */
9286 static void alc883_mitac_setup(struct hda_codec *codec)
9288 struct alc_spec *spec = codec->spec;
9290 spec->autocfg.hp_pins[0] = 0x15;
9291 spec->autocfg.speaker_pins[0] = 0x14;
9292 spec->autocfg.speaker_pins[1] = 0x17;
9295 static struct hda_verb alc883_mitac_verbs[] = {
9296 /* HP */
9297 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9298 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9299 /* Subwoofer */
9300 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9301 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9303 /* enable unsolicited event */
9304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9305 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9307 { } /* end */
9310 static struct hda_verb alc883_clevo_m540r_verbs[] = {
9311 /* HP */
9312 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9314 /* Int speaker */
9315 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9317 /* enable unsolicited event */
9319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9320 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9323 { } /* end */
9326 static struct hda_verb alc883_clevo_m720_verbs[] = {
9327 /* HP */
9328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9329 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9330 /* Int speaker */
9331 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9332 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9334 /* enable unsolicited event */
9335 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9336 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9338 { } /* end */
9341 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9342 /* HP */
9343 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9344 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9345 /* Subwoofer */
9346 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9347 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9349 /* enable unsolicited event */
9350 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9352 { } /* end */
9355 static struct hda_verb alc883_targa_verbs[] = {
9356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9359 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9362 /* Connect Line-Out side jack (SPDIF) to Side */
9363 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9364 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9365 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9366 /* Connect Mic jack to CLFE */
9367 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9368 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9369 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9370 /* Connect Line-in jack to Surround */
9371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9373 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9374 /* Connect HP out jack to Front */
9375 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9376 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9377 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9379 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9381 { } /* end */
9384 static struct hda_verb alc883_lenovo_101e_verbs[] = {
9385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9386 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9387 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9388 { } /* end */
9391 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9396 { } /* end */
9399 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9401 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9404 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9405 { } /* end */
9408 static struct hda_verb alc883_haier_w66_verbs[] = {
9409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9414 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9415 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9416 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9417 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9418 { } /* end */
9421 static struct hda_verb alc888_lenovo_sky_verbs[] = {
9422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9425 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9427 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9428 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9429 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9430 { } /* end */
9433 static struct hda_verb alc888_6st_dell_verbs[] = {
9434 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9438 static struct hda_verb alc883_vaiott_verbs[] = {
9439 /* HP */
9440 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9441 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9443 /* enable unsolicited event */
9444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9446 { } /* end */
9449 static void alc888_3st_hp_setup(struct hda_codec *codec)
9451 struct alc_spec *spec = codec->spec;
9453 spec->autocfg.hp_pins[0] = 0x1b;
9454 spec->autocfg.speaker_pins[0] = 0x14;
9455 spec->autocfg.speaker_pins[1] = 0x16;
9456 spec->autocfg.speaker_pins[2] = 0x18;
9459 static struct hda_verb alc888_3st_hp_verbs[] = {
9460 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9461 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9462 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9463 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9464 { } /* end */
9468 * 2ch mode
9470 static struct hda_verb alc888_3st_hp_2ch_init[] = {
9471 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9472 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9473 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9474 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9475 { } /* end */
9479 * 4ch mode
9481 static struct hda_verb alc888_3st_hp_4ch_init[] = {
9482 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9483 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9484 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9485 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9486 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9487 { } /* end */
9491 * 6ch mode
9493 static struct hda_verb alc888_3st_hp_6ch_init[] = {
9494 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9495 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9496 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9497 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9498 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9499 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9500 { } /* end */
9503 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
9504 { 2, alc888_3st_hp_2ch_init },
9505 { 4, alc888_3st_hp_4ch_init },
9506 { 6, alc888_3st_hp_6ch_init },
9509 /* toggle front-jack and RCA according to the hp-jack state */
9510 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
9512 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
9514 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9515 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9516 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9517 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9520 /* toggle RCA according to the front-jack state */
9521 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
9523 unsigned int present = snd_hda_jack_detect(codec, 0x14);
9525 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9526 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9529 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9530 unsigned int res)
9532 if ((res >> 26) == ALC880_HP_EVENT)
9533 alc888_lenovo_ms7195_front_automute(codec);
9534 if ((res >> 26) == ALC880_FRONT_EVENT)
9535 alc888_lenovo_ms7195_rca_automute(codec);
9538 /* toggle speaker-output according to the hp-jack state */
9539 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9541 struct alc_spec *spec = codec->spec;
9543 spec->autocfg.hp_pins[0] = 0x14;
9544 spec->autocfg.speaker_pins[0] = 0x15;
9547 /* toggle speaker-output according to the hp-jack state */
9548 #define alc883_targa_init_hook alc882_targa_init_hook
9549 #define alc883_targa_unsol_event alc882_targa_unsol_event
9551 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9553 struct alc_spec *spec = codec->spec;
9555 spec->autocfg.hp_pins[0] = 0x15;
9556 spec->autocfg.speaker_pins[0] = 0x14;
9559 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9561 alc_automute_amp(codec);
9562 alc88x_simple_mic_automute(codec);
9565 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9566 unsigned int res)
9568 switch (res >> 26) {
9569 case ALC880_MIC_EVENT:
9570 alc88x_simple_mic_automute(codec);
9571 break;
9572 default:
9573 alc_automute_amp_unsol_event(codec, res);
9574 break;
9578 /* toggle speaker-output according to the hp-jack state */
9579 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9581 struct alc_spec *spec = codec->spec;
9583 spec->autocfg.hp_pins[0] = 0x14;
9584 spec->autocfg.speaker_pins[0] = 0x15;
9587 static void alc883_haier_w66_setup(struct hda_codec *codec)
9589 struct alc_spec *spec = codec->spec;
9591 spec->autocfg.hp_pins[0] = 0x1b;
9592 spec->autocfg.speaker_pins[0] = 0x14;
9595 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9597 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9599 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9600 HDA_AMP_MUTE, bits);
9603 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9605 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9607 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9608 HDA_AMP_MUTE, bits);
9609 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9610 HDA_AMP_MUTE, bits);
9613 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9614 unsigned int res)
9616 if ((res >> 26) == ALC880_HP_EVENT)
9617 alc883_lenovo_101e_all_automute(codec);
9618 if ((res >> 26) == ALC880_FRONT_EVENT)
9619 alc883_lenovo_101e_ispeaker_automute(codec);
9622 /* toggle speaker-output according to the hp-jack state */
9623 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9625 struct alc_spec *spec = codec->spec;
9627 spec->autocfg.hp_pins[0] = 0x14;
9628 spec->autocfg.speaker_pins[0] = 0x15;
9629 spec->autocfg.speaker_pins[1] = 0x16;
9632 static struct hda_verb alc883_acer_eapd_verbs[] = {
9633 /* HP Pin: output 0 (0x0c) */
9634 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9635 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9636 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9637 /* Front Pin: output 0 (0x0c) */
9638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9639 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9640 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9641 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9642 /* eanable EAPD on medion laptop */
9643 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9644 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9645 /* enable unsolicited event */
9646 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9650 static void alc888_6st_dell_setup(struct hda_codec *codec)
9652 struct alc_spec *spec = codec->spec;
9654 spec->autocfg.hp_pins[0] = 0x1b;
9655 spec->autocfg.speaker_pins[0] = 0x14;
9656 spec->autocfg.speaker_pins[1] = 0x15;
9657 spec->autocfg.speaker_pins[2] = 0x16;
9658 spec->autocfg.speaker_pins[3] = 0x17;
9661 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9663 struct alc_spec *spec = codec->spec;
9665 spec->autocfg.hp_pins[0] = 0x1b;
9666 spec->autocfg.speaker_pins[0] = 0x14;
9667 spec->autocfg.speaker_pins[1] = 0x15;
9668 spec->autocfg.speaker_pins[2] = 0x16;
9669 spec->autocfg.speaker_pins[3] = 0x17;
9670 spec->autocfg.speaker_pins[4] = 0x1a;
9673 static void alc883_vaiott_setup(struct hda_codec *codec)
9675 struct alc_spec *spec = codec->spec;
9677 spec->autocfg.hp_pins[0] = 0x15;
9678 spec->autocfg.speaker_pins[0] = 0x14;
9679 spec->autocfg.speaker_pins[1] = 0x17;
9682 static struct hda_verb alc888_asus_m90v_verbs[] = {
9683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9686 /* enable unsolicited event */
9687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9689 { } /* end */
9692 static void alc883_mode2_setup(struct hda_codec *codec)
9694 struct alc_spec *spec = codec->spec;
9696 spec->autocfg.hp_pins[0] = 0x1b;
9697 spec->autocfg.speaker_pins[0] = 0x14;
9698 spec->autocfg.speaker_pins[1] = 0x15;
9699 spec->autocfg.speaker_pins[2] = 0x16;
9700 spec->ext_mic.pin = 0x18;
9701 spec->int_mic.pin = 0x19;
9702 spec->ext_mic.mux_idx = 0;
9703 spec->int_mic.mux_idx = 1;
9704 spec->auto_mic = 1;
9707 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9708 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9709 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9711 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9712 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9713 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9714 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9715 /* enable unsolicited event */
9716 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9717 { } /* end */
9720 static void alc883_eee1601_inithook(struct hda_codec *codec)
9722 struct alc_spec *spec = codec->spec;
9724 spec->autocfg.hp_pins[0] = 0x14;
9725 spec->autocfg.speaker_pins[0] = 0x1b;
9726 alc_automute_pin(codec);
9729 static struct hda_verb alc889A_mb31_verbs[] = {
9730 /* Init rear pin (used as headphone output) */
9731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9732 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9733 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9734 /* Init line pin (used as output in 4ch and 6ch mode) */
9735 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9736 /* Init line 2 pin (used as headphone out by default) */
9737 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9738 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9739 { } /* end */
9742 /* Mute speakers according to the headphone jack state */
9743 static void alc889A_mb31_automute(struct hda_codec *codec)
9745 unsigned int present;
9747 /* Mute only in 2ch or 4ch mode */
9748 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9749 == 0x00) {
9750 present = snd_hda_jack_detect(codec, 0x15);
9751 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9752 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9753 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9754 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9758 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9760 if ((res >> 26) == ALC880_HP_EVENT)
9761 alc889A_mb31_automute(codec);
9765 #ifdef CONFIG_SND_HDA_POWER_SAVE
9766 #define alc882_loopbacks alc880_loopbacks
9767 #endif
9769 /* pcm configuration: identical with ALC880 */
9770 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9771 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9772 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9773 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9775 static hda_nid_t alc883_slave_dig_outs[] = {
9776 ALC1200_DIGOUT_NID, 0,
9779 static hda_nid_t alc1200_slave_dig_outs[] = {
9780 ALC883_DIGOUT_NID, 0,
9784 * configuration and preset
9786 static const char * const alc882_models[ALC882_MODEL_LAST] = {
9787 [ALC882_3ST_DIG] = "3stack-dig",
9788 [ALC882_6ST_DIG] = "6stack-dig",
9789 [ALC882_ARIMA] = "arima",
9790 [ALC882_W2JC] = "w2jc",
9791 [ALC882_TARGA] = "targa",
9792 [ALC882_ASUS_A7J] = "asus-a7j",
9793 [ALC882_ASUS_A7M] = "asus-a7m",
9794 [ALC885_MACPRO] = "macpro",
9795 [ALC885_MB5] = "mb5",
9796 [ALC885_MACMINI3] = "macmini3",
9797 [ALC885_MBA21] = "mba21",
9798 [ALC885_MBP3] = "mbp3",
9799 [ALC885_IMAC24] = "imac24",
9800 [ALC885_IMAC91] = "imac91",
9801 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9802 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9803 [ALC883_3ST_6ch] = "3stack-6ch",
9804 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9805 [ALC883_TARGA_DIG] = "targa-dig",
9806 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9807 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9808 [ALC883_ACER] = "acer",
9809 [ALC883_ACER_ASPIRE] = "acer-aspire",
9810 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9811 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9812 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9813 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9814 [ALC883_MEDION] = "medion",
9815 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9816 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9817 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9818 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9819 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9820 [ALC888_LENOVO_SKY] = "lenovo-sky",
9821 [ALC883_HAIER_W66] = "haier-w66",
9822 [ALC888_3ST_HP] = "3stack-hp",
9823 [ALC888_6ST_DELL] = "6stack-dell",
9824 [ALC883_MITAC] = "mitac",
9825 [ALC883_CLEVO_M540R] = "clevo-m540r",
9826 [ALC883_CLEVO_M720] = "clevo-m720",
9827 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9828 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9829 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9830 [ALC889A_INTEL] = "intel-alc889a",
9831 [ALC889_INTEL] = "intel-x58",
9832 [ALC1200_ASUS_P5Q] = "asus-p5q",
9833 [ALC889A_MB31] = "mb31",
9834 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9835 [ALC882_AUTO] = "auto",
9838 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9839 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9841 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9842 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9843 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9844 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9845 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9846 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9847 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9848 ALC888_ACER_ASPIRE_4930G),
9849 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9850 ALC888_ACER_ASPIRE_4930G),
9851 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9852 ALC888_ACER_ASPIRE_8930G),
9853 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9854 ALC888_ACER_ASPIRE_8930G),
9855 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9856 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9857 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9858 ALC888_ACER_ASPIRE_6530G),
9859 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9860 ALC888_ACER_ASPIRE_6530G),
9861 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9862 ALC888_ACER_ASPIRE_7730G),
9863 /* default Acer -- disabled as it causes more problems.
9864 * model=auto should work fine now
9866 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9868 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9870 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9871 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9872 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9873 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9874 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9875 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9877 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9878 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9879 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9880 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9881 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9882 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9883 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9884 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9885 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9886 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9887 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9889 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9890 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9891 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9892 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9893 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9894 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9895 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9896 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9897 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9899 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9900 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9901 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9902 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9903 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9904 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9905 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9906 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9907 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9908 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9909 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9910 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9911 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9912 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9913 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9914 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9915 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9916 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9917 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9918 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9919 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9920 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9921 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9922 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9923 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9924 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9925 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9926 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9927 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9928 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9929 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9931 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9932 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9933 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9934 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9935 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9936 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9937 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9938 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9939 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9940 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9941 ALC883_FUJITSU_PI2515),
9942 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9943 ALC888_FUJITSU_XA3530),
9944 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9945 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9946 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9947 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9948 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9949 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9950 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9951 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9953 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9954 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9955 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9956 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9957 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9958 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9959 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9964 /* codec SSID table for Intel Mac */
9965 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9966 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9967 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9968 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9969 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9970 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9971 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9972 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9973 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
9974 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
9975 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
9976 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
9977 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9978 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9979 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9980 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9981 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9982 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
9983 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9984 * so apparently no perfect solution yet
9986 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9987 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9988 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9989 {} /* terminator */
9992 static struct alc_config_preset alc882_presets[] = {
9993 [ALC882_3ST_DIG] = {
9994 .mixers = { alc882_base_mixer },
9995 .init_verbs = { alc882_base_init_verbs,
9996 alc882_adc1_init_verbs },
9997 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9998 .dac_nids = alc882_dac_nids,
9999 .dig_out_nid = ALC882_DIGOUT_NID,
10000 .dig_in_nid = ALC882_DIGIN_NID,
10001 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10002 .channel_mode = alc882_ch_modes,
10003 .need_dac_fix = 1,
10004 .input_mux = &alc882_capture_source,
10006 [ALC882_6ST_DIG] = {
10007 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10008 .init_verbs = { alc882_base_init_verbs,
10009 alc882_adc1_init_verbs },
10010 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10011 .dac_nids = alc882_dac_nids,
10012 .dig_out_nid = ALC882_DIGOUT_NID,
10013 .dig_in_nid = ALC882_DIGIN_NID,
10014 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10015 .channel_mode = alc882_sixstack_modes,
10016 .input_mux = &alc882_capture_source,
10018 [ALC882_ARIMA] = {
10019 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10020 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10021 alc882_eapd_verbs },
10022 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10023 .dac_nids = alc882_dac_nids,
10024 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10025 .channel_mode = alc882_sixstack_modes,
10026 .input_mux = &alc882_capture_source,
10028 [ALC882_W2JC] = {
10029 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10030 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10031 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10032 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10033 .dac_nids = alc882_dac_nids,
10034 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10035 .channel_mode = alc880_threestack_modes,
10036 .need_dac_fix = 1,
10037 .input_mux = &alc882_capture_source,
10038 .dig_out_nid = ALC882_DIGOUT_NID,
10040 [ALC885_MBA21] = {
10041 .mixers = { alc885_mba21_mixer },
10042 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10043 .num_dacs = 2,
10044 .dac_nids = alc882_dac_nids,
10045 .channel_mode = alc885_mba21_ch_modes,
10046 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10047 .input_mux = &alc882_capture_source,
10048 .unsol_event = alc_automute_amp_unsol_event,
10049 .setup = alc885_mba21_setup,
10050 .init_hook = alc_automute_amp,
10052 [ALC885_MBP3] = {
10053 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10054 .init_verbs = { alc885_mbp3_init_verbs,
10055 alc880_gpio1_init_verbs },
10056 .num_dacs = 2,
10057 .dac_nids = alc882_dac_nids,
10058 .hp_nid = 0x04,
10059 .channel_mode = alc885_mbp_4ch_modes,
10060 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10061 .input_mux = &alc882_capture_source,
10062 .dig_out_nid = ALC882_DIGOUT_NID,
10063 .dig_in_nid = ALC882_DIGIN_NID,
10064 .unsol_event = alc_automute_amp_unsol_event,
10065 .setup = alc885_mbp3_setup,
10066 .init_hook = alc_automute_amp,
10068 [ALC885_MB5] = {
10069 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10070 .init_verbs = { alc885_mb5_init_verbs,
10071 alc880_gpio1_init_verbs },
10072 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10073 .dac_nids = alc882_dac_nids,
10074 .channel_mode = alc885_mb5_6ch_modes,
10075 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10076 .input_mux = &mb5_capture_source,
10077 .dig_out_nid = ALC882_DIGOUT_NID,
10078 .dig_in_nid = ALC882_DIGIN_NID,
10079 .unsol_event = alc_automute_amp_unsol_event,
10080 .setup = alc885_mb5_setup,
10081 .init_hook = alc_automute_amp,
10083 [ALC885_MACMINI3] = {
10084 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10085 .init_verbs = { alc885_macmini3_init_verbs,
10086 alc880_gpio1_init_verbs },
10087 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10088 .dac_nids = alc882_dac_nids,
10089 .channel_mode = alc885_macmini3_6ch_modes,
10090 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10091 .input_mux = &macmini3_capture_source,
10092 .dig_out_nid = ALC882_DIGOUT_NID,
10093 .dig_in_nid = ALC882_DIGIN_NID,
10094 .unsol_event = alc_automute_amp_unsol_event,
10095 .setup = alc885_macmini3_setup,
10096 .init_hook = alc_automute_amp,
10098 [ALC885_MACPRO] = {
10099 .mixers = { alc882_macpro_mixer },
10100 .init_verbs = { alc882_macpro_init_verbs },
10101 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10102 .dac_nids = alc882_dac_nids,
10103 .dig_out_nid = ALC882_DIGOUT_NID,
10104 .dig_in_nid = ALC882_DIGIN_NID,
10105 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10106 .channel_mode = alc882_ch_modes,
10107 .input_mux = &alc882_capture_source,
10108 .init_hook = alc885_macpro_init_hook,
10110 [ALC885_IMAC24] = {
10111 .mixers = { alc885_imac24_mixer },
10112 .init_verbs = { alc885_imac24_init_verbs },
10113 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10114 .dac_nids = alc882_dac_nids,
10115 .dig_out_nid = ALC882_DIGOUT_NID,
10116 .dig_in_nid = ALC882_DIGIN_NID,
10117 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10118 .channel_mode = alc882_ch_modes,
10119 .input_mux = &alc882_capture_source,
10120 .unsol_event = alc_automute_amp_unsol_event,
10121 .setup = alc885_imac24_setup,
10122 .init_hook = alc885_imac24_init_hook,
10124 [ALC885_IMAC91] = {
10125 .mixers = {alc885_imac91_mixer},
10126 .init_verbs = { alc885_imac91_init_verbs,
10127 alc880_gpio1_init_verbs },
10128 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10129 .dac_nids = alc882_dac_nids,
10130 .channel_mode = alc885_mba21_ch_modes,
10131 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10132 .input_mux = &alc889A_imac91_capture_source,
10133 .dig_out_nid = ALC882_DIGOUT_NID,
10134 .dig_in_nid = ALC882_DIGIN_NID,
10135 .unsol_event = alc_automute_amp_unsol_event,
10136 .setup = alc885_imac91_setup,
10137 .init_hook = alc_automute_amp,
10139 [ALC882_TARGA] = {
10140 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10141 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10142 alc880_gpio3_init_verbs, alc882_targa_verbs},
10143 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10144 .dac_nids = alc882_dac_nids,
10145 .dig_out_nid = ALC882_DIGOUT_NID,
10146 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10147 .adc_nids = alc882_adc_nids,
10148 .capsrc_nids = alc882_capsrc_nids,
10149 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10150 .channel_mode = alc882_3ST_6ch_modes,
10151 .need_dac_fix = 1,
10152 .input_mux = &alc882_capture_source,
10153 .unsol_event = alc882_targa_unsol_event,
10154 .setup = alc882_targa_setup,
10155 .init_hook = alc882_targa_automute,
10157 [ALC882_ASUS_A7J] = {
10158 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10159 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10160 alc882_asus_a7j_verbs},
10161 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10162 .dac_nids = alc882_dac_nids,
10163 .dig_out_nid = ALC882_DIGOUT_NID,
10164 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10165 .adc_nids = alc882_adc_nids,
10166 .capsrc_nids = alc882_capsrc_nids,
10167 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10168 .channel_mode = alc882_3ST_6ch_modes,
10169 .need_dac_fix = 1,
10170 .input_mux = &alc882_capture_source,
10172 [ALC882_ASUS_A7M] = {
10173 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10174 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10175 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10176 alc882_asus_a7m_verbs },
10177 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10178 .dac_nids = alc882_dac_nids,
10179 .dig_out_nid = ALC882_DIGOUT_NID,
10180 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10181 .channel_mode = alc880_threestack_modes,
10182 .need_dac_fix = 1,
10183 .input_mux = &alc882_capture_source,
10185 [ALC883_3ST_2ch_DIG] = {
10186 .mixers = { alc883_3ST_2ch_mixer },
10187 .init_verbs = { alc883_init_verbs },
10188 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10189 .dac_nids = alc883_dac_nids,
10190 .dig_out_nid = ALC883_DIGOUT_NID,
10191 .dig_in_nid = ALC883_DIGIN_NID,
10192 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10193 .channel_mode = alc883_3ST_2ch_modes,
10194 .input_mux = &alc883_capture_source,
10196 [ALC883_3ST_6ch_DIG] = {
10197 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10198 .init_verbs = { alc883_init_verbs },
10199 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10200 .dac_nids = alc883_dac_nids,
10201 .dig_out_nid = ALC883_DIGOUT_NID,
10202 .dig_in_nid = ALC883_DIGIN_NID,
10203 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10204 .channel_mode = alc883_3ST_6ch_modes,
10205 .need_dac_fix = 1,
10206 .input_mux = &alc883_capture_source,
10208 [ALC883_3ST_6ch] = {
10209 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10210 .init_verbs = { alc883_init_verbs },
10211 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10212 .dac_nids = alc883_dac_nids,
10213 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10214 .channel_mode = alc883_3ST_6ch_modes,
10215 .need_dac_fix = 1,
10216 .input_mux = &alc883_capture_source,
10218 [ALC883_3ST_6ch_INTEL] = {
10219 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10220 .init_verbs = { alc883_init_verbs },
10221 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10222 .dac_nids = alc883_dac_nids,
10223 .dig_out_nid = ALC883_DIGOUT_NID,
10224 .dig_in_nid = ALC883_DIGIN_NID,
10225 .slave_dig_outs = alc883_slave_dig_outs,
10226 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10227 .channel_mode = alc883_3ST_6ch_intel_modes,
10228 .need_dac_fix = 1,
10229 .input_mux = &alc883_3stack_6ch_intel,
10231 [ALC889A_INTEL] = {
10232 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10233 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10234 alc_hp15_unsol_verbs },
10235 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10236 .dac_nids = alc883_dac_nids,
10237 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10238 .adc_nids = alc889_adc_nids,
10239 .dig_out_nid = ALC883_DIGOUT_NID,
10240 .dig_in_nid = ALC883_DIGIN_NID,
10241 .slave_dig_outs = alc883_slave_dig_outs,
10242 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10243 .channel_mode = alc889_8ch_intel_modes,
10244 .capsrc_nids = alc889_capsrc_nids,
10245 .input_mux = &alc889_capture_source,
10246 .setup = alc889_automute_setup,
10247 .init_hook = alc_automute_amp,
10248 .unsol_event = alc_automute_amp_unsol_event,
10249 .need_dac_fix = 1,
10251 [ALC889_INTEL] = {
10252 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10253 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10254 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
10257 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10258 .adc_nids = alc889_adc_nids,
10259 .dig_out_nid = ALC883_DIGOUT_NID,
10260 .dig_in_nid = ALC883_DIGIN_NID,
10261 .slave_dig_outs = alc883_slave_dig_outs,
10262 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10263 .channel_mode = alc889_8ch_intel_modes,
10264 .capsrc_nids = alc889_capsrc_nids,
10265 .input_mux = &alc889_capture_source,
10266 .setup = alc889_automute_setup,
10267 .init_hook = alc889_intel_init_hook,
10268 .unsol_event = alc_automute_amp_unsol_event,
10269 .need_dac_fix = 1,
10271 [ALC883_6ST_DIG] = {
10272 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10273 .init_verbs = { alc883_init_verbs },
10274 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10275 .dac_nids = alc883_dac_nids,
10276 .dig_out_nid = ALC883_DIGOUT_NID,
10277 .dig_in_nid = ALC883_DIGIN_NID,
10278 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10279 .channel_mode = alc883_sixstack_modes,
10280 .input_mux = &alc883_capture_source,
10282 [ALC883_TARGA_DIG] = {
10283 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10284 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10285 alc883_targa_verbs},
10286 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10287 .dac_nids = alc883_dac_nids,
10288 .dig_out_nid = ALC883_DIGOUT_NID,
10289 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10290 .channel_mode = alc883_3ST_6ch_modes,
10291 .need_dac_fix = 1,
10292 .input_mux = &alc883_capture_source,
10293 .unsol_event = alc883_targa_unsol_event,
10294 .setup = alc882_targa_setup,
10295 .init_hook = alc882_targa_automute,
10297 [ALC883_TARGA_2ch_DIG] = {
10298 .mixers = { alc883_targa_2ch_mixer},
10299 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10300 alc883_targa_verbs},
10301 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10302 .dac_nids = alc883_dac_nids,
10303 .adc_nids = alc883_adc_nids_alt,
10304 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10305 .capsrc_nids = alc883_capsrc_nids,
10306 .dig_out_nid = ALC883_DIGOUT_NID,
10307 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10308 .channel_mode = alc883_3ST_2ch_modes,
10309 .input_mux = &alc883_capture_source,
10310 .unsol_event = alc883_targa_unsol_event,
10311 .setup = alc882_targa_setup,
10312 .init_hook = alc882_targa_automute,
10314 [ALC883_TARGA_8ch_DIG] = {
10315 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10316 alc883_chmode_mixer },
10317 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10318 alc883_targa_verbs },
10319 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10320 .dac_nids = alc883_dac_nids,
10321 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10322 .adc_nids = alc883_adc_nids_rev,
10323 .capsrc_nids = alc883_capsrc_nids_rev,
10324 .dig_out_nid = ALC883_DIGOUT_NID,
10325 .dig_in_nid = ALC883_DIGIN_NID,
10326 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10327 .channel_mode = alc883_4ST_8ch_modes,
10328 .need_dac_fix = 1,
10329 .input_mux = &alc883_capture_source,
10330 .unsol_event = alc883_targa_unsol_event,
10331 .setup = alc882_targa_setup,
10332 .init_hook = alc882_targa_automute,
10334 [ALC883_ACER] = {
10335 .mixers = { alc883_base_mixer },
10336 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10337 * and the headphone jack. Turn this on and rely on the
10338 * standard mute methods whenever the user wants to turn
10339 * these outputs off.
10341 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10342 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10343 .dac_nids = alc883_dac_nids,
10344 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10345 .channel_mode = alc883_3ST_2ch_modes,
10346 .input_mux = &alc883_capture_source,
10348 [ALC883_ACER_ASPIRE] = {
10349 .mixers = { alc883_acer_aspire_mixer },
10350 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10351 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10352 .dac_nids = alc883_dac_nids,
10353 .dig_out_nid = ALC883_DIGOUT_NID,
10354 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10355 .channel_mode = alc883_3ST_2ch_modes,
10356 .input_mux = &alc883_capture_source,
10357 .unsol_event = alc_automute_amp_unsol_event,
10358 .setup = alc883_acer_aspire_setup,
10359 .init_hook = alc_automute_amp,
10361 [ALC888_ACER_ASPIRE_4930G] = {
10362 .mixers = { alc888_base_mixer,
10363 alc883_chmode_mixer },
10364 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10365 alc888_acer_aspire_4930g_verbs },
10366 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10367 .dac_nids = alc883_dac_nids,
10368 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10369 .adc_nids = alc883_adc_nids_rev,
10370 .capsrc_nids = alc883_capsrc_nids_rev,
10371 .dig_out_nid = ALC883_DIGOUT_NID,
10372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10373 .channel_mode = alc883_3ST_6ch_modes,
10374 .need_dac_fix = 1,
10375 .const_channel_count = 6,
10376 .num_mux_defs =
10377 ARRAY_SIZE(alc888_2_capture_sources),
10378 .input_mux = alc888_2_capture_sources,
10379 .unsol_event = alc_automute_amp_unsol_event,
10380 .setup = alc888_acer_aspire_4930g_setup,
10381 .init_hook = alc_automute_amp,
10383 [ALC888_ACER_ASPIRE_6530G] = {
10384 .mixers = { alc888_acer_aspire_6530_mixer },
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10386 alc888_acer_aspire_6530g_verbs },
10387 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10388 .dac_nids = alc883_dac_nids,
10389 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10390 .adc_nids = alc883_adc_nids_rev,
10391 .capsrc_nids = alc883_capsrc_nids_rev,
10392 .dig_out_nid = ALC883_DIGOUT_NID,
10393 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10394 .channel_mode = alc883_3ST_2ch_modes,
10395 .num_mux_defs =
10396 ARRAY_SIZE(alc888_2_capture_sources),
10397 .input_mux = alc888_acer_aspire_6530_sources,
10398 .unsol_event = alc_automute_amp_unsol_event,
10399 .setup = alc888_acer_aspire_6530g_setup,
10400 .init_hook = alc_automute_amp,
10402 [ALC888_ACER_ASPIRE_8930G] = {
10403 .mixers = { alc889_acer_aspire_8930g_mixer,
10404 alc883_chmode_mixer },
10405 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10406 alc889_acer_aspire_8930g_verbs,
10407 alc889_eapd_verbs},
10408 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10409 .dac_nids = alc883_dac_nids,
10410 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10411 .adc_nids = alc889_adc_nids,
10412 .capsrc_nids = alc889_capsrc_nids,
10413 .dig_out_nid = ALC883_DIGOUT_NID,
10414 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10415 .channel_mode = alc883_3ST_6ch_modes,
10416 .need_dac_fix = 1,
10417 .const_channel_count = 6,
10418 .num_mux_defs =
10419 ARRAY_SIZE(alc889_capture_sources),
10420 .input_mux = alc889_capture_sources,
10421 .unsol_event = alc_automute_amp_unsol_event,
10422 .setup = alc889_acer_aspire_8930g_setup,
10423 .init_hook = alc_automute_amp,
10424 #ifdef CONFIG_SND_HDA_POWER_SAVE
10425 .power_hook = alc_power_eapd,
10426 #endif
10428 [ALC888_ACER_ASPIRE_7730G] = {
10429 .mixers = { alc883_3ST_6ch_mixer,
10430 alc883_chmode_mixer },
10431 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10432 alc888_acer_aspire_7730G_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10436 .adc_nids = alc883_adc_nids_rev,
10437 .capsrc_nids = alc883_capsrc_nids_rev,
10438 .dig_out_nid = ALC883_DIGOUT_NID,
10439 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10440 .channel_mode = alc883_3ST_6ch_modes,
10441 .need_dac_fix = 1,
10442 .const_channel_count = 6,
10443 .input_mux = &alc883_capture_source,
10444 .unsol_event = alc_automute_amp_unsol_event,
10445 .setup = alc888_acer_aspire_7730g_setup,
10446 .init_hook = alc_automute_amp,
10448 [ALC883_MEDION] = {
10449 .mixers = { alc883_fivestack_mixer,
10450 alc883_chmode_mixer },
10451 .init_verbs = { alc883_init_verbs,
10452 alc883_medion_eapd_verbs },
10453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10454 .dac_nids = alc883_dac_nids,
10455 .adc_nids = alc883_adc_nids_alt,
10456 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10457 .capsrc_nids = alc883_capsrc_nids,
10458 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10459 .channel_mode = alc883_sixstack_modes,
10460 .input_mux = &alc883_capture_source,
10462 [ALC883_MEDION_WIM2160] = {
10463 .mixers = { alc883_medion_wim2160_mixer },
10464 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10465 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10466 .dac_nids = alc883_dac_nids,
10467 .dig_out_nid = ALC883_DIGOUT_NID,
10468 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10469 .adc_nids = alc883_adc_nids,
10470 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10471 .channel_mode = alc883_3ST_2ch_modes,
10472 .input_mux = &alc883_capture_source,
10473 .unsol_event = alc_automute_amp_unsol_event,
10474 .setup = alc883_medion_wim2160_setup,
10475 .init_hook = alc_automute_amp,
10477 [ALC883_LAPTOP_EAPD] = {
10478 .mixers = { alc883_base_mixer },
10479 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
10482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10483 .channel_mode = alc883_3ST_2ch_modes,
10484 .input_mux = &alc883_capture_source,
10486 [ALC883_CLEVO_M540R] = {
10487 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10488 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10489 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10490 .dac_nids = alc883_dac_nids,
10491 .dig_out_nid = ALC883_DIGOUT_NID,
10492 .dig_in_nid = ALC883_DIGIN_NID,
10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10494 .channel_mode = alc883_3ST_6ch_clevo_modes,
10495 .need_dac_fix = 1,
10496 .input_mux = &alc883_capture_source,
10497 /* This machine has the hardware HP auto-muting, thus
10498 * we need no software mute via unsol event
10501 [ALC883_CLEVO_M720] = {
10502 .mixers = { alc883_clevo_m720_mixer },
10503 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10504 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10505 .dac_nids = alc883_dac_nids,
10506 .dig_out_nid = ALC883_DIGOUT_NID,
10507 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10508 .channel_mode = alc883_3ST_2ch_modes,
10509 .input_mux = &alc883_capture_source,
10510 .unsol_event = alc883_clevo_m720_unsol_event,
10511 .setup = alc883_clevo_m720_setup,
10512 .init_hook = alc883_clevo_m720_init_hook,
10514 [ALC883_LENOVO_101E_2ch] = {
10515 .mixers = { alc883_lenovo_101e_2ch_mixer},
10516 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10518 .dac_nids = alc883_dac_nids,
10519 .adc_nids = alc883_adc_nids_alt,
10520 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10521 .capsrc_nids = alc883_capsrc_nids,
10522 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10523 .channel_mode = alc883_3ST_2ch_modes,
10524 .input_mux = &alc883_lenovo_101e_capture_source,
10525 .unsol_event = alc883_lenovo_101e_unsol_event,
10526 .init_hook = alc883_lenovo_101e_all_automute,
10528 [ALC883_LENOVO_NB0763] = {
10529 .mixers = { alc883_lenovo_nb0763_mixer },
10530 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10532 .dac_nids = alc883_dac_nids,
10533 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10534 .channel_mode = alc883_3ST_2ch_modes,
10535 .need_dac_fix = 1,
10536 .input_mux = &alc883_lenovo_nb0763_capture_source,
10537 .unsol_event = alc_automute_amp_unsol_event,
10538 .setup = alc883_lenovo_nb0763_setup,
10539 .init_hook = alc_automute_amp,
10541 [ALC888_LENOVO_MS7195_DIG] = {
10542 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10543 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10544 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10545 .dac_nids = alc883_dac_nids,
10546 .dig_out_nid = ALC883_DIGOUT_NID,
10547 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10548 .channel_mode = alc883_3ST_6ch_modes,
10549 .need_dac_fix = 1,
10550 .input_mux = &alc883_capture_source,
10551 .unsol_event = alc883_lenovo_ms7195_unsol_event,
10552 .init_hook = alc888_lenovo_ms7195_front_automute,
10554 [ALC883_HAIER_W66] = {
10555 .mixers = { alc883_targa_2ch_mixer},
10556 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10557 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10558 .dac_nids = alc883_dac_nids,
10559 .dig_out_nid = ALC883_DIGOUT_NID,
10560 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10561 .channel_mode = alc883_3ST_2ch_modes,
10562 .input_mux = &alc883_capture_source,
10563 .unsol_event = alc_automute_amp_unsol_event,
10564 .setup = alc883_haier_w66_setup,
10565 .init_hook = alc_automute_amp,
10567 [ALC888_3ST_HP] = {
10568 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10569 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10571 .dac_nids = alc883_dac_nids,
10572 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10573 .channel_mode = alc888_3st_hp_modes,
10574 .need_dac_fix = 1,
10575 .input_mux = &alc883_capture_source,
10576 .unsol_event = alc_automute_amp_unsol_event,
10577 .setup = alc888_3st_hp_setup,
10578 .init_hook = alc_automute_amp,
10580 [ALC888_6ST_DELL] = {
10581 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10582 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10583 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10584 .dac_nids = alc883_dac_nids,
10585 .dig_out_nid = ALC883_DIGOUT_NID,
10586 .dig_in_nid = ALC883_DIGIN_NID,
10587 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10588 .channel_mode = alc883_sixstack_modes,
10589 .input_mux = &alc883_capture_source,
10590 .unsol_event = alc_automute_amp_unsol_event,
10591 .setup = alc888_6st_dell_setup,
10592 .init_hook = alc_automute_amp,
10594 [ALC883_MITAC] = {
10595 .mixers = { alc883_mitac_mixer },
10596 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10597 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10598 .dac_nids = alc883_dac_nids,
10599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10600 .channel_mode = alc883_3ST_2ch_modes,
10601 .input_mux = &alc883_capture_source,
10602 .unsol_event = alc_automute_amp_unsol_event,
10603 .setup = alc883_mitac_setup,
10604 .init_hook = alc_automute_amp,
10606 [ALC883_FUJITSU_PI2515] = {
10607 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10608 .init_verbs = { alc883_init_verbs,
10609 alc883_2ch_fujitsu_pi2515_verbs},
10610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611 .dac_nids = alc883_dac_nids,
10612 .dig_out_nid = ALC883_DIGOUT_NID,
10613 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10614 .channel_mode = alc883_3ST_2ch_modes,
10615 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10616 .unsol_event = alc_automute_amp_unsol_event,
10617 .setup = alc883_2ch_fujitsu_pi2515_setup,
10618 .init_hook = alc_automute_amp,
10620 [ALC888_FUJITSU_XA3530] = {
10621 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10622 .init_verbs = { alc883_init_verbs,
10623 alc888_fujitsu_xa3530_verbs },
10624 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10625 .dac_nids = alc883_dac_nids,
10626 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10627 .adc_nids = alc883_adc_nids_rev,
10628 .capsrc_nids = alc883_capsrc_nids_rev,
10629 .dig_out_nid = ALC883_DIGOUT_NID,
10630 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10631 .channel_mode = alc888_4ST_8ch_intel_modes,
10632 .num_mux_defs =
10633 ARRAY_SIZE(alc888_2_capture_sources),
10634 .input_mux = alc888_2_capture_sources,
10635 .unsol_event = alc_automute_amp_unsol_event,
10636 .setup = alc888_fujitsu_xa3530_setup,
10637 .init_hook = alc_automute_amp,
10639 [ALC888_LENOVO_SKY] = {
10640 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10641 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10642 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10643 .dac_nids = alc883_dac_nids,
10644 .dig_out_nid = ALC883_DIGOUT_NID,
10645 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10646 .channel_mode = alc883_sixstack_modes,
10647 .need_dac_fix = 1,
10648 .input_mux = &alc883_lenovo_sky_capture_source,
10649 .unsol_event = alc_automute_amp_unsol_event,
10650 .setup = alc888_lenovo_sky_setup,
10651 .init_hook = alc_automute_amp,
10653 [ALC888_ASUS_M90V] = {
10654 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10655 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10656 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10657 .dac_nids = alc883_dac_nids,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .dig_in_nid = ALC883_DIGIN_NID,
10660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10661 .channel_mode = alc883_3ST_6ch_modes,
10662 .need_dac_fix = 1,
10663 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10664 .unsol_event = alc_sku_unsol_event,
10665 .setup = alc883_mode2_setup,
10666 .init_hook = alc_inithook,
10668 [ALC888_ASUS_EEE1601] = {
10669 .mixers = { alc883_asus_eee1601_mixer },
10670 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10671 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10672 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10673 .dac_nids = alc883_dac_nids,
10674 .dig_out_nid = ALC883_DIGOUT_NID,
10675 .dig_in_nid = ALC883_DIGIN_NID,
10676 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10677 .channel_mode = alc883_3ST_2ch_modes,
10678 .need_dac_fix = 1,
10679 .input_mux = &alc883_asus_eee1601_capture_source,
10680 .unsol_event = alc_sku_unsol_event,
10681 .init_hook = alc883_eee1601_inithook,
10683 [ALC1200_ASUS_P5Q] = {
10684 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10685 .init_verbs = { alc883_init_verbs },
10686 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10687 .dac_nids = alc883_dac_nids,
10688 .dig_out_nid = ALC1200_DIGOUT_NID,
10689 .dig_in_nid = ALC883_DIGIN_NID,
10690 .slave_dig_outs = alc1200_slave_dig_outs,
10691 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10692 .channel_mode = alc883_sixstack_modes,
10693 .input_mux = &alc883_capture_source,
10695 [ALC889A_MB31] = {
10696 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10697 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10698 alc880_gpio1_init_verbs },
10699 .adc_nids = alc883_adc_nids,
10700 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10701 .capsrc_nids = alc883_capsrc_nids,
10702 .dac_nids = alc883_dac_nids,
10703 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10704 .channel_mode = alc889A_mb31_6ch_modes,
10705 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10706 .input_mux = &alc889A_mb31_capture_source,
10707 .dig_out_nid = ALC883_DIGOUT_NID,
10708 .unsol_event = alc889A_mb31_unsol_event,
10709 .init_hook = alc889A_mb31_automute,
10711 [ALC883_SONY_VAIO_TT] = {
10712 .mixers = { alc883_vaiott_mixer },
10713 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10714 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10715 .dac_nids = alc883_dac_nids,
10716 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10717 .channel_mode = alc883_3ST_2ch_modes,
10718 .input_mux = &alc883_capture_source,
10719 .unsol_event = alc_automute_amp_unsol_event,
10720 .setup = alc883_vaiott_setup,
10721 .init_hook = alc_automute_amp,
10727 * Pin config fixes
10729 enum {
10730 PINFIX_ABIT_AW9D_MAX,
10731 PINFIX_PB_M5210,
10732 PINFIX_ACER_ASPIRE_7736,
10735 static const struct alc_fixup alc882_fixups[] = {
10736 [PINFIX_ABIT_AW9D_MAX] = {
10737 .type = ALC_FIXUP_PINS,
10738 .v.pins = (const struct alc_pincfg[]) {
10739 { 0x15, 0x01080104 }, /* side */
10740 { 0x16, 0x01011012 }, /* rear */
10741 { 0x17, 0x01016011 }, /* clfe */
10745 [PINFIX_PB_M5210] = {
10746 .type = ALC_FIXUP_VERBS,
10747 .v.verbs = (const struct hda_verb[]) {
10748 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10752 [PINFIX_ACER_ASPIRE_7736] = {
10753 .type = ALC_FIXUP_SKU,
10754 .v.sku = ALC_FIXUP_SKU_IGNORE,
10758 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10759 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
10760 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10761 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
10766 * BIOS auto configuration
10768 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10769 const struct auto_pin_cfg *cfg)
10771 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10774 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10775 hda_nid_t nid, int pin_type,
10776 hda_nid_t dac)
10778 int idx;
10780 /* set as output */
10781 alc_set_pin_output(codec, nid, pin_type);
10783 if (dac == 0x25)
10784 idx = 4;
10785 else if (dac >= 0x02 && dac <= 0x05)
10786 idx = dac - 2;
10787 else
10788 return;
10789 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10792 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10794 struct alc_spec *spec = codec->spec;
10795 int i;
10797 for (i = 0; i <= HDA_SIDE; i++) {
10798 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10799 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10800 if (nid)
10801 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10802 spec->multiout.dac_nids[i]);
10806 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10808 struct alc_spec *spec = codec->spec;
10809 hda_nid_t pin, dac;
10810 int i;
10812 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
10813 pin = spec->autocfg.hp_pins[i];
10814 if (!pin)
10815 break;
10816 dac = spec->multiout.hp_nid;
10817 if (!dac)
10818 dac = spec->multiout.dac_nids[0]; /* to front */
10819 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10821 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
10822 pin = spec->autocfg.speaker_pins[i];
10823 if (!pin)
10824 break;
10825 dac = spec->multiout.extra_out_nid[0];
10826 if (!dac)
10827 dac = spec->multiout.dac_nids[0]; /* to front */
10828 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10832 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10834 struct alc_spec *spec = codec->spec;
10835 struct auto_pin_cfg *cfg = &spec->autocfg;
10836 int i;
10838 for (i = 0; i < cfg->num_inputs; i++) {
10839 hda_nid_t nid = cfg->inputs[i].pin;
10840 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
10841 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10842 snd_hda_codec_write(codec, nid, 0,
10843 AC_VERB_SET_AMP_GAIN_MUTE,
10844 AMP_OUT_MUTE);
10848 static void alc882_auto_init_input_src(struct hda_codec *codec)
10850 struct alc_spec *spec = codec->spec;
10851 int c;
10853 for (c = 0; c < spec->num_adc_nids; c++) {
10854 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10855 hda_nid_t nid = spec->capsrc_nids[c];
10856 unsigned int mux_idx;
10857 const struct hda_input_mux *imux;
10858 int conns, mute, idx, item;
10860 conns = snd_hda_get_connections(codec, nid, conn_list,
10861 ARRAY_SIZE(conn_list));
10862 if (conns < 0)
10863 continue;
10864 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10865 imux = &spec->input_mux[mux_idx];
10866 if (!imux->num_items && mux_idx > 0)
10867 imux = &spec->input_mux[0];
10868 for (idx = 0; idx < conns; idx++) {
10869 /* if the current connection is the selected one,
10870 * unmute it as default - otherwise mute it
10872 mute = AMP_IN_MUTE(idx);
10873 for (item = 0; item < imux->num_items; item++) {
10874 if (imux->items[item].index == idx) {
10875 if (spec->cur_mux[c] == item)
10876 mute = AMP_IN_UNMUTE(idx);
10877 break;
10880 /* check if we have a selector or mixer
10881 * we could check for the widget type instead, but
10882 * just check for Amp-In presence (in case of mixer
10883 * without amp-in there is something wrong, this
10884 * function shouldn't be used or capsrc nid is wrong)
10886 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10887 snd_hda_codec_write(codec, nid, 0,
10888 AC_VERB_SET_AMP_GAIN_MUTE,
10889 mute);
10890 else if (mute != AMP_IN_MUTE(idx))
10891 snd_hda_codec_write(codec, nid, 0,
10892 AC_VERB_SET_CONNECT_SEL,
10893 idx);
10898 /* add mic boosts if needed */
10899 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10901 struct alc_spec *spec = codec->spec;
10902 struct auto_pin_cfg *cfg = &spec->autocfg;
10903 int i, err;
10904 int type_idx = 0;
10905 hda_nid_t nid;
10906 const char *prev_label = NULL;
10908 for (i = 0; i < cfg->num_inputs; i++) {
10909 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10910 break;
10911 nid = cfg->inputs[i].pin;
10912 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10913 const char *label;
10914 char boost_label[32];
10916 label = hda_get_autocfg_input_label(codec, cfg, i);
10917 if (prev_label && !strcmp(label, prev_label))
10918 type_idx++;
10919 else
10920 type_idx = 0;
10921 prev_label = label;
10923 snprintf(boost_label, sizeof(boost_label),
10924 "%s Boost Volume", label);
10925 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10926 boost_label, type_idx,
10927 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10928 if (err < 0)
10929 return err;
10932 return 0;
10935 /* almost identical with ALC880 parser... */
10936 static int alc882_parse_auto_config(struct hda_codec *codec)
10938 struct alc_spec *spec = codec->spec;
10939 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10940 int err;
10942 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10943 alc882_ignore);
10944 if (err < 0)
10945 return err;
10946 if (!spec->autocfg.line_outs)
10947 return 0; /* can't find valid BIOS pin config */
10949 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10950 if (err < 0)
10951 return err;
10952 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10953 if (err < 0)
10954 return err;
10955 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10956 "Headphone");
10957 if (err < 0)
10958 return err;
10959 err = alc880_auto_create_extra_out(spec,
10960 spec->autocfg.speaker_pins[0],
10961 "Speaker");
10962 if (err < 0)
10963 return err;
10964 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10965 if (err < 0)
10966 return err;
10968 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10970 alc_auto_parse_digital(codec);
10972 if (spec->kctls.list)
10973 add_mixer(spec, spec->kctls.list);
10975 add_verb(spec, alc883_auto_init_verbs);
10976 /* if ADC 0x07 is available, initialize it, too */
10977 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10978 add_verb(spec, alc882_adc1_init_verbs);
10980 spec->num_mux_defs = 1;
10981 spec->input_mux = &spec->private_imux[0];
10983 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10985 err = alc_auto_add_mic_boost(codec);
10986 if (err < 0)
10987 return err;
10989 return 1; /* config found */
10992 /* additional initialization for auto-configuration model */
10993 static void alc882_auto_init(struct hda_codec *codec)
10995 struct alc_spec *spec = codec->spec;
10996 alc882_auto_init_multi_out(codec);
10997 alc882_auto_init_hp_out(codec);
10998 alc882_auto_init_analog_input(codec);
10999 alc882_auto_init_input_src(codec);
11000 alc_auto_init_digital(codec);
11001 if (spec->unsol_event)
11002 alc_inithook(codec);
11005 static int patch_alc882(struct hda_codec *codec)
11007 struct alc_spec *spec;
11008 int err, board_config;
11010 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11011 if (spec == NULL)
11012 return -ENOMEM;
11014 codec->spec = spec;
11016 switch (codec->vendor_id) {
11017 case 0x10ec0882:
11018 case 0x10ec0885:
11019 break;
11020 default:
11021 /* ALC883 and variants */
11022 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11023 break;
11026 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11027 alc882_models,
11028 alc882_cfg_tbl);
11030 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11031 board_config = snd_hda_check_board_codec_sid_config(codec,
11032 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11034 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11035 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11036 codec->chip_name);
11037 board_config = ALC882_AUTO;
11040 if (board_config == ALC882_AUTO) {
11041 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11042 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11045 alc_auto_parse_customize_define(codec);
11047 if (board_config == ALC882_AUTO) {
11048 /* automatic parse from the BIOS config */
11049 err = alc882_parse_auto_config(codec);
11050 if (err < 0) {
11051 alc_free(codec);
11052 return err;
11053 } else if (!err) {
11054 printk(KERN_INFO
11055 "hda_codec: Cannot set up configuration "
11056 "from BIOS. Using base mode...\n");
11057 board_config = ALC882_3ST_DIG;
11061 if (has_cdefine_beep(codec)) {
11062 err = snd_hda_attach_beep_device(codec, 0x1);
11063 if (err < 0) {
11064 alc_free(codec);
11065 return err;
11069 if (board_config != ALC882_AUTO)
11070 setup_preset(codec, &alc882_presets[board_config]);
11072 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11073 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11074 /* FIXME: setup DAC5 */
11075 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11076 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11078 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11079 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11081 if (!spec->adc_nids && spec->input_mux) {
11082 int i, j;
11083 spec->num_adc_nids = 0;
11084 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11085 const struct hda_input_mux *imux = spec->input_mux;
11086 hda_nid_t cap;
11087 hda_nid_t items[16];
11088 hda_nid_t nid = alc882_adc_nids[i];
11089 unsigned int wcap = get_wcaps(codec, nid);
11090 /* get type */
11091 wcap = get_wcaps_type(wcap);
11092 if (wcap != AC_WID_AUD_IN)
11093 continue;
11094 spec->private_adc_nids[spec->num_adc_nids] = nid;
11095 err = snd_hda_get_connections(codec, nid, &cap, 1);
11096 if (err < 0)
11097 continue;
11098 err = snd_hda_get_connections(codec, cap, items,
11099 ARRAY_SIZE(items));
11100 if (err < 0)
11101 continue;
11102 for (j = 0; j < imux->num_items; j++)
11103 if (imux->items[j].index >= err)
11104 break;
11105 if (j < imux->num_items)
11106 continue;
11107 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11108 spec->num_adc_nids++;
11110 spec->adc_nids = spec->private_adc_nids;
11111 spec->capsrc_nids = spec->private_capsrc_nids;
11114 set_capture_mixer(codec);
11116 if (has_cdefine_beep(codec))
11117 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11119 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11121 spec->vmaster_nid = 0x0c;
11123 codec->patch_ops = alc_patch_ops;
11124 if (board_config == ALC882_AUTO)
11125 spec->init_hook = alc882_auto_init;
11127 alc_init_jacks(codec);
11128 #ifdef CONFIG_SND_HDA_POWER_SAVE
11129 if (!spec->loopback.amplist)
11130 spec->loopback.amplist = alc882_loopbacks;
11131 #endif
11133 return 0;
11138 * ALC262 support
11141 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11142 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11144 #define alc262_dac_nids alc260_dac_nids
11145 #define alc262_adc_nids alc882_adc_nids
11146 #define alc262_adc_nids_alt alc882_adc_nids_alt
11147 #define alc262_capsrc_nids alc882_capsrc_nids
11148 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11150 #define alc262_modes alc260_modes
11151 #define alc262_capture_source alc882_capture_source
11153 static hda_nid_t alc262_dmic_adc_nids[1] = {
11154 /* ADC0 */
11155 0x09
11158 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11160 static struct snd_kcontrol_new alc262_base_mixer[] = {
11161 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11162 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11163 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11164 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11165 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11175 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11176 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11177 { } /* end */
11180 /* update HP, line and mono-out pins according to the master switch */
11181 static void alc262_hp_master_update(struct hda_codec *codec)
11183 struct alc_spec *spec = codec->spec;
11184 int val = spec->master_sw;
11186 /* HP & line-out */
11187 snd_hda_codec_write_cache(codec, 0x1b, 0,
11188 AC_VERB_SET_PIN_WIDGET_CONTROL,
11189 val ? PIN_HP : 0);
11190 snd_hda_codec_write_cache(codec, 0x15, 0,
11191 AC_VERB_SET_PIN_WIDGET_CONTROL,
11192 val ? PIN_HP : 0);
11193 /* mono (speaker) depending on the HP jack sense */
11194 val = val && !spec->jack_present;
11195 snd_hda_codec_write_cache(codec, 0x16, 0,
11196 AC_VERB_SET_PIN_WIDGET_CONTROL,
11197 val ? PIN_OUT : 0);
11200 static void alc262_hp_bpc_automute(struct hda_codec *codec)
11202 struct alc_spec *spec = codec->spec;
11204 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11205 alc262_hp_master_update(codec);
11208 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
11210 if ((res >> 26) != ALC880_HP_EVENT)
11211 return;
11212 alc262_hp_bpc_automute(codec);
11215 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
11217 struct alc_spec *spec = codec->spec;
11219 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11220 alc262_hp_master_update(codec);
11223 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
11224 unsigned int res)
11226 if ((res >> 26) != ALC880_HP_EVENT)
11227 return;
11228 alc262_hp_wildwest_automute(codec);
11231 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11233 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
11234 struct snd_ctl_elem_value *ucontrol)
11236 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11237 struct alc_spec *spec = codec->spec;
11238 int val = !!*ucontrol->value.integer.value;
11240 if (val == spec->master_sw)
11241 return 0;
11242 spec->master_sw = val;
11243 alc262_hp_master_update(codec);
11244 return 1;
11247 #define ALC262_HP_MASTER_SWITCH \
11249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11250 .name = "Master Playback Switch", \
11251 .info = snd_ctl_boolean_mono_info, \
11252 .get = alc262_hp_master_sw_get, \
11253 .put = alc262_hp_master_sw_put, \
11254 }, \
11256 .iface = NID_MAPPING, \
11257 .name = "Master Playback Switch", \
11258 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11262 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11263 ALC262_HP_MASTER_SWITCH,
11264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11265 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11267 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11268 HDA_OUTPUT),
11269 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11270 HDA_OUTPUT),
11271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11276 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11279 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11280 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11281 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11282 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11283 { } /* end */
11286 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11287 ALC262_HP_MASTER_SWITCH,
11288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11289 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11292 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11293 HDA_OUTPUT),
11294 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11295 HDA_OUTPUT),
11296 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11297 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11303 { } /* end */
11306 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11307 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11308 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11309 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11310 { } /* end */
11313 /* mute/unmute internal speaker according to the hp jack and mute state */
11314 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11316 struct alc_spec *spec = codec->spec;
11318 spec->autocfg.hp_pins[0] = 0x15;
11319 spec->autocfg.speaker_pins[0] = 0x14;
11322 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11323 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11324 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11325 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11330 { } /* end */
11333 static struct hda_verb alc262_hp_t5735_verbs[] = {
11334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11341 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11342 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11343 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11344 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11345 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11347 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11348 { } /* end */
11351 static struct hda_verb alc262_hp_rp5700_verbs[] = {
11352 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11353 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11365 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
11366 .num_items = 1,
11367 .items = {
11368 { "Line", 0x1 },
11372 /* bind hp and internal speaker mute (with plug check) as master switch */
11373 static void alc262_hippo_master_update(struct hda_codec *codec)
11375 struct alc_spec *spec = codec->spec;
11376 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11377 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11378 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11379 unsigned int mute;
11381 /* HP */
11382 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
11383 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
11384 HDA_AMP_MUTE, mute);
11385 /* mute internal speaker per jack sense */
11386 if (spec->jack_present)
11387 mute = HDA_AMP_MUTE;
11388 if (line_nid)
11389 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
11390 HDA_AMP_MUTE, mute);
11391 if (speaker_nid && speaker_nid != line_nid)
11392 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
11393 HDA_AMP_MUTE, mute);
11396 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11398 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
11399 struct snd_ctl_elem_value *ucontrol)
11401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11402 struct alc_spec *spec = codec->spec;
11403 int val = !!*ucontrol->value.integer.value;
11405 if (val == spec->master_sw)
11406 return 0;
11407 spec->master_sw = val;
11408 alc262_hippo_master_update(codec);
11409 return 1;
11412 #define ALC262_HIPPO_MASTER_SWITCH \
11414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11415 .name = "Master Playback Switch", \
11416 .info = snd_ctl_boolean_mono_info, \
11417 .get = alc262_hippo_master_sw_get, \
11418 .put = alc262_hippo_master_sw_put, \
11419 }, \
11421 .iface = NID_MAPPING, \
11422 .name = "Master Playback Switch", \
11423 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11424 (SUBDEV_SPEAKER(0) << 16), \
11427 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11428 ALC262_HIPPO_MASTER_SWITCH,
11429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11430 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11431 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11432 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11433 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11439 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11441 { } /* end */
11444 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11445 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446 ALC262_HIPPO_MASTER_SWITCH,
11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11457 { } /* end */
11460 /* mute/unmute internal speaker according to the hp jack and mute state */
11461 static void alc262_hippo_automute(struct hda_codec *codec)
11463 struct alc_spec *spec = codec->spec;
11464 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11466 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
11467 alc262_hippo_master_update(codec);
11470 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
11472 if ((res >> 26) != ALC880_HP_EVENT)
11473 return;
11474 alc262_hippo_automute(codec);
11477 static void alc262_hippo_setup(struct hda_codec *codec)
11479 struct alc_spec *spec = codec->spec;
11481 spec->autocfg.hp_pins[0] = 0x15;
11482 spec->autocfg.speaker_pins[0] = 0x14;
11485 static void alc262_hippo1_setup(struct hda_codec *codec)
11487 struct alc_spec *spec = codec->spec;
11489 spec->autocfg.hp_pins[0] = 0x1b;
11490 spec->autocfg.speaker_pins[0] = 0x14;
11494 static struct snd_kcontrol_new alc262_sony_mixer[] = {
11495 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11496 ALC262_HIPPO_MASTER_SWITCH,
11497 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11498 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11499 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11500 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11501 { } /* end */
11504 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11505 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 ALC262_HIPPO_MASTER_SWITCH,
11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11510 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11511 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11512 { } /* end */
11515 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11516 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11517 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11518 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11519 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11524 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11528 { } /* end */
11531 static struct hda_verb alc262_tyan_verbs[] = {
11532 /* Headphone automute */
11533 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11535 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11537 /* P11 AUX_IN, white 4-pin connector */
11538 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11539 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11540 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11541 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11546 /* unsolicited event for HP jack sensing */
11547 static void alc262_tyan_setup(struct hda_codec *codec)
11549 struct alc_spec *spec = codec->spec;
11551 spec->autocfg.hp_pins[0] = 0x1b;
11552 spec->autocfg.speaker_pins[0] = 0x15;
11556 #define alc262_capture_mixer alc882_capture_mixer
11557 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11560 * generic initialization of ADC, input mixers and output mixers
11562 static struct hda_verb alc262_init_verbs[] = {
11564 * Unmute ADC0-2 and set the default input to mic-in
11566 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11570 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11571 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11573 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11574 * mixer widget
11575 * Note: PASD motherboards uses the Line In 2 as the input for
11576 * front panel mic (mic 2)
11578 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11579 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11580 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11581 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11586 * Set up output mixers (0x0c - 0x0e)
11588 /* set vol=0 to output mixers */
11589 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11592 /* set up input amps for analog loopback */
11593 /* Amp Indices: DAC = 0, mixer = 1 */
11594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11595 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11597 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11598 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11599 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11603 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11604 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11605 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11606 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11609 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11610 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11611 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11612 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11615 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11617 /* FIXME: use matrix-type input source selection */
11618 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11619 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11620 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11621 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11622 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11623 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11624 /* Input mixer2 */
11625 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11626 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11627 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11628 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11629 /* Input mixer3 */
11630 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11631 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11632 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11633 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11638 static struct hda_verb alc262_eapd_verbs[] = {
11639 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11640 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11644 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11645 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11646 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11647 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11649 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11650 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11654 static struct hda_verb alc262_sony_unsol_verbs[] = {
11655 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11659 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11664 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11665 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11666 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11668 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11669 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11670 { } /* end */
11673 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11674 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11677 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11678 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11679 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11680 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11681 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11685 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11687 struct alc_spec *spec = codec->spec;
11689 spec->autocfg.hp_pins[0] = 0x15;
11690 spec->autocfg.speaker_pins[0] = 0x14;
11691 spec->ext_mic.pin = 0x18;
11692 spec->ext_mic.mux_idx = 0;
11693 spec->int_mic.pin = 0x12;
11694 spec->int_mic.mux_idx = 9;
11695 spec->auto_mic = 1;
11699 * nec model
11700 * 0x15 = headphone
11701 * 0x16 = internal speaker
11702 * 0x18 = external mic
11705 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11706 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11707 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11711 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11715 { } /* end */
11718 static struct hda_verb alc262_nec_verbs[] = {
11719 /* Unmute Speaker */
11720 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11722 /* Headphone */
11723 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11726 /* External mic to headphone */
11727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11728 /* External mic to speaker */
11729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11734 * fujitsu model
11735 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11736 * 0x1b = port replicator headphone out
11739 #define ALC_HP_EVENT 0x37
11741 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11742 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11744 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11745 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11749 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11750 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11751 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11755 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11756 /* Front Mic pin: input vref at 50% */
11757 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11762 static struct hda_input_mux alc262_fujitsu_capture_source = {
11763 .num_items = 3,
11764 .items = {
11765 { "Mic", 0x0 },
11766 { "Internal Mic", 0x1 },
11767 { "CD", 0x4 },
11771 static struct hda_input_mux alc262_HP_capture_source = {
11772 .num_items = 5,
11773 .items = {
11774 { "Mic", 0x0 },
11775 { "Front Mic", 0x1 },
11776 { "Line", 0x2 },
11777 { "CD", 0x4 },
11778 { "AUX IN", 0x6 },
11782 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11783 .num_items = 4,
11784 .items = {
11785 { "Mic", 0x0 },
11786 { "Front Mic", 0x2 },
11787 { "Line", 0x1 },
11788 { "CD", 0x4 },
11792 /* mute/unmute internal speaker according to the hp jacks and mute state */
11793 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11795 struct alc_spec *spec = codec->spec;
11796 unsigned int mute;
11798 if (force || !spec->sense_updated) {
11799 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11800 snd_hda_jack_detect(codec, 0x1b);
11801 spec->sense_updated = 1;
11803 /* unmute internal speaker only if both HPs are unplugged and
11804 * master switch is on
11806 if (spec->jack_present)
11807 mute = HDA_AMP_MUTE;
11808 else
11809 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11810 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11811 HDA_AMP_MUTE, mute);
11814 /* unsolicited event for HP jack sensing */
11815 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11816 unsigned int res)
11818 if ((res >> 26) != ALC_HP_EVENT)
11819 return;
11820 alc262_fujitsu_automute(codec, 1);
11823 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11825 alc262_fujitsu_automute(codec, 1);
11828 /* bind volumes of both NID 0x0c and 0x0d */
11829 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11830 .ops = &snd_hda_bind_vol,
11831 .values = {
11832 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11833 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11838 /* mute/unmute internal speaker according to the hp jack and mute state */
11839 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11841 struct alc_spec *spec = codec->spec;
11842 unsigned int mute;
11844 if (force || !spec->sense_updated) {
11845 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11846 spec->sense_updated = 1;
11848 if (spec->jack_present) {
11849 /* mute internal speaker */
11850 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11851 HDA_AMP_MUTE, HDA_AMP_MUTE);
11852 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11853 HDA_AMP_MUTE, HDA_AMP_MUTE);
11854 } else {
11855 /* unmute internal speaker if necessary */
11856 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11857 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11858 HDA_AMP_MUTE, mute);
11859 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11860 HDA_AMP_MUTE, mute);
11864 /* unsolicited event for HP jack sensing */
11865 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11866 unsigned int res)
11868 if ((res >> 26) != ALC_HP_EVENT)
11869 return;
11870 alc262_lenovo_3000_automute(codec, 1);
11873 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11874 int dir, int idx, long *valp)
11876 int i, change = 0;
11878 for (i = 0; i < 2; i++, valp++)
11879 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11880 HDA_AMP_MUTE,
11881 *valp ? 0 : HDA_AMP_MUTE);
11882 return change;
11885 /* bind hp and internal speaker mute (with plug check) */
11886 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11887 struct snd_ctl_elem_value *ucontrol)
11889 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11890 long *valp = ucontrol->value.integer.value;
11891 int change;
11893 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11894 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11895 if (change)
11896 alc262_fujitsu_automute(codec, 0);
11897 return change;
11900 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11901 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11904 .name = "Master Playback Switch",
11905 .subdevice = HDA_SUBDEV_AMP_FLAG,
11906 .info = snd_hda_mixer_amp_switch_info,
11907 .get = snd_hda_mixer_amp_switch_get,
11908 .put = alc262_fujitsu_master_sw_put,
11909 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11912 .iface = NID_MAPPING,
11913 .name = "Master Playback Switch",
11914 .private_value = 0x1b,
11916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11924 { } /* end */
11927 /* bind hp and internal speaker mute (with plug check) */
11928 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11929 struct snd_ctl_elem_value *ucontrol)
11931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11932 long *valp = ucontrol->value.integer.value;
11933 int change;
11935 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11936 if (change)
11937 alc262_lenovo_3000_automute(codec, 0);
11938 return change;
11941 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11942 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11944 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11945 .name = "Master Playback Switch",
11946 .subdevice = HDA_SUBDEV_AMP_FLAG,
11947 .info = snd_hda_mixer_amp_switch_info,
11948 .get = snd_hda_mixer_amp_switch_get,
11949 .put = alc262_lenovo_3000_master_sw_put,
11950 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11952 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11953 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11957 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11958 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11959 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11960 { } /* end */
11963 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11964 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11965 ALC262_HIPPO_MASTER_SWITCH,
11966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11968 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11969 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11971 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11972 { } /* end */
11975 /* additional init verbs for Benq laptops */
11976 static struct hda_verb alc262_EAPD_verbs[] = {
11977 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11978 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11982 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11984 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11986 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11987 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11991 /* Samsung Q1 Ultra Vista model setup */
11992 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11993 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11994 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11998 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11999 { } /* end */
12002 static struct hda_verb alc262_ultra_verbs[] = {
12003 /* output mixer */
12004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12007 /* speaker */
12008 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12009 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12010 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12011 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12012 /* HP */
12013 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12017 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12018 /* internal mic */
12019 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12021 /* ADC, choose mic */
12022 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12023 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12024 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12025 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12026 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12027 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12028 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12029 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12030 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12031 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12035 /* mute/unmute internal speaker according to the hp jack and mute state */
12036 static void alc262_ultra_automute(struct hda_codec *codec)
12038 struct alc_spec *spec = codec->spec;
12039 unsigned int mute;
12041 mute = 0;
12042 /* auto-mute only when HP is used as HP */
12043 if (!spec->cur_mux[0]) {
12044 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12045 if (spec->jack_present)
12046 mute = HDA_AMP_MUTE;
12048 /* mute/unmute internal speaker */
12049 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12050 HDA_AMP_MUTE, mute);
12051 /* mute/unmute HP */
12052 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12053 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12056 /* unsolicited event for HP jack sensing */
12057 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12058 unsigned int res)
12060 if ((res >> 26) != ALC880_HP_EVENT)
12061 return;
12062 alc262_ultra_automute(codec);
12065 static struct hda_input_mux alc262_ultra_capture_source = {
12066 .num_items = 2,
12067 .items = {
12068 { "Mic", 0x1 },
12069 { "Headphone", 0x7 },
12073 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12074 struct snd_ctl_elem_value *ucontrol)
12076 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12077 struct alc_spec *spec = codec->spec;
12078 int ret;
12080 ret = alc_mux_enum_put(kcontrol, ucontrol);
12081 if (!ret)
12082 return 0;
12083 /* reprogram the HP pin as mic or HP according to the input source */
12084 snd_hda_codec_write_cache(codec, 0x15, 0,
12085 AC_VERB_SET_PIN_WIDGET_CONTROL,
12086 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12087 alc262_ultra_automute(codec); /* mute/unmute HP */
12088 return ret;
12091 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12092 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12093 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12096 .name = "Capture Source",
12097 .info = alc_mux_enum_info,
12098 .get = alc_mux_enum_get,
12099 .put = alc262_ultra_mux_enum_put,
12102 .iface = NID_MAPPING,
12103 .name = "Capture Source",
12104 .private_value = 0x15,
12106 { } /* end */
12109 /* We use two mixers depending on the output pin; 0x16 is a mono output
12110 * and thus it's bound with a different mixer.
12111 * This function returns which mixer amp should be used.
12113 static int alc262_check_volbit(hda_nid_t nid)
12115 if (!nid)
12116 return 0;
12117 else if (nid == 0x16)
12118 return 2;
12119 else
12120 return 1;
12123 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12124 const char *pfx, int *vbits, int idx)
12126 unsigned long val;
12127 int vbit;
12129 vbit = alc262_check_volbit(nid);
12130 if (!vbit)
12131 return 0;
12132 if (*vbits & vbit) /* a volume control for this mixer already there */
12133 return 0;
12134 *vbits |= vbit;
12135 if (vbit == 2)
12136 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12137 else
12138 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12139 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12142 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12143 const char *pfx, int idx)
12145 unsigned long val;
12147 if (!nid)
12148 return 0;
12149 if (nid == 0x16)
12150 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12151 else
12152 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12153 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12156 /* add playback controls from the parsed DAC table */
12157 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12158 const struct auto_pin_cfg *cfg)
12160 const char *pfx;
12161 int vbits;
12162 int i, err;
12164 spec->multiout.num_dacs = 1; /* only use one dac */
12165 spec->multiout.dac_nids = spec->private_dac_nids;
12166 spec->multiout.dac_nids[0] = 2;
12168 pfx = alc_get_line_out_pfx(cfg, true);
12169 if (!pfx)
12170 pfx = "Front";
12171 for (i = 0; i < 2; i++) {
12172 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12173 if (err < 0)
12174 return err;
12175 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12176 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12177 "Speaker", i);
12178 if (err < 0)
12179 return err;
12181 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12182 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12183 "Headphone", i);
12184 if (err < 0)
12185 return err;
12189 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12190 alc262_check_volbit(cfg->speaker_pins[0]) |
12191 alc262_check_volbit(cfg->hp_pins[0]);
12192 if (vbits == 1 || vbits == 2)
12193 pfx = "Master"; /* only one mixer is used */
12194 vbits = 0;
12195 for (i = 0; i < 2; i++) {
12196 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12197 &vbits, i);
12198 if (err < 0)
12199 return err;
12200 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12201 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12202 "Speaker", &vbits, i);
12203 if (err < 0)
12204 return err;
12206 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12207 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12208 "Headphone", &vbits, i);
12209 if (err < 0)
12210 return err;
12213 return 0;
12216 #define alc262_auto_create_input_ctls \
12217 alc882_auto_create_input_ctls
12220 * generic initialization of ADC, input mixers and output mixers
12222 static struct hda_verb alc262_volume_init_verbs[] = {
12224 * Unmute ADC0-2 and set the default input to mic-in
12226 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12227 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12228 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12229 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12230 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12231 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12233 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12234 * mixer widget
12235 * Note: PASD motherboards uses the Line In 2 as the input for
12236 * front panel mic (mic 2)
12238 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12239 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12240 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12246 * Set up output mixers (0x0c - 0x0f)
12248 /* set vol=0 to output mixers */
12249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12251 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12253 /* set up input amps for analog loopback */
12254 /* Amp Indices: DAC = 0, mixer = 1 */
12255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12257 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12260 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12262 /* FIXME: use matrix-type input source selection */
12263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12264 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12265 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12266 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12267 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12268 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12269 /* Input mixer2 */
12270 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12271 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12272 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12273 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12274 /* Input mixer3 */
12275 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12283 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
12285 * Unmute ADC0-2 and set the default input to mic-in
12287 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12288 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12289 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12291 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12292 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12294 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12295 * mixer widget
12296 * Note: PASD motherboards uses the Line In 2 as the input for
12297 * front panel mic (mic 2)
12299 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12301 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12302 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12303 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12304 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12305 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12306 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12309 * Set up output mixers (0x0c - 0x0e)
12311 /* set vol=0 to output mixers */
12312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12313 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12314 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12316 /* set up input amps for analog loopback */
12317 /* Amp Indices: DAC = 0, mixer = 1 */
12318 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12320 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12321 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12322 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12323 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12325 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12326 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12327 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12329 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12332 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12333 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12337 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12339 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12341 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12344 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12345 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12346 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12349 /* FIXME: use matrix-type input source selection */
12350 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12351 /* Input mixer1: only unmute Mic */
12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12356 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12357 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12361 /* Input mixer2 */
12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12365 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12371 /* Input mixer3 */
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12376 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12378 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12379 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12380 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12382 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12387 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12389 * Unmute ADC0-2 and set the default input to mic-in
12391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12393 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12395 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12398 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12399 * mixer widget
12400 * Note: PASD motherboards uses the Line In 2 as the input for front
12401 * panel mic (mic 2)
12403 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12409 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12413 * Set up output mixers (0x0c - 0x0e)
12415 /* set vol=0 to output mixers */
12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12420 /* set up input amps for analog loopback */
12421 /* Amp Indices: DAC = 0, mixer = 1 */
12422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12423 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12424 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12425 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12426 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12427 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12431 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12439 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12442 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12444 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12445 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12446 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12448 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12449 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12451 /* FIXME: use matrix-type input source selection */
12452 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12453 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12458 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12459 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12461 /* Input mixer2 */
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12467 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12469 /* Input mixer3 */
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12475 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12478 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12483 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12486 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12487 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12490 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12492 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12495 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12501 * Pin config fixes
12503 enum {
12504 PINFIX_FSC_H270,
12507 static const struct alc_fixup alc262_fixups[] = {
12508 [PINFIX_FSC_H270] = {
12509 .type = ALC_FIXUP_PINS,
12510 .v.pins = (const struct alc_pincfg[]) {
12511 { 0x14, 0x99130110 }, /* speaker */
12512 { 0x15, 0x0221142f }, /* front HP */
12513 { 0x1b, 0x0121141f }, /* rear HP */
12519 static struct snd_pci_quirk alc262_fixup_tbl[] = {
12520 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12525 #ifdef CONFIG_SND_HDA_POWER_SAVE
12526 #define alc262_loopbacks alc880_loopbacks
12527 #endif
12529 /* pcm configuration: identical with ALC880 */
12530 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12531 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12532 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12533 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12536 * BIOS auto configuration
12538 static int alc262_parse_auto_config(struct hda_codec *codec)
12540 struct alc_spec *spec = codec->spec;
12541 int err;
12542 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12544 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12545 alc262_ignore);
12546 if (err < 0)
12547 return err;
12548 if (!spec->autocfg.line_outs) {
12549 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12550 spec->multiout.max_channels = 2;
12551 spec->no_analog = 1;
12552 goto dig_only;
12554 return 0; /* can't find valid BIOS pin config */
12556 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12557 if (err < 0)
12558 return err;
12559 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12560 if (err < 0)
12561 return err;
12563 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12565 dig_only:
12566 alc_auto_parse_digital(codec);
12568 if (spec->kctls.list)
12569 add_mixer(spec, spec->kctls.list);
12571 add_verb(spec, alc262_volume_init_verbs);
12572 spec->num_mux_defs = 1;
12573 spec->input_mux = &spec->private_imux[0];
12575 err = alc_auto_add_mic_boost(codec);
12576 if (err < 0)
12577 return err;
12579 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12581 return 1;
12584 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12585 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12586 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12587 #define alc262_auto_init_input_src alc882_auto_init_input_src
12590 /* init callback for auto-configuration model -- overriding the default init */
12591 static void alc262_auto_init(struct hda_codec *codec)
12593 struct alc_spec *spec = codec->spec;
12594 alc262_auto_init_multi_out(codec);
12595 alc262_auto_init_hp_out(codec);
12596 alc262_auto_init_analog_input(codec);
12597 alc262_auto_init_input_src(codec);
12598 alc_auto_init_digital(codec);
12599 if (spec->unsol_event)
12600 alc_inithook(codec);
12604 * configuration and preset
12606 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12607 [ALC262_BASIC] = "basic",
12608 [ALC262_HIPPO] = "hippo",
12609 [ALC262_HIPPO_1] = "hippo_1",
12610 [ALC262_FUJITSU] = "fujitsu",
12611 [ALC262_HP_BPC] = "hp-bpc",
12612 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12613 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12614 [ALC262_HP_RP5700] = "hp-rp5700",
12615 [ALC262_BENQ_ED8] = "benq",
12616 [ALC262_BENQ_T31] = "benq-t31",
12617 [ALC262_SONY_ASSAMD] = "sony-assamd",
12618 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12619 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12620 [ALC262_ULTRA] = "ultra",
12621 [ALC262_LENOVO_3000] = "lenovo-3000",
12622 [ALC262_NEC] = "nec",
12623 [ALC262_TYAN] = "tyan",
12624 [ALC262_AUTO] = "auto",
12627 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12628 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12629 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12630 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12631 ALC262_HP_BPC),
12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12633 ALC262_HP_BPC),
12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12635 ALC262_HP_BPC),
12636 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12637 ALC262_HP_BPC),
12638 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12639 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12640 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12641 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12642 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12643 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12644 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12645 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12646 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12647 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12648 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12649 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12650 ALC262_HP_TC_T5735),
12651 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12652 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12653 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12654 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12655 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12656 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12657 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12658 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12659 #if 0 /* disable the quirk since model=auto works better in recent versions */
12660 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12661 ALC262_SONY_ASSAMD),
12662 #endif
12663 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12664 ALC262_TOSHIBA_RX1),
12665 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12666 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12667 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12668 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12669 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12670 ALC262_ULTRA),
12671 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12672 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12673 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12674 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12675 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12679 static struct alc_config_preset alc262_presets[] = {
12680 [ALC262_BASIC] = {
12681 .mixers = { alc262_base_mixer },
12682 .init_verbs = { alc262_init_verbs },
12683 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12684 .dac_nids = alc262_dac_nids,
12685 .hp_nid = 0x03,
12686 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12687 .channel_mode = alc262_modes,
12688 .input_mux = &alc262_capture_source,
12690 [ALC262_HIPPO] = {
12691 .mixers = { alc262_hippo_mixer },
12692 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12693 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12694 .dac_nids = alc262_dac_nids,
12695 .hp_nid = 0x03,
12696 .dig_out_nid = ALC262_DIGOUT_NID,
12697 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12698 .channel_mode = alc262_modes,
12699 .input_mux = &alc262_capture_source,
12700 .unsol_event = alc262_hippo_unsol_event,
12701 .setup = alc262_hippo_setup,
12702 .init_hook = alc262_hippo_automute,
12704 [ALC262_HIPPO_1] = {
12705 .mixers = { alc262_hippo1_mixer },
12706 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12707 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12708 .dac_nids = alc262_dac_nids,
12709 .hp_nid = 0x02,
12710 .dig_out_nid = ALC262_DIGOUT_NID,
12711 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12712 .channel_mode = alc262_modes,
12713 .input_mux = &alc262_capture_source,
12714 .unsol_event = alc262_hippo_unsol_event,
12715 .setup = alc262_hippo1_setup,
12716 .init_hook = alc262_hippo_automute,
12718 [ALC262_FUJITSU] = {
12719 .mixers = { alc262_fujitsu_mixer },
12720 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12721 alc262_fujitsu_unsol_verbs },
12722 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12723 .dac_nids = alc262_dac_nids,
12724 .hp_nid = 0x03,
12725 .dig_out_nid = ALC262_DIGOUT_NID,
12726 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12727 .channel_mode = alc262_modes,
12728 .input_mux = &alc262_fujitsu_capture_source,
12729 .unsol_event = alc262_fujitsu_unsol_event,
12730 .init_hook = alc262_fujitsu_init_hook,
12732 [ALC262_HP_BPC] = {
12733 .mixers = { alc262_HP_BPC_mixer },
12734 .init_verbs = { alc262_HP_BPC_init_verbs },
12735 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12736 .dac_nids = alc262_dac_nids,
12737 .hp_nid = 0x03,
12738 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12739 .channel_mode = alc262_modes,
12740 .input_mux = &alc262_HP_capture_source,
12741 .unsol_event = alc262_hp_bpc_unsol_event,
12742 .init_hook = alc262_hp_bpc_automute,
12744 [ALC262_HP_BPC_D7000_WF] = {
12745 .mixers = { alc262_HP_BPC_WildWest_mixer },
12746 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12747 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12748 .dac_nids = alc262_dac_nids,
12749 .hp_nid = 0x03,
12750 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12751 .channel_mode = alc262_modes,
12752 .input_mux = &alc262_HP_D7000_capture_source,
12753 .unsol_event = alc262_hp_wildwest_unsol_event,
12754 .init_hook = alc262_hp_wildwest_automute,
12756 [ALC262_HP_BPC_D7000_WL] = {
12757 .mixers = { alc262_HP_BPC_WildWest_mixer,
12758 alc262_HP_BPC_WildWest_option_mixer },
12759 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12760 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12761 .dac_nids = alc262_dac_nids,
12762 .hp_nid = 0x03,
12763 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12764 .channel_mode = alc262_modes,
12765 .input_mux = &alc262_HP_D7000_capture_source,
12766 .unsol_event = alc262_hp_wildwest_unsol_event,
12767 .init_hook = alc262_hp_wildwest_automute,
12769 [ALC262_HP_TC_T5735] = {
12770 .mixers = { alc262_hp_t5735_mixer },
12771 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12772 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12773 .dac_nids = alc262_dac_nids,
12774 .hp_nid = 0x03,
12775 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12776 .channel_mode = alc262_modes,
12777 .input_mux = &alc262_capture_source,
12778 .unsol_event = alc_sku_unsol_event,
12779 .setup = alc262_hp_t5735_setup,
12780 .init_hook = alc_inithook,
12782 [ALC262_HP_RP5700] = {
12783 .mixers = { alc262_hp_rp5700_mixer },
12784 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12785 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12786 .dac_nids = alc262_dac_nids,
12787 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12788 .channel_mode = alc262_modes,
12789 .input_mux = &alc262_hp_rp5700_capture_source,
12791 [ALC262_BENQ_ED8] = {
12792 .mixers = { alc262_base_mixer },
12793 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12794 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12795 .dac_nids = alc262_dac_nids,
12796 .hp_nid = 0x03,
12797 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12798 .channel_mode = alc262_modes,
12799 .input_mux = &alc262_capture_source,
12801 [ALC262_SONY_ASSAMD] = {
12802 .mixers = { alc262_sony_mixer },
12803 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805 .dac_nids = alc262_dac_nids,
12806 .hp_nid = 0x02,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
12810 .unsol_event = alc262_hippo_unsol_event,
12811 .setup = alc262_hippo_setup,
12812 .init_hook = alc262_hippo_automute,
12814 [ALC262_BENQ_T31] = {
12815 .mixers = { alc262_benq_t31_mixer },
12816 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12817 alc_hp15_unsol_verbs },
12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819 .dac_nids = alc262_dac_nids,
12820 .hp_nid = 0x03,
12821 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12822 .channel_mode = alc262_modes,
12823 .input_mux = &alc262_capture_source,
12824 .unsol_event = alc262_hippo_unsol_event,
12825 .setup = alc262_hippo_setup,
12826 .init_hook = alc262_hippo_automute,
12828 [ALC262_ULTRA] = {
12829 .mixers = { alc262_ultra_mixer },
12830 .cap_mixer = alc262_ultra_capture_mixer,
12831 .init_verbs = { alc262_ultra_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .dac_nids = alc262_dac_nids,
12834 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12835 .channel_mode = alc262_modes,
12836 .input_mux = &alc262_ultra_capture_source,
12837 .adc_nids = alc262_adc_nids, /* ADC0 */
12838 .capsrc_nids = alc262_capsrc_nids,
12839 .num_adc_nids = 1, /* single ADC */
12840 .unsol_event = alc262_ultra_unsol_event,
12841 .init_hook = alc262_ultra_automute,
12843 [ALC262_LENOVO_3000] = {
12844 .mixers = { alc262_lenovo_3000_mixer },
12845 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12846 alc262_lenovo_3000_unsol_verbs,
12847 alc262_lenovo_3000_init_verbs },
12848 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12849 .dac_nids = alc262_dac_nids,
12850 .hp_nid = 0x03,
12851 .dig_out_nid = ALC262_DIGOUT_NID,
12852 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12853 .channel_mode = alc262_modes,
12854 .input_mux = &alc262_fujitsu_capture_source,
12855 .unsol_event = alc262_lenovo_3000_unsol_event,
12857 [ALC262_NEC] = {
12858 .mixers = { alc262_nec_mixer },
12859 .init_verbs = { alc262_nec_verbs },
12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12861 .dac_nids = alc262_dac_nids,
12862 .hp_nid = 0x03,
12863 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12864 .channel_mode = alc262_modes,
12865 .input_mux = &alc262_capture_source,
12867 [ALC262_TOSHIBA_S06] = {
12868 .mixers = { alc262_toshiba_s06_mixer },
12869 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12870 alc262_eapd_verbs },
12871 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12872 .capsrc_nids = alc262_dmic_capsrc_nids,
12873 .dac_nids = alc262_dac_nids,
12874 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12875 .num_adc_nids = 1, /* single ADC */
12876 .dig_out_nid = ALC262_DIGOUT_NID,
12877 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12878 .channel_mode = alc262_modes,
12879 .unsol_event = alc_sku_unsol_event,
12880 .setup = alc262_toshiba_s06_setup,
12881 .init_hook = alc_inithook,
12883 [ALC262_TOSHIBA_RX1] = {
12884 .mixers = { alc262_toshiba_rx1_mixer },
12885 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12886 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12887 .dac_nids = alc262_dac_nids,
12888 .hp_nid = 0x03,
12889 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12890 .channel_mode = alc262_modes,
12891 .input_mux = &alc262_capture_source,
12892 .unsol_event = alc262_hippo_unsol_event,
12893 .setup = alc262_hippo_setup,
12894 .init_hook = alc262_hippo_automute,
12896 [ALC262_TYAN] = {
12897 .mixers = { alc262_tyan_mixer },
12898 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12899 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12900 .dac_nids = alc262_dac_nids,
12901 .hp_nid = 0x02,
12902 .dig_out_nid = ALC262_DIGOUT_NID,
12903 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12904 .channel_mode = alc262_modes,
12905 .input_mux = &alc262_capture_source,
12906 .unsol_event = alc_automute_amp_unsol_event,
12907 .setup = alc262_tyan_setup,
12908 .init_hook = alc_automute_amp,
12912 static int patch_alc262(struct hda_codec *codec)
12914 struct alc_spec *spec;
12915 int board_config;
12916 int err;
12918 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12919 if (spec == NULL)
12920 return -ENOMEM;
12922 codec->spec = spec;
12923 #if 0
12924 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12925 * under-run
12928 int tmp;
12929 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12930 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12931 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12932 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12934 #endif
12935 alc_auto_parse_customize_define(codec);
12937 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12939 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12940 alc262_models,
12941 alc262_cfg_tbl);
12943 if (board_config < 0) {
12944 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12945 codec->chip_name);
12946 board_config = ALC262_AUTO;
12949 if (board_config == ALC262_AUTO) {
12950 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12951 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12954 if (board_config == ALC262_AUTO) {
12955 /* automatic parse from the BIOS config */
12956 err = alc262_parse_auto_config(codec);
12957 if (err < 0) {
12958 alc_free(codec);
12959 return err;
12960 } else if (!err) {
12961 printk(KERN_INFO
12962 "hda_codec: Cannot set up configuration "
12963 "from BIOS. Using base mode...\n");
12964 board_config = ALC262_BASIC;
12968 if (!spec->no_analog && has_cdefine_beep(codec)) {
12969 err = snd_hda_attach_beep_device(codec, 0x1);
12970 if (err < 0) {
12971 alc_free(codec);
12972 return err;
12976 if (board_config != ALC262_AUTO)
12977 setup_preset(codec, &alc262_presets[board_config]);
12979 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12980 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12982 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12983 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12985 if (!spec->adc_nids && spec->input_mux) {
12986 int i;
12987 /* check whether the digital-mic has to be supported */
12988 for (i = 0; i < spec->input_mux->num_items; i++) {
12989 if (spec->input_mux->items[i].index >= 9)
12990 break;
12992 if (i < spec->input_mux->num_items) {
12993 /* use only ADC0 */
12994 spec->adc_nids = alc262_dmic_adc_nids;
12995 spec->num_adc_nids = 1;
12996 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12997 } else {
12998 /* all analog inputs */
12999 /* check whether NID 0x07 is valid */
13000 unsigned int wcap = get_wcaps(codec, 0x07);
13002 /* get type */
13003 wcap = get_wcaps_type(wcap);
13004 if (wcap != AC_WID_AUD_IN) {
13005 spec->adc_nids = alc262_adc_nids_alt;
13006 spec->num_adc_nids =
13007 ARRAY_SIZE(alc262_adc_nids_alt);
13008 spec->capsrc_nids = alc262_capsrc_nids_alt;
13009 } else {
13010 spec->adc_nids = alc262_adc_nids;
13011 spec->num_adc_nids =
13012 ARRAY_SIZE(alc262_adc_nids);
13013 spec->capsrc_nids = alc262_capsrc_nids;
13017 if (!spec->cap_mixer && !spec->no_analog)
13018 set_capture_mixer(codec);
13019 if (!spec->no_analog && has_cdefine_beep(codec))
13020 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13022 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13024 spec->vmaster_nid = 0x0c;
13026 codec->patch_ops = alc_patch_ops;
13027 if (board_config == ALC262_AUTO)
13028 spec->init_hook = alc262_auto_init;
13030 alc_init_jacks(codec);
13031 #ifdef CONFIG_SND_HDA_POWER_SAVE
13032 if (!spec->loopback.amplist)
13033 spec->loopback.amplist = alc262_loopbacks;
13034 #endif
13036 return 0;
13040 * ALC268 channel source setting (2 channel)
13042 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13043 #define alc268_modes alc260_modes
13045 static hda_nid_t alc268_dac_nids[2] = {
13046 /* front, hp */
13047 0x02, 0x03
13050 static hda_nid_t alc268_adc_nids[2] = {
13051 /* ADC0-1 */
13052 0x08, 0x07
13055 static hda_nid_t alc268_adc_nids_alt[1] = {
13056 /* ADC0 */
13057 0x08
13060 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13062 static struct snd_kcontrol_new alc268_base_mixer[] = {
13063 /* output mixer control */
13064 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13066 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13068 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13069 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13070 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13074 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13075 /* output mixer control */
13076 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13077 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13078 ALC262_HIPPO_MASTER_SWITCH,
13079 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13080 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13081 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13085 /* bind Beep switches of both NID 0x0f and 0x10 */
13086 static struct hda_bind_ctls alc268_bind_beep_sw = {
13087 .ops = &snd_hda_bind_sw,
13088 .values = {
13089 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13090 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13095 static struct snd_kcontrol_new alc268_beep_mixer[] = {
13096 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13097 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13101 static struct hda_verb alc268_eapd_verbs[] = {
13102 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13103 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13107 /* Toshiba specific */
13108 static struct hda_verb alc268_toshiba_verbs[] = {
13109 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13110 { } /* end */
13113 /* Acer specific */
13114 /* bind volumes of both NID 0x02 and 0x03 */
13115 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
13116 .ops = &snd_hda_bind_vol,
13117 .values = {
13118 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13119 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13124 /* mute/unmute internal speaker according to the hp jack and mute state */
13125 static void alc268_acer_automute(struct hda_codec *codec, int force)
13127 struct alc_spec *spec = codec->spec;
13128 unsigned int mute;
13130 if (force || !spec->sense_updated) {
13131 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
13132 spec->sense_updated = 1;
13134 if (spec->jack_present)
13135 mute = HDA_AMP_MUTE; /* mute internal speaker */
13136 else /* unmute internal speaker if necessary */
13137 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
13138 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
13139 HDA_AMP_MUTE, mute);
13143 /* bind hp and internal speaker mute (with plug check) */
13144 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
13145 struct snd_ctl_elem_value *ucontrol)
13147 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
13148 long *valp = ucontrol->value.integer.value;
13149 int change;
13151 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
13152 if (change)
13153 alc268_acer_automute(codec, 0);
13154 return change;
13157 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13158 /* output mixer control */
13159 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13162 .name = "Master Playback Switch",
13163 .subdevice = HDA_SUBDEV_AMP_FLAG,
13164 .info = snd_hda_mixer_amp_switch_info,
13165 .get = snd_hda_mixer_amp_switch_get,
13166 .put = alc268_acer_master_sw_put,
13167 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13169 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13173 static struct snd_kcontrol_new alc268_acer_mixer[] = {
13174 /* output mixer control */
13175 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13178 .name = "Master Playback Switch",
13179 .subdevice = HDA_SUBDEV_AMP_FLAG,
13180 .info = snd_hda_mixer_amp_switch_info,
13181 .get = snd_hda_mixer_amp_switch_get,
13182 .put = alc268_acer_master_sw_put,
13183 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13186 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13187 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13191 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13192 /* output mixer control */
13193 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13195 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13196 .name = "Master Playback Switch",
13197 .subdevice = HDA_SUBDEV_AMP_FLAG,
13198 .info = snd_hda_mixer_amp_switch_info,
13199 .get = snd_hda_mixer_amp_switch_get,
13200 .put = alc268_acer_master_sw_put,
13201 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13204 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13208 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
13209 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13210 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13211 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13212 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13213 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13218 static struct hda_verb alc268_acer_verbs[] = {
13219 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13220 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13221 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13222 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13223 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13224 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13225 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13229 /* unsolicited event for HP jack sensing */
13230 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
13231 #define alc268_toshiba_setup alc262_hippo_setup
13232 #define alc268_toshiba_automute alc262_hippo_automute
13234 static void alc268_acer_unsol_event(struct hda_codec *codec,
13235 unsigned int res)
13237 if ((res >> 26) != ALC880_HP_EVENT)
13238 return;
13239 alc268_acer_automute(codec, 1);
13242 static void alc268_acer_init_hook(struct hda_codec *codec)
13244 alc268_acer_automute(codec, 1);
13247 /* toggle speaker-output according to the hp-jack state */
13248 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
13250 unsigned int present;
13251 unsigned char bits;
13253 present = snd_hda_jack_detect(codec, 0x15);
13254 bits = present ? HDA_AMP_MUTE : 0;
13255 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
13256 HDA_AMP_MUTE, bits);
13257 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
13258 HDA_AMP_MUTE, bits);
13261 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
13262 unsigned int res)
13264 switch (res >> 26) {
13265 case ALC880_HP_EVENT:
13266 alc268_aspire_one_speaker_automute(codec);
13267 break;
13268 case ALC880_MIC_EVENT:
13269 alc_mic_automute(codec);
13270 break;
13274 static void alc268_acer_lc_setup(struct hda_codec *codec)
13276 struct alc_spec *spec = codec->spec;
13277 spec->ext_mic.pin = 0x18;
13278 spec->ext_mic.mux_idx = 0;
13279 spec->int_mic.pin = 0x12;
13280 spec->int_mic.mux_idx = 6;
13281 spec->auto_mic = 1;
13284 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
13286 alc268_aspire_one_speaker_automute(codec);
13287 alc_mic_automute(codec);
13290 static struct snd_kcontrol_new alc268_dell_mixer[] = {
13291 /* output mixer control */
13292 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13297 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13301 static struct hda_verb alc268_dell_verbs[] = {
13302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13303 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13305 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13309 /* mute/unmute internal speaker according to the hp jack and mute state */
13310 static void alc268_dell_setup(struct hda_codec *codec)
13312 struct alc_spec *spec = codec->spec;
13314 spec->autocfg.hp_pins[0] = 0x15;
13315 spec->autocfg.speaker_pins[0] = 0x14;
13316 spec->ext_mic.pin = 0x18;
13317 spec->ext_mic.mux_idx = 0;
13318 spec->int_mic.pin = 0x19;
13319 spec->int_mic.mux_idx = 1;
13320 spec->auto_mic = 1;
13323 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13325 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13326 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13328 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13329 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13330 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13331 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13335 static struct hda_verb alc267_quanta_il1_verbs[] = {
13336 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13337 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13341 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13343 struct alc_spec *spec = codec->spec;
13344 spec->autocfg.hp_pins[0] = 0x15;
13345 spec->autocfg.speaker_pins[0] = 0x14;
13346 spec->ext_mic.pin = 0x18;
13347 spec->ext_mic.mux_idx = 0;
13348 spec->int_mic.pin = 0x19;
13349 spec->int_mic.mux_idx = 1;
13350 spec->auto_mic = 1;
13354 * generic initialization of ADC, input mixers and output mixers
13356 static struct hda_verb alc268_base_init_verbs[] = {
13357 /* Unmute DAC0-1 and set vol = 0 */
13358 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13359 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13362 * Set up output mixers (0x0c - 0x0e)
13364 /* set vol=0 to output mixers */
13365 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13368 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13369 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13371 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13372 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13374 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13375 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13376 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13377 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13378 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13380 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13382 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13383 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13384 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13386 /* set PCBEEP vol = 0, mute connections */
13387 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13388 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13389 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13391 /* Unmute Selector 23h,24h and set the default input to mic-in */
13393 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13394 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13395 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13396 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13402 * generic initialization of ADC, input mixers and output mixers
13404 static struct hda_verb alc268_volume_init_verbs[] = {
13405 /* set output DAC */
13406 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13407 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13411 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13413 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13415 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13417 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13419 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13420 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13422 /* set PCBEEP vol = 0, mute connections */
13423 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13425 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13430 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13431 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13432 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13433 { } /* end */
13436 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13437 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13438 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13439 _DEFINE_CAPSRC(1),
13440 { } /* end */
13443 static struct snd_kcontrol_new alc268_capture_mixer[] = {
13444 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13445 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13446 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13447 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13448 _DEFINE_CAPSRC(2),
13449 { } /* end */
13452 static struct hda_input_mux alc268_capture_source = {
13453 .num_items = 4,
13454 .items = {
13455 { "Mic", 0x0 },
13456 { "Front Mic", 0x1 },
13457 { "Line", 0x2 },
13458 { "CD", 0x3 },
13462 static struct hda_input_mux alc268_acer_capture_source = {
13463 .num_items = 3,
13464 .items = {
13465 { "Mic", 0x0 },
13466 { "Internal Mic", 0x1 },
13467 { "Line", 0x2 },
13471 static struct hda_input_mux alc268_acer_dmic_capture_source = {
13472 .num_items = 3,
13473 .items = {
13474 { "Mic", 0x0 },
13475 { "Internal Mic", 0x6 },
13476 { "Line", 0x2 },
13480 #ifdef CONFIG_SND_DEBUG
13481 static struct snd_kcontrol_new alc268_test_mixer[] = {
13482 /* Volume widgets */
13483 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13484 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13485 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13486 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13487 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13488 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13489 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13490 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13491 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13492 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13493 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13494 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13495 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13496 /* The below appears problematic on some hardwares */
13497 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13498 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13499 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13500 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13501 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13503 /* Modes for retasking pin widgets */
13504 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13505 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13506 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13507 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13509 /* Controls for GPIO pins, assuming they are configured as outputs */
13510 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13511 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13512 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13513 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13515 /* Switches to allow the digital SPDIF output pin to be enabled.
13516 * The ALC268 does not have an SPDIF input.
13518 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13520 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13521 * this output to turn on an external amplifier.
13523 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13524 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13526 { } /* end */
13528 #endif
13530 /* create input playback/capture controls for the given pin */
13531 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13532 const char *ctlname, int idx)
13534 hda_nid_t dac;
13535 int err;
13537 switch (nid) {
13538 case 0x14:
13539 case 0x16:
13540 dac = 0x02;
13541 break;
13542 case 0x15:
13543 case 0x1a: /* ALC259/269 only */
13544 case 0x1b: /* ALC259/269 only */
13545 case 0x21: /* ALC269vb has this pin, too */
13546 dac = 0x03;
13547 break;
13548 default:
13549 snd_printd(KERN_WARNING "hda_codec: "
13550 "ignoring pin 0x%x as unknown\n", nid);
13551 return 0;
13553 if (spec->multiout.dac_nids[0] != dac &&
13554 spec->multiout.dac_nids[1] != dac) {
13555 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13556 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13557 HDA_OUTPUT));
13558 if (err < 0)
13559 return err;
13560 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
13563 if (nid != 0x16)
13564 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13565 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13566 else /* mono */
13567 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13568 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13569 if (err < 0)
13570 return err;
13571 return 0;
13574 /* add playback controls from the parsed DAC table */
13575 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13576 const struct auto_pin_cfg *cfg)
13578 hda_nid_t nid;
13579 int err;
13581 spec->multiout.dac_nids = spec->private_dac_nids;
13583 nid = cfg->line_out_pins[0];
13584 if (nid) {
13585 const char *name;
13586 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13587 name = "Speaker";
13588 else
13589 name = "Front";
13590 err = alc268_new_analog_output(spec, nid, name, 0);
13591 if (err < 0)
13592 return err;
13595 nid = cfg->speaker_pins[0];
13596 if (nid == 0x1d) {
13597 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13598 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13599 if (err < 0)
13600 return err;
13601 } else if (nid) {
13602 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13603 if (err < 0)
13604 return err;
13606 nid = cfg->hp_pins[0];
13607 if (nid) {
13608 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13609 if (err < 0)
13610 return err;
13613 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13614 if (nid == 0x16) {
13615 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13616 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13617 if (err < 0)
13618 return err;
13620 return 0;
13623 /* create playback/capture controls for input pins */
13624 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13625 const struct auto_pin_cfg *cfg)
13627 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13630 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13631 hda_nid_t nid, int pin_type)
13633 int idx;
13635 alc_set_pin_output(codec, nid, pin_type);
13636 if (nid == 0x14 || nid == 0x16)
13637 idx = 0;
13638 else
13639 idx = 1;
13640 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13643 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13645 struct alc_spec *spec = codec->spec;
13646 int i;
13648 for (i = 0; i < spec->autocfg.line_outs; i++) {
13649 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13650 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13651 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13655 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13657 struct alc_spec *spec = codec->spec;
13658 hda_nid_t pin;
13659 int i;
13661 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13662 pin = spec->autocfg.hp_pins[i];
13663 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13665 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13666 pin = spec->autocfg.speaker_pins[i];
13667 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13669 if (spec->autocfg.mono_out_pin)
13670 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13671 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13674 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13676 struct alc_spec *spec = codec->spec;
13677 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13678 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13679 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13680 unsigned int dac_vol1, dac_vol2;
13682 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13683 snd_hda_codec_write(codec, speaker_nid, 0,
13684 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13685 /* mute mixer inputs from 0x1d */
13686 snd_hda_codec_write(codec, 0x0f, 0,
13687 AC_VERB_SET_AMP_GAIN_MUTE,
13688 AMP_IN_UNMUTE(1));
13689 snd_hda_codec_write(codec, 0x10, 0,
13690 AC_VERB_SET_AMP_GAIN_MUTE,
13691 AMP_IN_UNMUTE(1));
13692 } else {
13693 /* unmute mixer inputs from 0x1d */
13694 snd_hda_codec_write(codec, 0x0f, 0,
13695 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13696 snd_hda_codec_write(codec, 0x10, 0,
13697 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13700 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13701 if (line_nid == 0x14)
13702 dac_vol2 = AMP_OUT_ZERO;
13703 else if (line_nid == 0x15)
13704 dac_vol1 = AMP_OUT_ZERO;
13705 if (hp_nid == 0x14)
13706 dac_vol2 = AMP_OUT_ZERO;
13707 else if (hp_nid == 0x15)
13708 dac_vol1 = AMP_OUT_ZERO;
13709 if (line_nid != 0x16 || hp_nid != 0x16 ||
13710 spec->autocfg.line_out_pins[1] != 0x16 ||
13711 spec->autocfg.line_out_pins[2] != 0x16)
13712 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13714 snd_hda_codec_write(codec, 0x02, 0,
13715 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13716 snd_hda_codec_write(codec, 0x03, 0,
13717 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13720 /* pcm configuration: identical with ALC880 */
13721 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13722 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13723 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13724 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13727 * BIOS auto configuration
13729 static int alc268_parse_auto_config(struct hda_codec *codec)
13731 struct alc_spec *spec = codec->spec;
13732 int err;
13733 static hda_nid_t alc268_ignore[] = { 0 };
13735 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13736 alc268_ignore);
13737 if (err < 0)
13738 return err;
13739 if (!spec->autocfg.line_outs) {
13740 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13741 spec->multiout.max_channels = 2;
13742 spec->no_analog = 1;
13743 goto dig_only;
13745 return 0; /* can't find valid BIOS pin config */
13747 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13748 if (err < 0)
13749 return err;
13750 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13751 if (err < 0)
13752 return err;
13754 spec->multiout.max_channels = 2;
13756 dig_only:
13757 /* digital only support output */
13758 alc_auto_parse_digital(codec);
13759 if (spec->kctls.list)
13760 add_mixer(spec, spec->kctls.list);
13762 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13763 add_mixer(spec, alc268_beep_mixer);
13765 add_verb(spec, alc268_volume_init_verbs);
13766 spec->num_mux_defs = 2;
13767 spec->input_mux = &spec->private_imux[0];
13769 err = alc_auto_add_mic_boost(codec);
13770 if (err < 0)
13771 return err;
13773 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13775 return 1;
13778 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13780 /* init callback for auto-configuration model -- overriding the default init */
13781 static void alc268_auto_init(struct hda_codec *codec)
13783 struct alc_spec *spec = codec->spec;
13784 alc268_auto_init_multi_out(codec);
13785 alc268_auto_init_hp_out(codec);
13786 alc268_auto_init_mono_speaker_out(codec);
13787 alc268_auto_init_analog_input(codec);
13788 alc_auto_init_digital(codec);
13789 if (spec->unsol_event)
13790 alc_inithook(codec);
13794 * configuration and preset
13796 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13797 [ALC267_QUANTA_IL1] = "quanta-il1",
13798 [ALC268_3ST] = "3stack",
13799 [ALC268_TOSHIBA] = "toshiba",
13800 [ALC268_ACER] = "acer",
13801 [ALC268_ACER_DMIC] = "acer-dmic",
13802 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13803 [ALC268_DELL] = "dell",
13804 [ALC268_ZEPTO] = "zepto",
13805 #ifdef CONFIG_SND_DEBUG
13806 [ALC268_TEST] = "test",
13807 #endif
13808 [ALC268_AUTO] = "auto",
13811 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13812 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13813 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13814 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13815 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13816 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13817 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13818 ALC268_ACER_ASPIRE_ONE),
13819 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13820 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13821 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13822 /* almost compatible with toshiba but with optional digital outs;
13823 * auto-probing seems working fine
13825 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13826 ALC268_AUTO),
13827 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13828 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13829 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13830 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13831 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13835 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13836 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13837 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13838 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13839 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13840 ALC268_TOSHIBA),
13844 static struct alc_config_preset alc268_presets[] = {
13845 [ALC267_QUANTA_IL1] = {
13846 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13847 alc268_capture_nosrc_mixer },
13848 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13849 alc267_quanta_il1_verbs },
13850 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13851 .dac_nids = alc268_dac_nids,
13852 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13853 .adc_nids = alc268_adc_nids_alt,
13854 .hp_nid = 0x03,
13855 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13856 .channel_mode = alc268_modes,
13857 .unsol_event = alc_sku_unsol_event,
13858 .setup = alc267_quanta_il1_setup,
13859 .init_hook = alc_inithook,
13861 [ALC268_3ST] = {
13862 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13863 alc268_beep_mixer },
13864 .init_verbs = { alc268_base_init_verbs },
13865 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13866 .dac_nids = alc268_dac_nids,
13867 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13868 .adc_nids = alc268_adc_nids_alt,
13869 .capsrc_nids = alc268_capsrc_nids,
13870 .hp_nid = 0x03,
13871 .dig_out_nid = ALC268_DIGOUT_NID,
13872 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13873 .channel_mode = alc268_modes,
13874 .input_mux = &alc268_capture_source,
13876 [ALC268_TOSHIBA] = {
13877 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13878 alc268_beep_mixer },
13879 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13880 alc268_toshiba_verbs },
13881 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13882 .dac_nids = alc268_dac_nids,
13883 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13884 .adc_nids = alc268_adc_nids_alt,
13885 .capsrc_nids = alc268_capsrc_nids,
13886 .hp_nid = 0x03,
13887 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13888 .channel_mode = alc268_modes,
13889 .input_mux = &alc268_capture_source,
13890 .unsol_event = alc268_toshiba_unsol_event,
13891 .setup = alc268_toshiba_setup,
13892 .init_hook = alc268_toshiba_automute,
13894 [ALC268_ACER] = {
13895 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13896 alc268_beep_mixer },
13897 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13898 alc268_acer_verbs },
13899 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13900 .dac_nids = alc268_dac_nids,
13901 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13902 .adc_nids = alc268_adc_nids_alt,
13903 .capsrc_nids = alc268_capsrc_nids,
13904 .hp_nid = 0x02,
13905 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13906 .channel_mode = alc268_modes,
13907 .input_mux = &alc268_acer_capture_source,
13908 .unsol_event = alc268_acer_unsol_event,
13909 .init_hook = alc268_acer_init_hook,
13911 [ALC268_ACER_DMIC] = {
13912 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13913 alc268_beep_mixer },
13914 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13915 alc268_acer_verbs },
13916 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13917 .dac_nids = alc268_dac_nids,
13918 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13919 .adc_nids = alc268_adc_nids_alt,
13920 .capsrc_nids = alc268_capsrc_nids,
13921 .hp_nid = 0x02,
13922 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13923 .channel_mode = alc268_modes,
13924 .input_mux = &alc268_acer_dmic_capture_source,
13925 .unsol_event = alc268_acer_unsol_event,
13926 .init_hook = alc268_acer_init_hook,
13928 [ALC268_ACER_ASPIRE_ONE] = {
13929 .mixers = { alc268_acer_aspire_one_mixer,
13930 alc268_beep_mixer,
13931 alc268_capture_nosrc_mixer },
13932 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13933 alc268_acer_aspire_one_verbs },
13934 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13935 .dac_nids = alc268_dac_nids,
13936 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13937 .adc_nids = alc268_adc_nids_alt,
13938 .capsrc_nids = alc268_capsrc_nids,
13939 .hp_nid = 0x03,
13940 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13941 .channel_mode = alc268_modes,
13942 .unsol_event = alc268_acer_lc_unsol_event,
13943 .setup = alc268_acer_lc_setup,
13944 .init_hook = alc268_acer_lc_init_hook,
13946 [ALC268_DELL] = {
13947 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13948 alc268_capture_nosrc_mixer },
13949 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13950 alc268_dell_verbs },
13951 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13952 .dac_nids = alc268_dac_nids,
13953 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13954 .adc_nids = alc268_adc_nids_alt,
13955 .capsrc_nids = alc268_capsrc_nids,
13956 .hp_nid = 0x02,
13957 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13958 .channel_mode = alc268_modes,
13959 .unsol_event = alc_sku_unsol_event,
13960 .setup = alc268_dell_setup,
13961 .init_hook = alc_inithook,
13963 [ALC268_ZEPTO] = {
13964 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13965 alc268_beep_mixer },
13966 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13967 alc268_toshiba_verbs },
13968 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13969 .dac_nids = alc268_dac_nids,
13970 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13971 .adc_nids = alc268_adc_nids_alt,
13972 .capsrc_nids = alc268_capsrc_nids,
13973 .hp_nid = 0x03,
13974 .dig_out_nid = ALC268_DIGOUT_NID,
13975 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13976 .channel_mode = alc268_modes,
13977 .input_mux = &alc268_capture_source,
13978 .setup = alc268_toshiba_setup,
13979 .init_hook = alc268_toshiba_automute,
13981 #ifdef CONFIG_SND_DEBUG
13982 [ALC268_TEST] = {
13983 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13984 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13985 alc268_volume_init_verbs },
13986 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13987 .dac_nids = alc268_dac_nids,
13988 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13989 .adc_nids = alc268_adc_nids_alt,
13990 .capsrc_nids = alc268_capsrc_nids,
13991 .hp_nid = 0x03,
13992 .dig_out_nid = ALC268_DIGOUT_NID,
13993 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13994 .channel_mode = alc268_modes,
13995 .input_mux = &alc268_capture_source,
13997 #endif
14000 static int patch_alc268(struct hda_codec *codec)
14002 struct alc_spec *spec;
14003 int board_config;
14004 int i, has_beep, err;
14006 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14007 if (spec == NULL)
14008 return -ENOMEM;
14010 codec->spec = spec;
14012 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14013 alc268_models,
14014 alc268_cfg_tbl);
14016 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14017 board_config = snd_hda_check_board_codec_sid_config(codec,
14018 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14020 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14021 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14022 codec->chip_name);
14023 board_config = ALC268_AUTO;
14026 if (board_config == ALC268_AUTO) {
14027 /* automatic parse from the BIOS config */
14028 err = alc268_parse_auto_config(codec);
14029 if (err < 0) {
14030 alc_free(codec);
14031 return err;
14032 } else if (!err) {
14033 printk(KERN_INFO
14034 "hda_codec: Cannot set up configuration "
14035 "from BIOS. Using base mode...\n");
14036 board_config = ALC268_3ST;
14040 if (board_config != ALC268_AUTO)
14041 setup_preset(codec, &alc268_presets[board_config]);
14043 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14044 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14045 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14047 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14049 has_beep = 0;
14050 for (i = 0; i < spec->num_mixers; i++) {
14051 if (spec->mixers[i] == alc268_beep_mixer) {
14052 has_beep = 1;
14053 break;
14057 if (has_beep) {
14058 err = snd_hda_attach_beep_device(codec, 0x1);
14059 if (err < 0) {
14060 alc_free(codec);
14061 return err;
14063 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14064 /* override the amp caps for beep generator */
14065 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14066 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14067 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14068 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14069 (0 << AC_AMPCAP_MUTE_SHIFT));
14072 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14073 /* check whether NID 0x07 is valid */
14074 unsigned int wcap = get_wcaps(codec, 0x07);
14075 int i;
14077 spec->capsrc_nids = alc268_capsrc_nids;
14078 /* get type */
14079 wcap = get_wcaps_type(wcap);
14080 if (spec->auto_mic ||
14081 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14082 spec->adc_nids = alc268_adc_nids_alt;
14083 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14084 if (spec->auto_mic)
14085 fixup_automic_adc(codec);
14086 if (spec->auto_mic || spec->input_mux->num_items == 1)
14087 add_mixer(spec, alc268_capture_nosrc_mixer);
14088 else
14089 add_mixer(spec, alc268_capture_alt_mixer);
14090 } else {
14091 spec->adc_nids = alc268_adc_nids;
14092 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14093 add_mixer(spec, alc268_capture_mixer);
14095 /* set default input source */
14096 for (i = 0; i < spec->num_adc_nids; i++)
14097 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
14098 0, AC_VERB_SET_CONNECT_SEL,
14099 i < spec->num_mux_defs ?
14100 spec->input_mux[i].items[0].index :
14101 spec->input_mux->items[0].index);
14104 spec->vmaster_nid = 0x02;
14106 codec->patch_ops = alc_patch_ops;
14107 if (board_config == ALC268_AUTO)
14108 spec->init_hook = alc268_auto_init;
14110 alc_init_jacks(codec);
14112 return 0;
14116 * ALC269 channel source setting (2 channel)
14118 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14120 #define alc269_dac_nids alc260_dac_nids
14122 static hda_nid_t alc269_adc_nids[1] = {
14123 /* ADC1 */
14124 0x08,
14127 static hda_nid_t alc269_capsrc_nids[1] = {
14128 0x23,
14131 static hda_nid_t alc269vb_adc_nids[1] = {
14132 /* ADC1 */
14133 0x09,
14136 static hda_nid_t alc269vb_capsrc_nids[1] = {
14137 0x22,
14140 static hda_nid_t alc269_adc_candidates[] = {
14141 0x08, 0x09, 0x07,
14144 #define alc269_modes alc260_modes
14145 #define alc269_capture_source alc880_lg_lw_capture_source
14147 static struct snd_kcontrol_new alc269_base_mixer[] = {
14148 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14149 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14150 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14154 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14155 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14156 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14157 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14159 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14160 { } /* end */
14163 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14164 /* output mixer control */
14165 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14167 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14168 .name = "Master Playback Switch",
14169 .subdevice = HDA_SUBDEV_AMP_FLAG,
14170 .info = snd_hda_mixer_amp_switch_info,
14171 .get = snd_hda_mixer_amp_switch_get,
14172 .put = alc268_acer_master_sw_put,
14173 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14175 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14176 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14177 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14178 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14179 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14180 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14184 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14185 /* output mixer control */
14186 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14188 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14189 .name = "Master Playback Switch",
14190 .subdevice = HDA_SUBDEV_AMP_FLAG,
14191 .info = snd_hda_mixer_amp_switch_info,
14192 .get = snd_hda_mixer_amp_switch_get,
14193 .put = alc268_acer_master_sw_put,
14194 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14199 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14200 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14201 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14202 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14203 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14204 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14208 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
14209 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14213 { } /* end */
14216 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14217 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14218 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14219 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14220 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14221 { } /* end */
14224 static struct snd_kcontrol_new alc269_asus_mixer[] = {
14225 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14226 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14227 { } /* end */
14230 /* capture mixer elements */
14231 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14232 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14233 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14235 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14236 { } /* end */
14239 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14240 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14241 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14242 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14243 { } /* end */
14246 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14247 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14248 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14250 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14251 { } /* end */
14254 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14255 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14256 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14257 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14258 { } /* end */
14261 /* FSC amilo */
14262 #define alc269_fujitsu_mixer alc269_laptop_mixer
14264 static struct hda_verb alc269_quanta_fl1_verbs[] = {
14265 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14266 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14268 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14269 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14270 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14274 static struct hda_verb alc269_lifebook_verbs[] = {
14275 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14276 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14277 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14278 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14279 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14282 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14283 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14288 /* toggle speaker-output according to the hp-jack state */
14289 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14291 unsigned int present;
14292 unsigned char bits;
14294 present = snd_hda_jack_detect(codec, 0x15);
14295 bits = present ? HDA_AMP_MUTE : 0;
14296 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14297 HDA_AMP_MUTE, bits);
14298 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14299 HDA_AMP_MUTE, bits);
14301 snd_hda_codec_write(codec, 0x20, 0,
14302 AC_VERB_SET_COEF_INDEX, 0x0c);
14303 snd_hda_codec_write(codec, 0x20, 0,
14304 AC_VERB_SET_PROC_COEF, 0x680);
14306 snd_hda_codec_write(codec, 0x20, 0,
14307 AC_VERB_SET_COEF_INDEX, 0x0c);
14308 snd_hda_codec_write(codec, 0x20, 0,
14309 AC_VERB_SET_PROC_COEF, 0x480);
14312 /* toggle speaker-output according to the hp-jacks state */
14313 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
14315 unsigned int present;
14316 unsigned char bits;
14318 /* Check laptop headphone socket */
14319 present = snd_hda_jack_detect(codec, 0x15);
14321 /* Check port replicator headphone socket */
14322 present |= snd_hda_jack_detect(codec, 0x1a);
14324 bits = present ? HDA_AMP_MUTE : 0;
14325 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14326 HDA_AMP_MUTE, bits);
14327 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14328 HDA_AMP_MUTE, bits);
14330 snd_hda_codec_write(codec, 0x20, 0,
14331 AC_VERB_SET_COEF_INDEX, 0x0c);
14332 snd_hda_codec_write(codec, 0x20, 0,
14333 AC_VERB_SET_PROC_COEF, 0x680);
14335 snd_hda_codec_write(codec, 0x20, 0,
14336 AC_VERB_SET_COEF_INDEX, 0x0c);
14337 snd_hda_codec_write(codec, 0x20, 0,
14338 AC_VERB_SET_PROC_COEF, 0x480);
14341 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14343 unsigned int present_laptop;
14344 unsigned int present_dock;
14346 present_laptop = snd_hda_jack_detect(codec, 0x18);
14347 present_dock = snd_hda_jack_detect(codec, 0x1b);
14349 /* Laptop mic port overrides dock mic port, design decision */
14350 if (present_dock)
14351 snd_hda_codec_write(codec, 0x23, 0,
14352 AC_VERB_SET_CONNECT_SEL, 0x3);
14353 if (present_laptop)
14354 snd_hda_codec_write(codec, 0x23, 0,
14355 AC_VERB_SET_CONNECT_SEL, 0x0);
14356 if (!present_dock && !present_laptop)
14357 snd_hda_codec_write(codec, 0x23, 0,
14358 AC_VERB_SET_CONNECT_SEL, 0x1);
14361 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14362 unsigned int res)
14364 switch (res >> 26) {
14365 case ALC880_HP_EVENT:
14366 alc269_quanta_fl1_speaker_automute(codec);
14367 break;
14368 case ALC880_MIC_EVENT:
14369 alc_mic_automute(codec);
14370 break;
14374 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14375 unsigned int res)
14377 if ((res >> 26) == ALC880_HP_EVENT)
14378 alc269_lifebook_speaker_automute(codec);
14379 if ((res >> 26) == ALC880_MIC_EVENT)
14380 alc269_lifebook_mic_autoswitch(codec);
14383 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14385 struct alc_spec *spec = codec->spec;
14386 spec->autocfg.hp_pins[0] = 0x15;
14387 spec->autocfg.speaker_pins[0] = 0x14;
14388 spec->ext_mic.pin = 0x18;
14389 spec->ext_mic.mux_idx = 0;
14390 spec->int_mic.pin = 0x19;
14391 spec->int_mic.mux_idx = 1;
14392 spec->auto_mic = 1;
14395 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14397 alc269_quanta_fl1_speaker_automute(codec);
14398 alc_mic_automute(codec);
14401 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14403 alc269_lifebook_speaker_automute(codec);
14404 alc269_lifebook_mic_autoswitch(codec);
14407 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14409 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14410 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14411 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14412 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14413 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14414 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14418 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
14419 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14420 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14421 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14422 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14423 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14424 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14428 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14429 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14430 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14431 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14432 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14433 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14434 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14435 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14439 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14440 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14441 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14442 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14444 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14445 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14446 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14450 static struct hda_verb alc271_acer_dmic_verbs[] = {
14451 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14452 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14453 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14455 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14456 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14457 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14458 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14459 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14460 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14464 /* toggle speaker-output according to the hp-jack state */
14465 static void alc269_speaker_automute(struct hda_codec *codec)
14467 struct alc_spec *spec = codec->spec;
14468 unsigned int nid = spec->autocfg.hp_pins[0];
14469 unsigned int present;
14470 unsigned char bits;
14472 present = snd_hda_jack_detect(codec, nid);
14473 bits = present ? HDA_AMP_MUTE : 0;
14474 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
14475 HDA_AMP_MUTE, bits);
14476 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
14477 HDA_AMP_MUTE, bits);
14478 alc_report_jack(codec, nid);
14481 /* unsolicited event for HP jack sensing */
14482 static void alc269_laptop_unsol_event(struct hda_codec *codec,
14483 unsigned int res)
14485 switch (res >> 26) {
14486 case ALC880_HP_EVENT:
14487 alc269_speaker_automute(codec);
14488 break;
14489 case ALC880_MIC_EVENT:
14490 alc_mic_automute(codec);
14491 break;
14495 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14497 struct alc_spec *spec = codec->spec;
14498 spec->autocfg.hp_pins[0] = 0x15;
14499 spec->autocfg.speaker_pins[0] = 0x14;
14500 spec->ext_mic.pin = 0x18;
14501 spec->ext_mic.mux_idx = 0;
14502 spec->int_mic.pin = 0x19;
14503 spec->int_mic.mux_idx = 1;
14504 spec->auto_mic = 1;
14507 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14509 struct alc_spec *spec = codec->spec;
14510 spec->autocfg.hp_pins[0] = 0x15;
14511 spec->autocfg.speaker_pins[0] = 0x14;
14512 spec->ext_mic.pin = 0x18;
14513 spec->ext_mic.mux_idx = 0;
14514 spec->int_mic.pin = 0x12;
14515 spec->int_mic.mux_idx = 5;
14516 spec->auto_mic = 1;
14519 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14521 struct alc_spec *spec = codec->spec;
14522 spec->autocfg.hp_pins[0] = 0x21;
14523 spec->autocfg.speaker_pins[0] = 0x14;
14524 spec->ext_mic.pin = 0x18;
14525 spec->ext_mic.mux_idx = 0;
14526 spec->int_mic.pin = 0x19;
14527 spec->int_mic.mux_idx = 1;
14528 spec->auto_mic = 1;
14531 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14533 struct alc_spec *spec = codec->spec;
14534 spec->autocfg.hp_pins[0] = 0x21;
14535 spec->autocfg.speaker_pins[0] = 0x14;
14536 spec->ext_mic.pin = 0x18;
14537 spec->ext_mic.mux_idx = 0;
14538 spec->int_mic.pin = 0x12;
14539 spec->int_mic.mux_idx = 6;
14540 spec->auto_mic = 1;
14543 static void alc269_laptop_inithook(struct hda_codec *codec)
14545 alc269_speaker_automute(codec);
14546 alc_mic_automute(codec);
14550 * generic initialization of ADC, input mixers and output mixers
14552 static struct hda_verb alc269_init_verbs[] = {
14554 * Unmute ADC0 and set the default input to mic-in
14556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14559 * Set up output mixers (0x02 - 0x03)
14561 /* set vol=0 to output mixers */
14562 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14563 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14565 /* set up input amps for analog loopback */
14566 /* Amp Indices: DAC = 0, mixer = 1 */
14567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14569 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14570 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14576 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14577 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14578 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14579 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14580 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14585 /* FIXME: use Mux-type input source selection */
14586 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14587 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14588 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14590 /* set EAPD */
14591 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14595 static struct hda_verb alc269vb_init_verbs[] = {
14597 * Unmute ADC0 and set the default input to mic-in
14599 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14602 * Set up output mixers (0x02 - 0x03)
14604 /* set vol=0 to output mixers */
14605 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14608 /* set up input amps for analog loopback */
14609 /* Amp Indices: DAC = 0, mixer = 1 */
14610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14612 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14613 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14614 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14615 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14618 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14619 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14620 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14622 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14623 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14625 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14626 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14628 /* FIXME: use Mux-type input source selection */
14629 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14630 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14631 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14633 /* set EAPD */
14634 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14638 #define alc269_auto_create_multi_out_ctls \
14639 alc268_auto_create_multi_out_ctls
14640 #define alc269_auto_create_input_ctls \
14641 alc268_auto_create_input_ctls
14643 #ifdef CONFIG_SND_HDA_POWER_SAVE
14644 #define alc269_loopbacks alc880_loopbacks
14645 #endif
14647 /* pcm configuration: identical with ALC880 */
14648 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14649 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14650 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14651 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14653 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14654 .substreams = 1,
14655 .channels_min = 2,
14656 .channels_max = 8,
14657 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14658 /* NID is set in alc_build_pcms */
14659 .ops = {
14660 .open = alc880_playback_pcm_open,
14661 .prepare = alc880_playback_pcm_prepare,
14662 .cleanup = alc880_playback_pcm_cleanup
14666 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14667 .substreams = 1,
14668 .channels_min = 2,
14669 .channels_max = 2,
14670 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14671 /* NID is set in alc_build_pcms */
14674 #ifdef CONFIG_SND_HDA_POWER_SAVE
14675 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14677 switch (codec->subsystem_id) {
14678 case 0x103c1586:
14679 return 1;
14681 return 0;
14684 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14686 /* update mute-LED according to the speaker mute state */
14687 if (nid == 0x01 || nid == 0x14) {
14688 int pinval;
14689 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14690 HDA_AMP_MUTE)
14691 pinval = 0x24;
14692 else
14693 pinval = 0x20;
14694 /* mic2 vref pin is used for mute LED control */
14695 snd_hda_codec_update_cache(codec, 0x19, 0,
14696 AC_VERB_SET_PIN_WIDGET_CONTROL,
14697 pinval);
14699 return alc_check_power_status(codec, nid);
14701 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14703 static int alc275_setup_dual_adc(struct hda_codec *codec)
14705 struct alc_spec *spec = codec->spec;
14707 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14708 return 0;
14709 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14710 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14711 if (spec->ext_mic.pin <= 0x12) {
14712 spec->private_adc_nids[0] = 0x08;
14713 spec->private_adc_nids[1] = 0x11;
14714 spec->private_capsrc_nids[0] = 0x23;
14715 spec->private_capsrc_nids[1] = 0x22;
14716 } else {
14717 spec->private_adc_nids[0] = 0x11;
14718 spec->private_adc_nids[1] = 0x08;
14719 spec->private_capsrc_nids[0] = 0x22;
14720 spec->private_capsrc_nids[1] = 0x23;
14722 spec->adc_nids = spec->private_adc_nids;
14723 spec->capsrc_nids = spec->private_capsrc_nids;
14724 spec->num_adc_nids = 2;
14725 spec->dual_adc_switch = 1;
14726 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14727 spec->adc_nids[0], spec->adc_nids[1]);
14728 return 1;
14730 return 0;
14733 /* different alc269-variants */
14734 enum {
14735 ALC269_TYPE_NORMAL,
14736 ALC269_TYPE_ALC258,
14737 ALC269_TYPE_ALC259,
14738 ALC269_TYPE_ALC269VB,
14739 ALC269_TYPE_ALC270,
14740 ALC269_TYPE_ALC271X,
14744 * BIOS auto configuration
14746 static int alc269_parse_auto_config(struct hda_codec *codec)
14748 struct alc_spec *spec = codec->spec;
14749 int err;
14750 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14752 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14753 alc269_ignore);
14754 if (err < 0)
14755 return err;
14757 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14758 if (err < 0)
14759 return err;
14760 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14761 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14762 else
14763 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14764 0x22, 0);
14765 if (err < 0)
14766 return err;
14768 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14770 alc_auto_parse_digital(codec);
14772 if (spec->kctls.list)
14773 add_mixer(spec, spec->kctls.list);
14775 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14776 add_verb(spec, alc269vb_init_verbs);
14777 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14778 } else {
14779 add_verb(spec, alc269_init_verbs);
14780 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14783 spec->num_mux_defs = 1;
14784 spec->input_mux = &spec->private_imux[0];
14786 if (!alc275_setup_dual_adc(codec))
14787 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14788 sizeof(alc269_adc_candidates));
14790 /* set default input source */
14791 if (!spec->dual_adc_switch)
14792 select_or_unmute_capsrc(codec, spec->capsrc_nids[0],
14793 spec->input_mux->items[0].index);
14795 err = alc_auto_add_mic_boost(codec);
14796 if (err < 0)
14797 return err;
14799 if (!spec->cap_mixer && !spec->no_analog)
14800 set_capture_mixer(codec);
14802 return 1;
14805 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14806 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14807 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14810 /* init callback for auto-configuration model -- overriding the default init */
14811 static void alc269_auto_init(struct hda_codec *codec)
14813 struct alc_spec *spec = codec->spec;
14814 alc269_auto_init_multi_out(codec);
14815 alc269_auto_init_hp_out(codec);
14816 alc269_auto_init_analog_input(codec);
14817 alc_auto_init_digital(codec);
14818 if (spec->unsol_event)
14819 alc_inithook(codec);
14822 #ifdef SND_HDA_NEEDS_RESUME
14823 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14825 int val = alc_read_coef_idx(codec, 0x04);
14826 if (power_up)
14827 val |= 1 << 11;
14828 else
14829 val &= ~(1 << 11);
14830 alc_write_coef_idx(codec, 0x04, val);
14833 #ifdef CONFIG_SND_HDA_POWER_SAVE
14834 static int alc269_suspend(struct hda_codec *codec, pm_message_t state)
14836 struct alc_spec *spec = codec->spec;
14838 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14839 alc269_toggle_power_output(codec, 0);
14840 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14841 alc269_toggle_power_output(codec, 0);
14842 msleep(150);
14845 alc_shutup(codec);
14846 if (spec && spec->power_hook)
14847 spec->power_hook(codec);
14848 return 0;
14850 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14852 static int alc269_resume(struct hda_codec *codec)
14854 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14855 alc269_toggle_power_output(codec, 0);
14856 msleep(150);
14859 codec->patch_ops.init(codec);
14861 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14862 alc269_toggle_power_output(codec, 1);
14863 msleep(200);
14866 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14867 alc269_toggle_power_output(codec, 1);
14869 snd_hda_codec_resume_amp(codec);
14870 snd_hda_codec_resume_cache(codec);
14871 hda_call_check_power_status(codec, 0x01);
14872 return 0;
14874 #endif /* SND_HDA_NEEDS_RESUME */
14876 static void alc269_fixup_hweq(struct hda_codec *codec,
14877 const struct alc_fixup *fix, int action)
14879 int coef;
14881 if (action != ALC_FIXUP_ACT_INIT)
14882 return;
14883 coef = alc_read_coef_idx(codec, 0x1e);
14884 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14887 enum {
14888 ALC269_FIXUP_SONY_VAIO,
14889 ALC275_FIXUP_SONY_VAIO_GPIO2,
14890 ALC269_FIXUP_DELL_M101Z,
14891 ALC269_FIXUP_SKU_IGNORE,
14892 ALC269_FIXUP_ASUS_G73JW,
14893 ALC269_FIXUP_LENOVO_EAPD,
14894 ALC275_FIXUP_SONY_HWEQ,
14897 static const struct alc_fixup alc269_fixups[] = {
14898 [ALC269_FIXUP_SONY_VAIO] = {
14899 .type = ALC_FIXUP_VERBS,
14900 .v.verbs = (const struct hda_verb[]) {
14901 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14905 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14906 .type = ALC_FIXUP_VERBS,
14907 .v.verbs = (const struct hda_verb[]) {
14908 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14909 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14910 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14913 .chained = true,
14914 .chain_id = ALC269_FIXUP_SONY_VAIO
14916 [ALC269_FIXUP_DELL_M101Z] = {
14917 .type = ALC_FIXUP_VERBS,
14918 .v.verbs = (const struct hda_verb[]) {
14919 /* Enables internal speaker */
14920 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14921 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14925 [ALC269_FIXUP_SKU_IGNORE] = {
14926 .type = ALC_FIXUP_SKU,
14927 .v.sku = ALC_FIXUP_SKU_IGNORE,
14929 [ALC269_FIXUP_ASUS_G73JW] = {
14930 .type = ALC_FIXUP_PINS,
14931 .v.pins = (const struct alc_pincfg[]) {
14932 { 0x17, 0x99130111 }, /* subwoofer */
14936 [ALC269_FIXUP_LENOVO_EAPD] = {
14937 .type = ALC_FIXUP_VERBS,
14938 .v.verbs = (const struct hda_verb[]) {
14939 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14943 [ALC275_FIXUP_SONY_HWEQ] = {
14944 .type = ALC_FIXUP_FUNC,
14945 .v.func = alc269_fixup_hweq,
14946 .chained = true,
14947 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14951 static struct snd_pci_quirk alc269_fixup_tbl[] = {
14952 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14953 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14954 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14955 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14956 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14957 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14958 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14959 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14960 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14961 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14967 * configuration and preset
14969 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14970 [ALC269_BASIC] = "basic",
14971 [ALC269_QUANTA_FL1] = "quanta",
14972 [ALC269_AMIC] = "laptop-amic",
14973 [ALC269_DMIC] = "laptop-dmic",
14974 [ALC269_FUJITSU] = "fujitsu",
14975 [ALC269_LIFEBOOK] = "lifebook",
14976 [ALC269_AUTO] = "auto",
14979 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14980 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14981 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14982 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14983 ALC269_AMIC),
14984 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14985 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14986 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14987 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14988 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14989 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14990 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14991 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15016 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15021 ALC269_DMIC),
15022 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15023 ALC269_DMIC),
15024 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15025 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15026 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15027 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15028 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15029 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15030 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15031 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15032 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15033 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15037 static struct alc_config_preset alc269_presets[] = {
15038 [ALC269_BASIC] = {
15039 .mixers = { alc269_base_mixer },
15040 .init_verbs = { alc269_init_verbs },
15041 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15042 .dac_nids = alc269_dac_nids,
15043 .hp_nid = 0x03,
15044 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15045 .channel_mode = alc269_modes,
15046 .input_mux = &alc269_capture_source,
15048 [ALC269_QUANTA_FL1] = {
15049 .mixers = { alc269_quanta_fl1_mixer },
15050 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15051 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15052 .dac_nids = alc269_dac_nids,
15053 .hp_nid = 0x03,
15054 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15055 .channel_mode = alc269_modes,
15056 .input_mux = &alc269_capture_source,
15057 .unsol_event = alc269_quanta_fl1_unsol_event,
15058 .setup = alc269_quanta_fl1_setup,
15059 .init_hook = alc269_quanta_fl1_init_hook,
15061 [ALC269_AMIC] = {
15062 .mixers = { alc269_laptop_mixer },
15063 .cap_mixer = alc269_laptop_analog_capture_mixer,
15064 .init_verbs = { alc269_init_verbs,
15065 alc269_laptop_amic_init_verbs },
15066 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15067 .dac_nids = alc269_dac_nids,
15068 .hp_nid = 0x03,
15069 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15070 .channel_mode = alc269_modes,
15071 .unsol_event = alc269_laptop_unsol_event,
15072 .setup = alc269_laptop_amic_setup,
15073 .init_hook = alc269_laptop_inithook,
15075 [ALC269_DMIC] = {
15076 .mixers = { alc269_laptop_mixer },
15077 .cap_mixer = alc269_laptop_digital_capture_mixer,
15078 .init_verbs = { alc269_init_verbs,
15079 alc269_laptop_dmic_init_verbs },
15080 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15081 .dac_nids = alc269_dac_nids,
15082 .hp_nid = 0x03,
15083 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15084 .channel_mode = alc269_modes,
15085 .unsol_event = alc269_laptop_unsol_event,
15086 .setup = alc269_laptop_dmic_setup,
15087 .init_hook = alc269_laptop_inithook,
15089 [ALC269VB_AMIC] = {
15090 .mixers = { alc269vb_laptop_mixer },
15091 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15092 .init_verbs = { alc269vb_init_verbs,
15093 alc269vb_laptop_amic_init_verbs },
15094 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15095 .dac_nids = alc269_dac_nids,
15096 .hp_nid = 0x03,
15097 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15098 .channel_mode = alc269_modes,
15099 .unsol_event = alc269_laptop_unsol_event,
15100 .setup = alc269vb_laptop_amic_setup,
15101 .init_hook = alc269_laptop_inithook,
15103 [ALC269VB_DMIC] = {
15104 .mixers = { alc269vb_laptop_mixer },
15105 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15106 .init_verbs = { alc269vb_init_verbs,
15107 alc269vb_laptop_dmic_init_verbs },
15108 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15109 .dac_nids = alc269_dac_nids,
15110 .hp_nid = 0x03,
15111 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15112 .channel_mode = alc269_modes,
15113 .unsol_event = alc269_laptop_unsol_event,
15114 .setup = alc269vb_laptop_dmic_setup,
15115 .init_hook = alc269_laptop_inithook,
15117 [ALC269_FUJITSU] = {
15118 .mixers = { alc269_fujitsu_mixer },
15119 .cap_mixer = alc269_laptop_digital_capture_mixer,
15120 .init_verbs = { alc269_init_verbs,
15121 alc269_laptop_dmic_init_verbs },
15122 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15123 .dac_nids = alc269_dac_nids,
15124 .hp_nid = 0x03,
15125 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15126 .channel_mode = alc269_modes,
15127 .unsol_event = alc269_laptop_unsol_event,
15128 .setup = alc269_laptop_dmic_setup,
15129 .init_hook = alc269_laptop_inithook,
15131 [ALC269_LIFEBOOK] = {
15132 .mixers = { alc269_lifebook_mixer },
15133 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15134 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15135 .dac_nids = alc269_dac_nids,
15136 .hp_nid = 0x03,
15137 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15138 .channel_mode = alc269_modes,
15139 .input_mux = &alc269_capture_source,
15140 .unsol_event = alc269_lifebook_unsol_event,
15141 .init_hook = alc269_lifebook_init_hook,
15143 [ALC271_ACER] = {
15144 .mixers = { alc269_asus_mixer },
15145 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15146 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15147 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15148 .dac_nids = alc269_dac_nids,
15149 .adc_nids = alc262_dmic_adc_nids,
15150 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15151 .capsrc_nids = alc262_dmic_capsrc_nids,
15152 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15153 .channel_mode = alc269_modes,
15154 .input_mux = &alc269_capture_source,
15155 .dig_out_nid = ALC880_DIGOUT_NID,
15156 .unsol_event = alc_sku_unsol_event,
15157 .setup = alc269vb_laptop_dmic_setup,
15158 .init_hook = alc_inithook,
15162 static int alc269_fill_coef(struct hda_codec *codec)
15164 int val;
15166 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15167 alc_write_coef_idx(codec, 0xf, 0x960b);
15168 alc_write_coef_idx(codec, 0xe, 0x8817);
15171 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15172 alc_write_coef_idx(codec, 0xf, 0x960b);
15173 alc_write_coef_idx(codec, 0xe, 0x8814);
15176 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15177 val = alc_read_coef_idx(codec, 0x04);
15178 /* Power up output pin */
15179 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15182 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15183 val = alc_read_coef_idx(codec, 0xd);
15184 if ((val & 0x0c00) >> 10 != 0x1) {
15185 /* Capless ramp up clock control */
15186 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15188 val = alc_read_coef_idx(codec, 0x17);
15189 if ((val & 0x01c0) >> 6 != 0x4) {
15190 /* Class D power on reset */
15191 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15194 return 0;
15197 static int patch_alc269(struct hda_codec *codec)
15199 struct alc_spec *spec;
15200 int board_config, coef;
15201 int err;
15203 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15204 if (spec == NULL)
15205 return -ENOMEM;
15207 codec->spec = spec;
15209 alc_auto_parse_customize_define(codec);
15211 if (codec->vendor_id == 0x10ec0269) {
15212 coef = alc_read_coef_idx(codec, 0);
15213 if ((coef & 0x00f0) == 0x0010) {
15214 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15215 spec->cdefine.platform_type == 1) {
15216 alc_codec_rename(codec, "ALC271X");
15217 spec->codec_variant = ALC269_TYPE_ALC271X;
15218 } else if ((coef & 0xf000) == 0x1000) {
15219 spec->codec_variant = ALC269_TYPE_ALC270;
15220 } else if ((coef & 0xf000) == 0x2000) {
15221 alc_codec_rename(codec, "ALC259");
15222 spec->codec_variant = ALC269_TYPE_ALC259;
15223 } else if ((coef & 0xf000) == 0x3000) {
15224 alc_codec_rename(codec, "ALC258");
15225 spec->codec_variant = ALC269_TYPE_ALC258;
15226 } else {
15227 alc_codec_rename(codec, "ALC269VB");
15228 spec->codec_variant = ALC269_TYPE_ALC269VB;
15230 } else
15231 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15232 alc269_fill_coef(codec);
15235 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15236 alc269_models,
15237 alc269_cfg_tbl);
15239 if (board_config < 0) {
15240 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15241 codec->chip_name);
15242 board_config = ALC269_AUTO;
15245 if (board_config == ALC269_AUTO) {
15246 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15247 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15250 if (board_config == ALC269_AUTO) {
15251 /* automatic parse from the BIOS config */
15252 err = alc269_parse_auto_config(codec);
15253 if (err < 0) {
15254 alc_free(codec);
15255 return err;
15256 } else if (!err) {
15257 printk(KERN_INFO
15258 "hda_codec: Cannot set up configuration "
15259 "from BIOS. Using base mode...\n");
15260 board_config = ALC269_BASIC;
15264 if (has_cdefine_beep(codec)) {
15265 err = snd_hda_attach_beep_device(codec, 0x1);
15266 if (err < 0) {
15267 alc_free(codec);
15268 return err;
15272 if (board_config != ALC269_AUTO)
15273 setup_preset(codec, &alc269_presets[board_config]);
15275 if (board_config == ALC269_QUANTA_FL1) {
15276 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15277 * fix the sample rate of analog I/O to 44.1kHz
15279 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15280 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15281 } else if (spec->dual_adc_switch) {
15282 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15283 /* switch ADC dynamically */
15284 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15285 } else {
15286 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15287 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15289 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15290 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15292 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15293 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15294 spec->adc_nids = alc269_adc_nids;
15295 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15296 spec->capsrc_nids = alc269_capsrc_nids;
15297 } else {
15298 spec->adc_nids = alc269vb_adc_nids;
15299 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15300 spec->capsrc_nids = alc269vb_capsrc_nids;
15304 if (!spec->cap_mixer)
15305 set_capture_mixer(codec);
15306 if (has_cdefine_beep(codec))
15307 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15309 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15311 spec->vmaster_nid = 0x02;
15313 codec->patch_ops = alc_patch_ops;
15314 #ifdef CONFIG_SND_HDA_POWER_SAVE
15315 codec->patch_ops.suspend = alc269_suspend;
15316 #endif
15317 #ifdef SND_HDA_NEEDS_RESUME
15318 codec->patch_ops.resume = alc269_resume;
15319 #endif
15320 if (board_config == ALC269_AUTO)
15321 spec->init_hook = alc269_auto_init;
15323 alc_init_jacks(codec);
15324 #ifdef CONFIG_SND_HDA_POWER_SAVE
15325 if (!spec->loopback.amplist)
15326 spec->loopback.amplist = alc269_loopbacks;
15327 if (alc269_mic2_for_mute_led(codec))
15328 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15329 #endif
15331 return 0;
15335 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15339 * set the path ways for 2 channel output
15340 * need to set the codec line out and mic 1 pin widgets to inputs
15342 static struct hda_verb alc861_threestack_ch2_init[] = {
15343 /* set pin widget 1Ah (line in) for input */
15344 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15345 /* set pin widget 18h (mic1/2) for input, for mic also enable
15346 * the vref
15348 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15350 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15351 #if 0
15352 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15353 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15354 #endif
15355 { } /* end */
15358 * 6ch mode
15359 * need to set the codec line out and mic 1 pin widgets to outputs
15361 static struct hda_verb alc861_threestack_ch6_init[] = {
15362 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15363 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15364 /* set pin widget 18h (mic1) for output (CLFE)*/
15365 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15367 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15368 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15370 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15371 #if 0
15372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15373 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15374 #endif
15375 { } /* end */
15378 static struct hda_channel_mode alc861_threestack_modes[2] = {
15379 { 2, alc861_threestack_ch2_init },
15380 { 6, alc861_threestack_ch6_init },
15382 /* Set mic1 as input and unmute the mixer */
15383 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15384 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15385 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15386 { } /* end */
15388 /* Set mic1 as output and mute mixer */
15389 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15390 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15391 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15392 { } /* end */
15395 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15396 { 2, alc861_uniwill_m31_ch2_init },
15397 { 4, alc861_uniwill_m31_ch4_init },
15400 /* Set mic1 and line-in as input and unmute the mixer */
15401 static struct hda_verb alc861_asus_ch2_init[] = {
15402 /* set pin widget 1Ah (line in) for input */
15403 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15404 /* set pin widget 18h (mic1/2) for input, for mic also enable
15405 * the vref
15407 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15409 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15410 #if 0
15411 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15412 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15413 #endif
15414 { } /* end */
15416 /* Set mic1 nad line-in as output and mute mixer */
15417 static struct hda_verb alc861_asus_ch6_init[] = {
15418 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15419 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15420 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15421 /* set pin widget 18h (mic1) for output (CLFE)*/
15422 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15423 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15424 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15425 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15428 #if 0
15429 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15430 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15431 #endif
15432 { } /* end */
15435 static struct hda_channel_mode alc861_asus_modes[2] = {
15436 { 2, alc861_asus_ch2_init },
15437 { 6, alc861_asus_ch6_init },
15440 /* patch-ALC861 */
15442 static struct snd_kcontrol_new alc861_base_mixer[] = {
15443 /* output mixer control */
15444 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15445 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15447 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15448 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15450 /*Input mixer control */
15451 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15452 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15453 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15454 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15455 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15456 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15458 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15462 { } /* end */
15465 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
15466 /* output mixer control */
15467 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15468 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15469 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15471 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15473 /* Input mixer control */
15474 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15475 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15476 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15477 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15478 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15479 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15481 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15487 .name = "Channel Mode",
15488 .info = alc_ch_mode_info,
15489 .get = alc_ch_mode_get,
15490 .put = alc_ch_mode_put,
15491 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15493 { } /* end */
15496 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15497 /* output mixer control */
15498 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15499 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15500 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15502 { } /* end */
15505 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15506 /* output mixer control */
15507 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15508 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15509 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15510 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15511 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15513 /* Input mixer control */
15514 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15515 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15516 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15517 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15518 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15519 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15521 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15522 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15527 .name = "Channel Mode",
15528 .info = alc_ch_mode_info,
15529 .get = alc_ch_mode_get,
15530 .put = alc_ch_mode_put,
15531 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15533 { } /* end */
15536 static struct snd_kcontrol_new alc861_asus_mixer[] = {
15537 /* output mixer control */
15538 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15539 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15540 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15541 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15542 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15544 /* Input mixer control */
15545 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15546 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15547 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15548 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15549 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15550 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15551 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15552 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15553 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15558 .name = "Channel Mode",
15559 .info = alc_ch_mode_info,
15560 .get = alc_ch_mode_get,
15561 .put = alc_ch_mode_put,
15562 .private_value = ARRAY_SIZE(alc861_asus_modes),
15567 /* additional mixer */
15568 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15569 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15570 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15575 * generic initialization of ADC, input mixers and output mixers
15577 static struct hda_verb alc861_base_init_verbs[] = {
15579 * Unmute ADC0 and set the default input to mic-in
15581 /* port-A for surround (rear panel) */
15582 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15583 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15584 /* port-B for mic-in (rear panel) with vref */
15585 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15586 /* port-C for line-in (rear panel) */
15587 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15588 /* port-D for Front */
15589 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15590 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15591 /* port-E for HP out (front panel) */
15592 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15593 /* route front PCM to HP */
15594 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15595 /* port-F for mic-in (front panel) with vref */
15596 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15597 /* port-G for CLFE (rear panel) */
15598 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15599 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15600 /* port-H for side (rear panel) */
15601 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15602 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15603 /* CD-in */
15604 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15605 /* route front mic to ADC1*/
15606 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15609 /* Unmute DAC0~3 & spdif out*/
15610 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15611 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15613 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15616 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15617 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15618 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15619 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15620 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15622 /* Unmute Stereo Mixer 15 */
15623 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15625 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15628 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15629 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15630 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15636 /* hp used DAC 3 (Front) */
15637 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15643 static struct hda_verb alc861_threestack_init_verbs[] = {
15645 * Unmute ADC0 and set the default input to mic-in
15647 /* port-A for surround (rear panel) */
15648 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15649 /* port-B for mic-in (rear panel) with vref */
15650 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15651 /* port-C for line-in (rear panel) */
15652 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15653 /* port-D for Front */
15654 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15655 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15656 /* port-E for HP out (front panel) */
15657 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15658 /* route front PCM to HP */
15659 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15660 /* port-F for mic-in (front panel) with vref */
15661 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15662 /* port-G for CLFE (rear panel) */
15663 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15664 /* port-H for side (rear panel) */
15665 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15666 /* CD-in */
15667 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15668 /* route front mic to ADC1*/
15669 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671 /* Unmute DAC0~3 & spdif out*/
15672 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15673 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15674 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15675 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15676 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15678 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15679 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15680 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15681 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15682 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15684 /* Unmute Stereo Mixer 15 */
15685 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15690 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15691 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15692 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15693 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15694 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15696 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15697 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15698 /* hp used DAC 3 (Front) */
15699 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15700 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15704 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15706 * Unmute ADC0 and set the default input to mic-in
15708 /* port-A for surround (rear panel) */
15709 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15710 /* port-B for mic-in (rear panel) with vref */
15711 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15712 /* port-C for line-in (rear panel) */
15713 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15714 /* port-D for Front */
15715 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15716 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15717 /* port-E for HP out (front panel) */
15718 /* this has to be set to VREF80 */
15719 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15720 /* route front PCM to HP */
15721 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15722 /* port-F for mic-in (front panel) with vref */
15723 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15724 /* port-G for CLFE (rear panel) */
15725 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15726 /* port-H for side (rear panel) */
15727 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15728 /* CD-in */
15729 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15730 /* route front mic to ADC1*/
15731 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15732 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15733 /* Unmute DAC0~3 & spdif out*/
15734 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15735 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15736 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15737 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15740 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15741 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15742 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15743 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15744 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15746 /* Unmute Stereo Mixer 15 */
15747 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15749 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15753 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15754 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15755 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15756 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15758 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 /* hp used DAC 3 (Front) */
15761 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15762 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15766 static struct hda_verb alc861_asus_init_verbs[] = {
15768 * Unmute ADC0 and set the default input to mic-in
15770 /* port-A for surround (rear panel)
15771 * according to codec#0 this is the HP jack
15773 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15774 /* route front PCM to HP */
15775 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15776 /* port-B for mic-in (rear panel) with vref */
15777 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15778 /* port-C for line-in (rear panel) */
15779 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15780 /* port-D for Front */
15781 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15782 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15783 /* port-E for HP out (front panel) */
15784 /* this has to be set to VREF80 */
15785 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15786 /* route front PCM to HP */
15787 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15788 /* port-F for mic-in (front panel) with vref */
15789 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15790 /* port-G for CLFE (rear panel) */
15791 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15792 /* port-H for side (rear panel) */
15793 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15794 /* CD-in */
15795 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15796 /* route front mic to ADC1*/
15797 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15798 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15799 /* Unmute DAC0~3 & spdif out*/
15800 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15801 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15802 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15803 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15805 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15806 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15807 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15808 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15809 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15811 /* Unmute Stereo Mixer 15 */
15812 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15814 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15818 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15819 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15820 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15821 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15823 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15825 /* hp used DAC 3 (Front) */
15826 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15827 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15831 /* additional init verbs for ASUS laptops */
15832 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
15833 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15834 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15839 * generic initialization of ADC, input mixers and output mixers
15841 static struct hda_verb alc861_auto_init_verbs[] = {
15843 * Unmute ADC0 and set the default input to mic-in
15845 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15848 /* Unmute DAC0~3 & spdif out*/
15849 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15850 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15851 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15852 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15853 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15855 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15856 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15857 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15858 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15859 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15861 /* Unmute Stereo Mixer 15 */
15862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15863 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15864 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15865 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15867 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15868 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15869 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15870 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15871 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15874 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15877 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15878 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15880 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15882 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15883 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15885 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15890 static struct hda_verb alc861_toshiba_init_verbs[] = {
15891 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15896 /* toggle speaker-output according to the hp-jack state */
15897 static void alc861_toshiba_automute(struct hda_codec *codec)
15899 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15901 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15902 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15903 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15904 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15907 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15908 unsigned int res)
15910 if ((res >> 26) == ALC880_HP_EVENT)
15911 alc861_toshiba_automute(codec);
15914 /* pcm configuration: identical with ALC880 */
15915 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15916 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15917 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15918 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15921 #define ALC861_DIGOUT_NID 0x07
15923 static struct hda_channel_mode alc861_8ch_modes[1] = {
15924 { 8, NULL }
15927 static hda_nid_t alc861_dac_nids[4] = {
15928 /* front, surround, clfe, side */
15929 0x03, 0x06, 0x05, 0x04
15932 static hda_nid_t alc660_dac_nids[3] = {
15933 /* front, clfe, surround */
15934 0x03, 0x05, 0x06
15937 static hda_nid_t alc861_adc_nids[1] = {
15938 /* ADC0-2 */
15939 0x08,
15942 static struct hda_input_mux alc861_capture_source = {
15943 .num_items = 5,
15944 .items = {
15945 { "Mic", 0x0 },
15946 { "Front Mic", 0x3 },
15947 { "Line", 0x1 },
15948 { "CD", 0x4 },
15949 { "Mixer", 0x5 },
15953 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15955 struct alc_spec *spec = codec->spec;
15956 hda_nid_t mix, srcs[5];
15957 int i, j, num;
15959 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15960 return 0;
15961 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15962 if (num < 0)
15963 return 0;
15964 for (i = 0; i < num; i++) {
15965 unsigned int type;
15966 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15967 if (type != AC_WID_AUD_OUT)
15968 continue;
15969 for (j = 0; j < spec->multiout.num_dacs; j++)
15970 if (spec->multiout.dac_nids[j] == srcs[i])
15971 break;
15972 if (j >= spec->multiout.num_dacs)
15973 return srcs[i];
15975 return 0;
15978 /* fill in the dac_nids table from the parsed pin configuration */
15979 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15980 const struct auto_pin_cfg *cfg)
15982 struct alc_spec *spec = codec->spec;
15983 int i;
15984 hda_nid_t nid, dac;
15986 spec->multiout.dac_nids = spec->private_dac_nids;
15987 for (i = 0; i < cfg->line_outs; i++) {
15988 nid = cfg->line_out_pins[i];
15989 dac = alc861_look_for_dac(codec, nid);
15990 if (!dac)
15991 continue;
15992 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15994 return 0;
15997 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15998 hda_nid_t nid, int idx, unsigned int chs)
16000 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16001 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16004 #define alc861_create_out_sw(codec, pfx, nid, chs) \
16005 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16007 /* add playback controls from the parsed DAC table */
16008 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16009 const struct auto_pin_cfg *cfg)
16011 struct alc_spec *spec = codec->spec;
16012 static const char * const chname[4] = {
16013 "Front", "Surround", NULL /*CLFE*/, "Side"
16015 const char *pfx = alc_get_line_out_pfx(cfg, true);
16016 hda_nid_t nid;
16017 int i, err;
16019 for (i = 0; i < cfg->line_outs; i++) {
16020 nid = spec->multiout.dac_nids[i];
16021 if (!nid)
16022 continue;
16023 if (!pfx && i == 2) {
16024 /* Center/LFE */
16025 err = alc861_create_out_sw(codec, "Center", nid, 1);
16026 if (err < 0)
16027 return err;
16028 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16029 if (err < 0)
16030 return err;
16031 } else {
16032 const char *name = pfx;
16033 if (!name)
16034 name = chname[i];
16035 err = __alc861_create_out_sw(codec, name, nid, i, 3);
16036 if (err < 0)
16037 return err;
16040 return 0;
16043 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16045 struct alc_spec *spec = codec->spec;
16046 int err;
16047 hda_nid_t nid;
16049 if (!pin)
16050 return 0;
16052 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16053 nid = alc861_look_for_dac(codec, pin);
16054 if (nid) {
16055 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16056 if (err < 0)
16057 return err;
16058 spec->multiout.hp_nid = nid;
16061 return 0;
16064 /* create playback/capture controls for input pins */
16065 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16066 const struct auto_pin_cfg *cfg)
16068 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16071 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16072 hda_nid_t nid,
16073 int pin_type, hda_nid_t dac)
16075 hda_nid_t mix, srcs[5];
16076 int i, num;
16078 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16079 pin_type);
16080 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16081 AMP_OUT_UNMUTE);
16082 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16083 return;
16084 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16085 if (num < 0)
16086 return;
16087 for (i = 0; i < num; i++) {
16088 unsigned int mute;
16089 if (srcs[i] == dac || srcs[i] == 0x15)
16090 mute = AMP_IN_UNMUTE(i);
16091 else
16092 mute = AMP_IN_MUTE(i);
16093 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16094 mute);
16098 static void alc861_auto_init_multi_out(struct hda_codec *codec)
16100 struct alc_spec *spec = codec->spec;
16101 int i;
16103 for (i = 0; i < spec->autocfg.line_outs; i++) {
16104 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16105 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16106 if (nid)
16107 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16108 spec->multiout.dac_nids[i]);
16112 static void alc861_auto_init_hp_out(struct hda_codec *codec)
16114 struct alc_spec *spec = codec->spec;
16116 if (spec->autocfg.hp_outs)
16117 alc861_auto_set_output_and_unmute(codec,
16118 spec->autocfg.hp_pins[0],
16119 PIN_HP,
16120 spec->multiout.hp_nid);
16121 if (spec->autocfg.speaker_outs)
16122 alc861_auto_set_output_and_unmute(codec,
16123 spec->autocfg.speaker_pins[0],
16124 PIN_OUT,
16125 spec->multiout.dac_nids[0]);
16128 static void alc861_auto_init_analog_input(struct hda_codec *codec)
16130 struct alc_spec *spec = codec->spec;
16131 struct auto_pin_cfg *cfg = &spec->autocfg;
16132 int i;
16134 for (i = 0; i < cfg->num_inputs; i++) {
16135 hda_nid_t nid = cfg->inputs[i].pin;
16136 if (nid >= 0x0c && nid <= 0x11)
16137 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16141 /* parse the BIOS configuration and set up the alc_spec */
16142 /* return 1 if successful, 0 if the proper config is not found,
16143 * or a negative error code
16145 static int alc861_parse_auto_config(struct hda_codec *codec)
16147 struct alc_spec *spec = codec->spec;
16148 int err;
16149 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16151 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16152 alc861_ignore);
16153 if (err < 0)
16154 return err;
16155 if (!spec->autocfg.line_outs)
16156 return 0; /* can't find valid BIOS pin config */
16158 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16159 if (err < 0)
16160 return err;
16161 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16162 if (err < 0)
16163 return err;
16164 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16165 if (err < 0)
16166 return err;
16167 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16168 if (err < 0)
16169 return err;
16171 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16173 alc_auto_parse_digital(codec);
16175 if (spec->kctls.list)
16176 add_mixer(spec, spec->kctls.list);
16178 add_verb(spec, alc861_auto_init_verbs);
16180 spec->num_mux_defs = 1;
16181 spec->input_mux = &spec->private_imux[0];
16183 spec->adc_nids = alc861_adc_nids;
16184 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16185 set_capture_mixer(codec);
16187 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16189 return 1;
16192 /* additional initialization for auto-configuration model */
16193 static void alc861_auto_init(struct hda_codec *codec)
16195 struct alc_spec *spec = codec->spec;
16196 alc861_auto_init_multi_out(codec);
16197 alc861_auto_init_hp_out(codec);
16198 alc861_auto_init_analog_input(codec);
16199 alc_auto_init_digital(codec);
16200 if (spec->unsol_event)
16201 alc_inithook(codec);
16204 #ifdef CONFIG_SND_HDA_POWER_SAVE
16205 static struct hda_amp_list alc861_loopbacks[] = {
16206 { 0x15, HDA_INPUT, 0 },
16207 { 0x15, HDA_INPUT, 1 },
16208 { 0x15, HDA_INPUT, 2 },
16209 { 0x15, HDA_INPUT, 3 },
16210 { } /* end */
16212 #endif
16216 * configuration and preset
16218 static const char * const alc861_models[ALC861_MODEL_LAST] = {
16219 [ALC861_3ST] = "3stack",
16220 [ALC660_3ST] = "3stack-660",
16221 [ALC861_3ST_DIG] = "3stack-dig",
16222 [ALC861_6ST_DIG] = "6stack-dig",
16223 [ALC861_UNIWILL_M31] = "uniwill-m31",
16224 [ALC861_TOSHIBA] = "toshiba",
16225 [ALC861_ASUS] = "asus",
16226 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16227 [ALC861_AUTO] = "auto",
16230 static struct snd_pci_quirk alc861_cfg_tbl[] = {
16231 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16232 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16233 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16234 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16235 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16236 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16237 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16238 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16239 * Any other models that need this preset?
16241 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16242 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16243 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16244 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16245 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16246 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16247 /* FIXME: the below seems conflict */
16248 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16249 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16250 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16254 static struct alc_config_preset alc861_presets[] = {
16255 [ALC861_3ST] = {
16256 .mixers = { alc861_3ST_mixer },
16257 .init_verbs = { alc861_threestack_init_verbs },
16258 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16259 .dac_nids = alc861_dac_nids,
16260 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16261 .channel_mode = alc861_threestack_modes,
16262 .need_dac_fix = 1,
16263 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16264 .adc_nids = alc861_adc_nids,
16265 .input_mux = &alc861_capture_source,
16267 [ALC861_3ST_DIG] = {
16268 .mixers = { alc861_base_mixer },
16269 .init_verbs = { alc861_threestack_init_verbs },
16270 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16271 .dac_nids = alc861_dac_nids,
16272 .dig_out_nid = ALC861_DIGOUT_NID,
16273 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16274 .channel_mode = alc861_threestack_modes,
16275 .need_dac_fix = 1,
16276 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16277 .adc_nids = alc861_adc_nids,
16278 .input_mux = &alc861_capture_source,
16280 [ALC861_6ST_DIG] = {
16281 .mixers = { alc861_base_mixer },
16282 .init_verbs = { alc861_base_init_verbs },
16283 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16284 .dac_nids = alc861_dac_nids,
16285 .dig_out_nid = ALC861_DIGOUT_NID,
16286 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16287 .channel_mode = alc861_8ch_modes,
16288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16289 .adc_nids = alc861_adc_nids,
16290 .input_mux = &alc861_capture_source,
16292 [ALC660_3ST] = {
16293 .mixers = { alc861_3ST_mixer },
16294 .init_verbs = { alc861_threestack_init_verbs },
16295 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16296 .dac_nids = alc660_dac_nids,
16297 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16298 .channel_mode = alc861_threestack_modes,
16299 .need_dac_fix = 1,
16300 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16301 .adc_nids = alc861_adc_nids,
16302 .input_mux = &alc861_capture_source,
16304 [ALC861_UNIWILL_M31] = {
16305 .mixers = { alc861_uniwill_m31_mixer },
16306 .init_verbs = { alc861_uniwill_m31_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16308 .dac_nids = alc861_dac_nids,
16309 .dig_out_nid = ALC861_DIGOUT_NID,
16310 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16311 .channel_mode = alc861_uniwill_m31_modes,
16312 .need_dac_fix = 1,
16313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16314 .adc_nids = alc861_adc_nids,
16315 .input_mux = &alc861_capture_source,
16317 [ALC861_TOSHIBA] = {
16318 .mixers = { alc861_toshiba_mixer },
16319 .init_verbs = { alc861_base_init_verbs,
16320 alc861_toshiba_init_verbs },
16321 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16322 .dac_nids = alc861_dac_nids,
16323 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16324 .channel_mode = alc883_3ST_2ch_modes,
16325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16326 .adc_nids = alc861_adc_nids,
16327 .input_mux = &alc861_capture_source,
16328 .unsol_event = alc861_toshiba_unsol_event,
16329 .init_hook = alc861_toshiba_automute,
16331 [ALC861_ASUS] = {
16332 .mixers = { alc861_asus_mixer },
16333 .init_verbs = { alc861_asus_init_verbs },
16334 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16335 .dac_nids = alc861_dac_nids,
16336 .dig_out_nid = ALC861_DIGOUT_NID,
16337 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16338 .channel_mode = alc861_asus_modes,
16339 .need_dac_fix = 1,
16340 .hp_nid = 0x06,
16341 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16342 .adc_nids = alc861_adc_nids,
16343 .input_mux = &alc861_capture_source,
16345 [ALC861_ASUS_LAPTOP] = {
16346 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16347 .init_verbs = { alc861_asus_init_verbs,
16348 alc861_asus_laptop_init_verbs },
16349 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16350 .dac_nids = alc861_dac_nids,
16351 .dig_out_nid = ALC861_DIGOUT_NID,
16352 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16353 .channel_mode = alc883_3ST_2ch_modes,
16354 .need_dac_fix = 1,
16355 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16356 .adc_nids = alc861_adc_nids,
16357 .input_mux = &alc861_capture_source,
16361 /* Pin config fixes */
16362 enum {
16363 PINFIX_FSC_AMILO_PI1505,
16366 static const struct alc_fixup alc861_fixups[] = {
16367 [PINFIX_FSC_AMILO_PI1505] = {
16368 .type = ALC_FIXUP_PINS,
16369 .v.pins = (const struct alc_pincfg[]) {
16370 { 0x0b, 0x0221101f }, /* HP */
16371 { 0x0f, 0x90170310 }, /* speaker */
16377 static struct snd_pci_quirk alc861_fixup_tbl[] = {
16378 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16382 static int patch_alc861(struct hda_codec *codec)
16384 struct alc_spec *spec;
16385 int board_config;
16386 int err;
16388 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16389 if (spec == NULL)
16390 return -ENOMEM;
16392 codec->spec = spec;
16394 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16395 alc861_models,
16396 alc861_cfg_tbl);
16398 if (board_config < 0) {
16399 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16400 codec->chip_name);
16401 board_config = ALC861_AUTO;
16404 if (board_config == ALC861_AUTO) {
16405 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16406 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16409 if (board_config == ALC861_AUTO) {
16410 /* automatic parse from the BIOS config */
16411 err = alc861_parse_auto_config(codec);
16412 if (err < 0) {
16413 alc_free(codec);
16414 return err;
16415 } else if (!err) {
16416 printk(KERN_INFO
16417 "hda_codec: Cannot set up configuration "
16418 "from BIOS. Using base mode...\n");
16419 board_config = ALC861_3ST_DIG;
16423 err = snd_hda_attach_beep_device(codec, 0x23);
16424 if (err < 0) {
16425 alc_free(codec);
16426 return err;
16429 if (board_config != ALC861_AUTO)
16430 setup_preset(codec, &alc861_presets[board_config]);
16432 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16433 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16435 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16436 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16438 if (!spec->cap_mixer)
16439 set_capture_mixer(codec);
16440 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16442 spec->vmaster_nid = 0x03;
16444 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16446 codec->patch_ops = alc_patch_ops;
16447 if (board_config == ALC861_AUTO) {
16448 spec->init_hook = alc861_auto_init;
16449 #ifdef CONFIG_SND_HDA_POWER_SAVE
16450 spec->power_hook = alc_power_eapd;
16451 #endif
16453 #ifdef CONFIG_SND_HDA_POWER_SAVE
16454 if (!spec->loopback.amplist)
16455 spec->loopback.amplist = alc861_loopbacks;
16456 #endif
16458 return 0;
16462 * ALC861-VD support
16464 * Based on ALC882
16466 * In addition, an independent DAC
16468 #define ALC861VD_DIGOUT_NID 0x06
16470 static hda_nid_t alc861vd_dac_nids[4] = {
16471 /* front, surr, clfe, side surr */
16472 0x02, 0x03, 0x04, 0x05
16475 /* dac_nids for ALC660vd are in a different order - according to
16476 * Realtek's driver.
16477 * This should probably result in a different mixer for 6stack models
16478 * of ALC660vd codecs, but for now there is only 3stack mixer
16479 * - and it is the same as in 861vd.
16480 * adc_nids in ALC660vd are (is) the same as in 861vd
16482 static hda_nid_t alc660vd_dac_nids[3] = {
16483 /* front, rear, clfe, rear_surr */
16484 0x02, 0x04, 0x03
16487 static hda_nid_t alc861vd_adc_nids[1] = {
16488 /* ADC0 */
16489 0x09,
16492 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16494 /* input MUX */
16495 /* FIXME: should be a matrix-type input source selection */
16496 static struct hda_input_mux alc861vd_capture_source = {
16497 .num_items = 4,
16498 .items = {
16499 { "Mic", 0x0 },
16500 { "Front Mic", 0x1 },
16501 { "Line", 0x2 },
16502 { "CD", 0x4 },
16506 static struct hda_input_mux alc861vd_dallas_capture_source = {
16507 .num_items = 2,
16508 .items = {
16509 { "Mic", 0x0 },
16510 { "Internal Mic", 0x1 },
16514 static struct hda_input_mux alc861vd_hp_capture_source = {
16515 .num_items = 2,
16516 .items = {
16517 { "Front Mic", 0x0 },
16518 { "ATAPI Mic", 0x1 },
16523 * 2ch mode
16525 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16526 { 2, NULL }
16530 * 6ch mode
16532 static struct hda_verb alc861vd_6stack_ch6_init[] = {
16533 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16534 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16535 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16536 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16537 { } /* end */
16541 * 8ch mode
16543 static struct hda_verb alc861vd_6stack_ch8_init[] = {
16544 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16545 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16546 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16547 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16548 { } /* end */
16551 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
16552 { 6, alc861vd_6stack_ch6_init },
16553 { 8, alc861vd_6stack_ch8_init },
16556 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16558 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16559 .name = "Channel Mode",
16560 .info = alc_ch_mode_info,
16561 .get = alc_ch_mode_get,
16562 .put = alc_ch_mode_put,
16564 { } /* end */
16567 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16568 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16570 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16571 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16572 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16575 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16577 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16578 HDA_OUTPUT),
16579 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16580 HDA_OUTPUT),
16581 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16582 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16584 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16585 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16587 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16589 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16590 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16591 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16593 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16595 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16597 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16598 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16600 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16601 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16603 { } /* end */
16606 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16607 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16608 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16610 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16612 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16616 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16617 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16618 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16620 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16621 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16623 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16624 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16626 { } /* end */
16629 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16630 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16631 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16632 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16644 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16645 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16647 { } /* end */
16650 /* Pin assignment: Speaker=0x14, HP = 0x15,
16651 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16653 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16654 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16656 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16657 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16658 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16662 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16663 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16664 { } /* end */
16667 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16668 * Front Mic=0x18, ATAPI Mic = 0x19,
16670 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16671 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16672 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16673 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16674 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16675 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16676 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16677 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16678 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16680 { } /* end */
16684 * generic initialization of ADC, input mixers and output mixers
16686 static struct hda_verb alc861vd_volume_init_verbs[] = {
16688 * Unmute ADC0 and set the default input to mic-in
16690 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16693 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16694 * the analog-loopback mixer widget
16696 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16697 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16698 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16699 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16700 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16701 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16703 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16704 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16705 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16706 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16707 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16710 * Set up output mixers (0x02 - 0x05)
16712 /* set vol=0 to output mixers */
16713 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16714 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16715 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16716 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16718 /* set up input amps for analog loopback */
16719 /* Amp Indices: DAC = 0, mixer = 1 */
16720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16726 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16727 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16733 * 3-stack pin configuration:
16734 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16736 static struct hda_verb alc861vd_3stack_init_verbs[] = {
16738 * Set pin mode and muting
16740 /* set front pin widgets 0x14 for output */
16741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16743 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16745 /* Mic (rear) pin: input vref at 80% */
16746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16748 /* Front Mic pin: input vref at 80% */
16749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16751 /* Line In pin: input */
16752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16754 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16755 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16756 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16757 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16758 /* CD pin widget for input */
16759 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16765 * 6-stack pin configuration:
16767 static struct hda_verb alc861vd_6stack_init_verbs[] = {
16769 * Set pin mode and muting
16771 /* set front pin widgets 0x14 for output */
16772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16774 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16776 /* Rear Pin: output 1 (0x0d) */
16777 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16778 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16779 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16780 /* CLFE Pin: output 2 (0x0e) */
16781 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16782 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16783 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16784 /* Side Pin: output 3 (0x0f) */
16785 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16786 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16787 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16789 /* Mic (rear) pin: input vref at 80% */
16790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16791 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16792 /* Front Mic pin: input vref at 80% */
16793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16794 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16795 /* Line In pin: input */
16796 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16797 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16798 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16799 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16800 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16801 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16802 /* CD pin widget for input */
16803 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16808 static struct hda_verb alc861vd_eapd_verbs[] = {
16809 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16813 static struct hda_verb alc660vd_eapd_verbs[] = {
16814 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16815 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16819 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16821 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16822 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16823 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16824 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16828 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16830 struct alc_spec *spec = codec->spec;
16831 spec->autocfg.hp_pins[0] = 0x1b;
16832 spec->autocfg.speaker_pins[0] = 0x14;
16835 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16837 alc_automute_amp(codec);
16838 alc88x_simple_mic_automute(codec);
16841 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16842 unsigned int res)
16844 switch (res >> 26) {
16845 case ALC880_MIC_EVENT:
16846 alc88x_simple_mic_automute(codec);
16847 break;
16848 default:
16849 alc_automute_amp_unsol_event(codec, res);
16850 break;
16854 static struct hda_verb alc861vd_dallas_verbs[] = {
16855 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16856 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16857 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16858 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16860 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16861 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16862 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16863 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16864 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16865 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16866 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16867 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16873 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16874 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16875 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16876 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16883 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16884 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16885 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16887 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16888 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16892 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16893 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16894 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16896 { } /* end */
16899 /* toggle speaker-output according to the hp-jack state */
16900 static void alc861vd_dallas_setup(struct hda_codec *codec)
16902 struct alc_spec *spec = codec->spec;
16904 spec->autocfg.hp_pins[0] = 0x15;
16905 spec->autocfg.speaker_pins[0] = 0x14;
16908 #ifdef CONFIG_SND_HDA_POWER_SAVE
16909 #define alc861vd_loopbacks alc880_loopbacks
16910 #endif
16912 /* pcm configuration: identical with ALC880 */
16913 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16914 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16915 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16916 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16919 * configuration and preset
16921 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16922 [ALC660VD_3ST] = "3stack-660",
16923 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16924 [ALC660VD_ASUS_V1S] = "asus-v1s",
16925 [ALC861VD_3ST] = "3stack",
16926 [ALC861VD_3ST_DIG] = "3stack-digout",
16927 [ALC861VD_6ST_DIG] = "6stack-digout",
16928 [ALC861VD_LENOVO] = "lenovo",
16929 [ALC861VD_DALLAS] = "dallas",
16930 [ALC861VD_HP] = "hp",
16931 [ALC861VD_AUTO] = "auto",
16934 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16935 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16936 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16937 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16938 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16939 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16940 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16941 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16942 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16943 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16944 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16945 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16946 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16947 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16948 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16949 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16953 static struct alc_config_preset alc861vd_presets[] = {
16954 [ALC660VD_3ST] = {
16955 .mixers = { alc861vd_3st_mixer },
16956 .init_verbs = { alc861vd_volume_init_verbs,
16957 alc861vd_3stack_init_verbs },
16958 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16959 .dac_nids = alc660vd_dac_nids,
16960 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16961 .channel_mode = alc861vd_3stack_2ch_modes,
16962 .input_mux = &alc861vd_capture_source,
16964 [ALC660VD_3ST_DIG] = {
16965 .mixers = { alc861vd_3st_mixer },
16966 .init_verbs = { alc861vd_volume_init_verbs,
16967 alc861vd_3stack_init_verbs },
16968 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16969 .dac_nids = alc660vd_dac_nids,
16970 .dig_out_nid = ALC861VD_DIGOUT_NID,
16971 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16972 .channel_mode = alc861vd_3stack_2ch_modes,
16973 .input_mux = &alc861vd_capture_source,
16975 [ALC861VD_3ST] = {
16976 .mixers = { alc861vd_3st_mixer },
16977 .init_verbs = { alc861vd_volume_init_verbs,
16978 alc861vd_3stack_init_verbs },
16979 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16980 .dac_nids = alc861vd_dac_nids,
16981 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16982 .channel_mode = alc861vd_3stack_2ch_modes,
16983 .input_mux = &alc861vd_capture_source,
16985 [ALC861VD_3ST_DIG] = {
16986 .mixers = { alc861vd_3st_mixer },
16987 .init_verbs = { alc861vd_volume_init_verbs,
16988 alc861vd_3stack_init_verbs },
16989 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16990 .dac_nids = alc861vd_dac_nids,
16991 .dig_out_nid = ALC861VD_DIGOUT_NID,
16992 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16993 .channel_mode = alc861vd_3stack_2ch_modes,
16994 .input_mux = &alc861vd_capture_source,
16996 [ALC861VD_6ST_DIG] = {
16997 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16998 .init_verbs = { alc861vd_volume_init_verbs,
16999 alc861vd_6stack_init_verbs },
17000 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17001 .dac_nids = alc861vd_dac_nids,
17002 .dig_out_nid = ALC861VD_DIGOUT_NID,
17003 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17004 .channel_mode = alc861vd_6stack_modes,
17005 .input_mux = &alc861vd_capture_source,
17007 [ALC861VD_LENOVO] = {
17008 .mixers = { alc861vd_lenovo_mixer },
17009 .init_verbs = { alc861vd_volume_init_verbs,
17010 alc861vd_3stack_init_verbs,
17011 alc861vd_eapd_verbs,
17012 alc861vd_lenovo_unsol_verbs },
17013 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17014 .dac_nids = alc660vd_dac_nids,
17015 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17016 .channel_mode = alc861vd_3stack_2ch_modes,
17017 .input_mux = &alc861vd_capture_source,
17018 .unsol_event = alc861vd_lenovo_unsol_event,
17019 .setup = alc861vd_lenovo_setup,
17020 .init_hook = alc861vd_lenovo_init_hook,
17022 [ALC861VD_DALLAS] = {
17023 .mixers = { alc861vd_dallas_mixer },
17024 .init_verbs = { alc861vd_dallas_verbs },
17025 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17026 .dac_nids = alc861vd_dac_nids,
17027 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17028 .channel_mode = alc861vd_3stack_2ch_modes,
17029 .input_mux = &alc861vd_dallas_capture_source,
17030 .unsol_event = alc_automute_amp_unsol_event,
17031 .setup = alc861vd_dallas_setup,
17032 .init_hook = alc_automute_amp,
17034 [ALC861VD_HP] = {
17035 .mixers = { alc861vd_hp_mixer },
17036 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17037 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17038 .dac_nids = alc861vd_dac_nids,
17039 .dig_out_nid = ALC861VD_DIGOUT_NID,
17040 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17041 .channel_mode = alc861vd_3stack_2ch_modes,
17042 .input_mux = &alc861vd_hp_capture_source,
17043 .unsol_event = alc_automute_amp_unsol_event,
17044 .setup = alc861vd_dallas_setup,
17045 .init_hook = alc_automute_amp,
17047 [ALC660VD_ASUS_V1S] = {
17048 .mixers = { alc861vd_lenovo_mixer },
17049 .init_verbs = { alc861vd_volume_init_verbs,
17050 alc861vd_3stack_init_verbs,
17051 alc861vd_eapd_verbs,
17052 alc861vd_lenovo_unsol_verbs },
17053 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17054 .dac_nids = alc660vd_dac_nids,
17055 .dig_out_nid = ALC861VD_DIGOUT_NID,
17056 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17057 .channel_mode = alc861vd_3stack_2ch_modes,
17058 .input_mux = &alc861vd_capture_source,
17059 .unsol_event = alc861vd_lenovo_unsol_event,
17060 .setup = alc861vd_lenovo_setup,
17061 .init_hook = alc861vd_lenovo_init_hook,
17066 * BIOS auto configuration
17068 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17069 const struct auto_pin_cfg *cfg)
17071 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17075 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17076 hda_nid_t nid, int pin_type, int dac_idx)
17078 alc_set_pin_output(codec, nid, pin_type);
17081 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17083 struct alc_spec *spec = codec->spec;
17084 int i;
17086 for (i = 0; i <= HDA_SIDE; i++) {
17087 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17088 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17089 if (nid)
17090 alc861vd_auto_set_output_and_unmute(codec, nid,
17091 pin_type, i);
17096 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17098 struct alc_spec *spec = codec->spec;
17099 hda_nid_t pin;
17101 pin = spec->autocfg.hp_pins[0];
17102 if (pin) /* connect to front and use dac 0 */
17103 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17104 pin = spec->autocfg.speaker_pins[0];
17105 if (pin)
17106 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17109 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17111 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17113 struct alc_spec *spec = codec->spec;
17114 struct auto_pin_cfg *cfg = &spec->autocfg;
17115 int i;
17117 for (i = 0; i < cfg->num_inputs; i++) {
17118 hda_nid_t nid = cfg->inputs[i].pin;
17119 if (alc_is_input_pin(codec, nid)) {
17120 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17121 if (nid != ALC861VD_PIN_CD_NID &&
17122 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17123 snd_hda_codec_write(codec, nid, 0,
17124 AC_VERB_SET_AMP_GAIN_MUTE,
17125 AMP_OUT_MUTE);
17130 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
17132 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17133 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17135 /* add playback controls from the parsed DAC table */
17136 /* Based on ALC880 version. But ALC861VD has separate,
17137 * different NIDs for mute/unmute switch and volume control */
17138 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17139 const struct auto_pin_cfg *cfg)
17141 static const char * const chname[4] = {
17142 "Front", "Surround", "CLFE", "Side"
17144 const char *pfx = alc_get_line_out_pfx(cfg, true);
17145 hda_nid_t nid_v, nid_s;
17146 int i, err;
17148 for (i = 0; i < cfg->line_outs; i++) {
17149 if (!spec->multiout.dac_nids[i])
17150 continue;
17151 nid_v = alc861vd_idx_to_mixer_vol(
17152 alc880_dac_to_idx(
17153 spec->multiout.dac_nids[i]));
17154 nid_s = alc861vd_idx_to_mixer_switch(
17155 alc880_dac_to_idx(
17156 spec->multiout.dac_nids[i]));
17158 if (!pfx && i == 2) {
17159 /* Center/LFE */
17160 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17161 "Center",
17162 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17163 HDA_OUTPUT));
17164 if (err < 0)
17165 return err;
17166 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17167 "LFE",
17168 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17169 HDA_OUTPUT));
17170 if (err < 0)
17171 return err;
17172 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17173 "Center",
17174 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17175 HDA_INPUT));
17176 if (err < 0)
17177 return err;
17178 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17179 "LFE",
17180 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17181 HDA_INPUT));
17182 if (err < 0)
17183 return err;
17184 } else {
17185 const char *name = pfx;
17186 if (!name)
17187 name = chname[i];
17188 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17189 name, i,
17190 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17191 HDA_OUTPUT));
17192 if (err < 0)
17193 return err;
17194 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17195 name, i,
17196 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17197 HDA_INPUT));
17198 if (err < 0)
17199 return err;
17202 return 0;
17205 /* add playback controls for speaker and HP outputs */
17206 /* Based on ALC880 version. But ALC861VD has separate,
17207 * different NIDs for mute/unmute switch and volume control */
17208 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17209 hda_nid_t pin, const char *pfx)
17211 hda_nid_t nid_v, nid_s;
17212 int err;
17214 if (!pin)
17215 return 0;
17217 if (alc880_is_fixed_pin(pin)) {
17218 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17219 /* specify the DAC as the extra output */
17220 if (!spec->multiout.hp_nid)
17221 spec->multiout.hp_nid = nid_v;
17222 else
17223 spec->multiout.extra_out_nid[0] = nid_v;
17224 /* control HP volume/switch on the output mixer amp */
17225 nid_v = alc861vd_idx_to_mixer_vol(
17226 alc880_fixed_pin_idx(pin));
17227 nid_s = alc861vd_idx_to_mixer_switch(
17228 alc880_fixed_pin_idx(pin));
17230 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17231 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17232 if (err < 0)
17233 return err;
17234 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17235 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17236 if (err < 0)
17237 return err;
17238 } else if (alc880_is_multi_pin(pin)) {
17239 /* set manual connection */
17240 /* we have only a switch on HP-out PIN */
17241 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17242 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17243 if (err < 0)
17244 return err;
17246 return 0;
17249 /* parse the BIOS configuration and set up the alc_spec
17250 * return 1 if successful, 0 if the proper config is not found,
17251 * or a negative error code
17252 * Based on ALC880 version - had to change it to override
17253 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17254 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17256 struct alc_spec *spec = codec->spec;
17257 int err;
17258 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17260 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17261 alc861vd_ignore);
17262 if (err < 0)
17263 return err;
17264 if (!spec->autocfg.line_outs)
17265 return 0; /* can't find valid BIOS pin config */
17267 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17268 if (err < 0)
17269 return err;
17270 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17271 if (err < 0)
17272 return err;
17273 err = alc861vd_auto_create_extra_out(spec,
17274 spec->autocfg.speaker_pins[0],
17275 "Speaker");
17276 if (err < 0)
17277 return err;
17278 err = alc861vd_auto_create_extra_out(spec,
17279 spec->autocfg.hp_pins[0],
17280 "Headphone");
17281 if (err < 0)
17282 return err;
17283 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17284 if (err < 0)
17285 return err;
17287 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17289 alc_auto_parse_digital(codec);
17291 if (spec->kctls.list)
17292 add_mixer(spec, spec->kctls.list);
17294 add_verb(spec, alc861vd_volume_init_verbs);
17296 spec->num_mux_defs = 1;
17297 spec->input_mux = &spec->private_imux[0];
17299 err = alc_auto_add_mic_boost(codec);
17300 if (err < 0)
17301 return err;
17303 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17305 return 1;
17308 /* additional initialization for auto-configuration model */
17309 static void alc861vd_auto_init(struct hda_codec *codec)
17311 struct alc_spec *spec = codec->spec;
17312 alc861vd_auto_init_multi_out(codec);
17313 alc861vd_auto_init_hp_out(codec);
17314 alc861vd_auto_init_analog_input(codec);
17315 alc861vd_auto_init_input_src(codec);
17316 alc_auto_init_digital(codec);
17317 if (spec->unsol_event)
17318 alc_inithook(codec);
17321 enum {
17322 ALC660VD_FIX_ASUS_GPIO1
17325 /* reset GPIO1 */
17326 static const struct alc_fixup alc861vd_fixups[] = {
17327 [ALC660VD_FIX_ASUS_GPIO1] = {
17328 .type = ALC_FIXUP_VERBS,
17329 .v.verbs = (const struct hda_verb[]) {
17330 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17331 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17332 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17338 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17339 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17343 static int patch_alc861vd(struct hda_codec *codec)
17345 struct alc_spec *spec;
17346 int err, board_config;
17348 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17349 if (spec == NULL)
17350 return -ENOMEM;
17352 codec->spec = spec;
17354 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17355 alc861vd_models,
17356 alc861vd_cfg_tbl);
17358 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17359 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17360 codec->chip_name);
17361 board_config = ALC861VD_AUTO;
17364 if (board_config == ALC861VD_AUTO) {
17365 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17366 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17369 if (board_config == ALC861VD_AUTO) {
17370 /* automatic parse from the BIOS config */
17371 err = alc861vd_parse_auto_config(codec);
17372 if (err < 0) {
17373 alc_free(codec);
17374 return err;
17375 } else if (!err) {
17376 printk(KERN_INFO
17377 "hda_codec: Cannot set up configuration "
17378 "from BIOS. Using base mode...\n");
17379 board_config = ALC861VD_3ST;
17383 err = snd_hda_attach_beep_device(codec, 0x23);
17384 if (err < 0) {
17385 alc_free(codec);
17386 return err;
17389 if (board_config != ALC861VD_AUTO)
17390 setup_preset(codec, &alc861vd_presets[board_config]);
17392 if (codec->vendor_id == 0x10ec0660) {
17393 /* always turn on EAPD */
17394 add_verb(spec, alc660vd_eapd_verbs);
17397 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17398 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17400 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17401 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17403 if (!spec->adc_nids) {
17404 spec->adc_nids = alc861vd_adc_nids;
17405 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17407 if (!spec->capsrc_nids)
17408 spec->capsrc_nids = alc861vd_capsrc_nids;
17410 set_capture_mixer(codec);
17411 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17413 spec->vmaster_nid = 0x02;
17415 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17417 codec->patch_ops = alc_patch_ops;
17419 if (board_config == ALC861VD_AUTO)
17420 spec->init_hook = alc861vd_auto_init;
17421 #ifdef CONFIG_SND_HDA_POWER_SAVE
17422 if (!spec->loopback.amplist)
17423 spec->loopback.amplist = alc861vd_loopbacks;
17424 #endif
17426 return 0;
17430 * ALC662 support
17432 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17433 * configuration. Each pin widget can choose any input DACs and a mixer.
17434 * Each ADC is connected from a mixer of all inputs. This makes possible
17435 * 6-channel independent captures.
17437 * In addition, an independent DAC for the multi-playback (not used in this
17438 * driver yet).
17440 #define ALC662_DIGOUT_NID 0x06
17441 #define ALC662_DIGIN_NID 0x0a
17443 static hda_nid_t alc662_dac_nids[4] = {
17444 /* front, rear, clfe, rear_surr */
17445 0x02, 0x03, 0x04
17448 static hda_nid_t alc272_dac_nids[2] = {
17449 0x02, 0x03
17452 static hda_nid_t alc662_adc_nids[2] = {
17453 /* ADC1-2 */
17454 0x09, 0x08
17457 static hda_nid_t alc272_adc_nids[1] = {
17458 /* ADC1-2 */
17459 0x08,
17462 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17463 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17466 /* input MUX */
17467 /* FIXME: should be a matrix-type input source selection */
17468 static struct hda_input_mux alc662_capture_source = {
17469 .num_items = 4,
17470 .items = {
17471 { "Mic", 0x0 },
17472 { "Front Mic", 0x1 },
17473 { "Line", 0x2 },
17474 { "CD", 0x4 },
17478 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
17479 .num_items = 2,
17480 .items = {
17481 { "Mic", 0x1 },
17482 { "Line", 0x2 },
17486 static struct hda_input_mux alc663_capture_source = {
17487 .num_items = 3,
17488 .items = {
17489 { "Mic", 0x0 },
17490 { "Front Mic", 0x1 },
17491 { "Line", 0x2 },
17495 #if 0 /* set to 1 for testing other input sources below */
17496 static struct hda_input_mux alc272_nc10_capture_source = {
17497 .num_items = 16,
17498 .items = {
17499 { "Autoselect Mic", 0x0 },
17500 { "Internal Mic", 0x1 },
17501 { "In-0x02", 0x2 },
17502 { "In-0x03", 0x3 },
17503 { "In-0x04", 0x4 },
17504 { "In-0x05", 0x5 },
17505 { "In-0x06", 0x6 },
17506 { "In-0x07", 0x7 },
17507 { "In-0x08", 0x8 },
17508 { "In-0x09", 0x9 },
17509 { "In-0x0a", 0x0a },
17510 { "In-0x0b", 0x0b },
17511 { "In-0x0c", 0x0c },
17512 { "In-0x0d", 0x0d },
17513 { "In-0x0e", 0x0e },
17514 { "In-0x0f", 0x0f },
17517 #endif
17520 * 2ch mode
17522 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17523 { 2, NULL }
17527 * 2ch mode
17529 static struct hda_verb alc662_3ST_ch2_init[] = {
17530 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17531 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17534 { } /* end */
17538 * 6ch mode
17540 static struct hda_verb alc662_3ST_ch6_init[] = {
17541 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17542 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17543 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17544 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17545 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17546 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17547 { } /* end */
17550 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17551 { 2, alc662_3ST_ch2_init },
17552 { 6, alc662_3ST_ch6_init },
17556 * 2ch mode
17558 static struct hda_verb alc662_sixstack_ch6_init[] = {
17559 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17560 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17561 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17562 { } /* end */
17566 * 6ch mode
17568 static struct hda_verb alc662_sixstack_ch8_init[] = {
17569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17572 { } /* end */
17575 static struct hda_channel_mode alc662_5stack_modes[2] = {
17576 { 2, alc662_sixstack_ch6_init },
17577 { 6, alc662_sixstack_ch8_init },
17580 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17581 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17584 static struct snd_kcontrol_new alc662_base_mixer[] = {
17585 /* output mixer control */
17586 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17587 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17588 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17589 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17590 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17591 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17592 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17593 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17594 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17596 /*Input mixer control */
17597 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17598 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17599 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17600 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17601 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17602 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17605 { } /* end */
17608 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17609 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17610 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17612 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17613 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17614 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17615 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17616 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17617 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17620 { } /* end */
17623 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17624 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17625 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17626 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17627 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17628 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17629 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17631 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17633 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17634 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17635 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17636 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17639 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17640 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17641 { } /* end */
17644 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17645 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17646 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17647 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17648 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17649 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17650 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17651 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17654 { } /* end */
17657 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17658 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17659 ALC262_HIPPO_MASTER_SWITCH,
17661 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17665 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17666 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17667 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17668 { } /* end */
17671 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17672 ALC262_HIPPO_MASTER_SWITCH,
17673 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17674 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17675 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17676 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17677 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17678 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17679 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17681 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17682 { } /* end */
17685 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
17686 .ops = &snd_hda_bind_vol,
17687 .values = {
17688 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17689 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17694 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
17695 .ops = &snd_hda_bind_sw,
17696 .values = {
17697 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17698 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17703 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
17704 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17705 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17708 { } /* end */
17711 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17712 .ops = &snd_hda_bind_sw,
17713 .values = {
17714 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17715 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17716 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17721 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17722 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17723 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17724 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17725 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17726 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17727 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17729 { } /* end */
17732 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
17733 .ops = &snd_hda_bind_sw,
17734 .values = {
17735 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17736 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17742 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17747 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17748 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17749 { } /* end */
17752 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17753 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17754 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17755 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17758 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17759 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17760 { } /* end */
17763 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17764 .ops = &snd_hda_bind_vol,
17765 .values = {
17766 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17767 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17772 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
17773 .ops = &snd_hda_bind_sw,
17774 .values = {
17775 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17781 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17782 HDA_BIND_VOL("Master Playback Volume",
17783 &alc663_asus_two_bind_master_vol),
17784 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17785 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17786 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17789 { } /* end */
17792 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17793 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17794 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17795 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17796 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17799 { } /* end */
17802 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17803 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17804 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17805 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17806 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17807 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17811 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17812 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17813 { } /* end */
17816 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17817 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17818 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17819 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17823 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17824 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17825 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17826 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17827 { } /* end */
17830 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17831 .ops = &snd_hda_bind_sw,
17832 .values = {
17833 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17834 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17835 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17836 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17837 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17842 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17843 .ops = &snd_hda_bind_sw,
17844 .values = {
17845 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17846 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17851 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
17852 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17853 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17854 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17855 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17856 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17858 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17859 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17860 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17861 { } /* end */
17864 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
17865 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17866 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17867 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17868 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17869 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17871 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17872 { } /* end */
17876 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
17878 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17879 .name = "Channel Mode",
17880 .info = alc_ch_mode_info,
17881 .get = alc_ch_mode_get,
17882 .put = alc_ch_mode_put,
17884 { } /* end */
17887 static struct hda_verb alc662_init_verbs[] = {
17888 /* ADC: mute amp left and right */
17889 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17890 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17893 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17895 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17897 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17899 /* Front Pin: output 0 (0x0c) */
17900 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17903 /* Rear Pin: output 1 (0x0d) */
17904 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17905 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17907 /* CLFE Pin: output 2 (0x0e) */
17908 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17911 /* Mic (rear) pin: input vref at 80% */
17912 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17913 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17914 /* Front Mic pin: input vref at 80% */
17915 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17916 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17917 /* Line In pin: input */
17918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17920 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17921 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17922 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17923 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17924 /* CD pin widget for input */
17925 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17927 /* FIXME: use matrix-type input source selection */
17928 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17929 /* Input mixer */
17930 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17933 /* always trun on EAPD */
17934 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17935 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17940 static struct hda_verb alc663_init_verbs[] = {
17941 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17942 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17943 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17946 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17950 static struct hda_verb alc272_init_verbs[] = {
17951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17952 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17953 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17954 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17955 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17956 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17957 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17958 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17962 static struct hda_verb alc662_sue_init_verbs[] = {
17963 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17964 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17968 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17969 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17970 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17974 /* Set Unsolicited Event*/
17975 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17976 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17977 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17981 static struct hda_verb alc663_m51va_init_verbs[] = {
17982 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17983 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17984 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17994 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17995 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17996 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17997 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17998 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17999 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18000 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18001 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18005 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18006 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18007 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18008 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18009 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18012 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18013 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18017 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
18018 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18020 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18022 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18023 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18024 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18028 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18029 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18030 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18031 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18032 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18033 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18035 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18036 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18037 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18038 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18039 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18044 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18045 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18046 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18047 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18048 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18049 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18050 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18055 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18060 static struct hda_verb alc663_g71v_init_verbs[] = {
18061 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18062 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18063 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18065 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18066 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18067 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18069 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18070 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18071 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18075 static struct hda_verb alc663_g50v_init_verbs[] = {
18076 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18077 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18078 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18080 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18081 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18085 static struct hda_verb alc662_ecs_init_verbs[] = {
18086 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18088 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18089 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18093 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
18094 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18095 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18096 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18097 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18098 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18099 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18100 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18103 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18108 static struct hda_verb alc272_dell_init_verbs[] = {
18109 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18110 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18111 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18112 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18113 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18114 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18115 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18116 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18117 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18118 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18119 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18123 static struct hda_verb alc663_mode7_init_verbs[] = {
18124 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18125 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18126 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18128 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18129 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18130 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18131 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18132 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18133 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18135 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18136 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18137 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18138 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18142 static struct hda_verb alc663_mode8_init_verbs[] = {
18143 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18145 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18146 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18148 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18149 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18162 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18163 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18164 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18165 { } /* end */
18168 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18169 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18170 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18171 { } /* end */
18174 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
18176 unsigned int present;
18177 unsigned char bits;
18179 present = snd_hda_jack_detect(codec, 0x14);
18180 bits = present ? HDA_AMP_MUTE : 0;
18182 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18183 HDA_AMP_MUTE, bits);
18186 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
18188 unsigned int present;
18189 unsigned char bits;
18191 present = snd_hda_jack_detect(codec, 0x1b);
18192 bits = present ? HDA_AMP_MUTE : 0;
18194 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18195 HDA_AMP_MUTE, bits);
18196 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18197 HDA_AMP_MUTE, bits);
18200 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
18201 unsigned int res)
18203 if ((res >> 26) == ALC880_HP_EVENT)
18204 alc662_lenovo_101e_all_automute(codec);
18205 if ((res >> 26) == ALC880_FRONT_EVENT)
18206 alc662_lenovo_101e_ispeaker_automute(codec);
18209 /* unsolicited event for HP jack sensing */
18210 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
18211 unsigned int res)
18213 if ((res >> 26) == ALC880_MIC_EVENT)
18214 alc_mic_automute(codec);
18215 else
18216 alc262_hippo_unsol_event(codec, res);
18219 static void alc662_eeepc_setup(struct hda_codec *codec)
18221 struct alc_spec *spec = codec->spec;
18223 alc262_hippo1_setup(codec);
18224 spec->ext_mic.pin = 0x18;
18225 spec->ext_mic.mux_idx = 0;
18226 spec->int_mic.pin = 0x19;
18227 spec->int_mic.mux_idx = 1;
18228 spec->auto_mic = 1;
18231 static void alc662_eeepc_inithook(struct hda_codec *codec)
18233 alc262_hippo_automute(codec);
18234 alc_mic_automute(codec);
18237 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18239 struct alc_spec *spec = codec->spec;
18241 spec->autocfg.hp_pins[0] = 0x14;
18242 spec->autocfg.speaker_pins[0] = 0x1b;
18245 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
18247 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
18249 unsigned int present;
18250 unsigned char bits;
18252 present = snd_hda_jack_detect(codec, 0x21);
18253 bits = present ? HDA_AMP_MUTE : 0;
18254 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18255 HDA_AMP_MUTE, bits);
18256 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18257 HDA_AMP_MUTE, bits);
18260 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
18262 unsigned int present;
18263 unsigned char bits;
18265 present = snd_hda_jack_detect(codec, 0x21);
18266 bits = present ? HDA_AMP_MUTE : 0;
18267 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18268 HDA_AMP_MUTE, bits);
18269 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18270 HDA_AMP_MUTE, bits);
18271 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18272 HDA_AMP_MUTE, bits);
18273 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18274 HDA_AMP_MUTE, bits);
18277 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
18279 unsigned int present;
18280 unsigned char bits;
18282 present = snd_hda_jack_detect(codec, 0x15);
18283 bits = present ? HDA_AMP_MUTE : 0;
18284 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18285 HDA_AMP_MUTE, bits);
18286 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18287 HDA_AMP_MUTE, bits);
18288 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
18289 HDA_AMP_MUTE, bits);
18290 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
18291 HDA_AMP_MUTE, bits);
18294 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
18296 unsigned int present;
18297 unsigned char bits;
18299 present = snd_hda_jack_detect(codec, 0x1b);
18300 bits = present ? 0 : PIN_OUT;
18301 snd_hda_codec_write(codec, 0x14, 0,
18302 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
18305 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
18307 unsigned int present1, present2;
18309 present1 = snd_hda_jack_detect(codec, 0x21);
18310 present2 = snd_hda_jack_detect(codec, 0x15);
18312 if (present1 || present2) {
18313 snd_hda_codec_write_cache(codec, 0x14, 0,
18314 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18315 } else {
18316 snd_hda_codec_write_cache(codec, 0x14, 0,
18317 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18321 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
18323 unsigned int present1, present2;
18325 present1 = snd_hda_jack_detect(codec, 0x1b);
18326 present2 = snd_hda_jack_detect(codec, 0x15);
18328 if (present1 || present2) {
18329 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18330 HDA_AMP_MUTE, HDA_AMP_MUTE);
18331 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18332 HDA_AMP_MUTE, HDA_AMP_MUTE);
18333 } else {
18334 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
18335 HDA_AMP_MUTE, 0);
18336 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
18337 HDA_AMP_MUTE, 0);
18341 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
18343 unsigned int present1, present2;
18345 present1 = snd_hda_codec_read(codec, 0x1b, 0,
18346 AC_VERB_GET_PIN_SENSE, 0)
18347 & AC_PINSENSE_PRESENCE;
18348 present2 = snd_hda_codec_read(codec, 0x21, 0,
18349 AC_VERB_GET_PIN_SENSE, 0)
18350 & AC_PINSENSE_PRESENCE;
18352 if (present1 || present2) {
18353 snd_hda_codec_write_cache(codec, 0x14, 0,
18354 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18355 snd_hda_codec_write_cache(codec, 0x17, 0,
18356 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18357 } else {
18358 snd_hda_codec_write_cache(codec, 0x14, 0,
18359 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18360 snd_hda_codec_write_cache(codec, 0x17, 0,
18361 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18365 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
18367 unsigned int present1, present2;
18369 present1 = snd_hda_codec_read(codec, 0x21, 0,
18370 AC_VERB_GET_PIN_SENSE, 0)
18371 & AC_PINSENSE_PRESENCE;
18372 present2 = snd_hda_codec_read(codec, 0x15, 0,
18373 AC_VERB_GET_PIN_SENSE, 0)
18374 & AC_PINSENSE_PRESENCE;
18376 if (present1 || present2) {
18377 snd_hda_codec_write_cache(codec, 0x14, 0,
18378 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18379 snd_hda_codec_write_cache(codec, 0x17, 0,
18380 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
18381 } else {
18382 snd_hda_codec_write_cache(codec, 0x14, 0,
18383 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18384 snd_hda_codec_write_cache(codec, 0x17, 0,
18385 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
18389 static void alc663_m51va_unsol_event(struct hda_codec *codec,
18390 unsigned int res)
18392 switch (res >> 26) {
18393 case ALC880_HP_EVENT:
18394 alc663_m51va_speaker_automute(codec);
18395 break;
18396 case ALC880_MIC_EVENT:
18397 alc_mic_automute(codec);
18398 break;
18402 static void alc663_m51va_setup(struct hda_codec *codec)
18404 struct alc_spec *spec = codec->spec;
18405 spec->ext_mic.pin = 0x18;
18406 spec->ext_mic.mux_idx = 0;
18407 spec->int_mic.pin = 0x12;
18408 spec->int_mic.mux_idx = 9;
18409 spec->auto_mic = 1;
18412 static void alc663_m51va_inithook(struct hda_codec *codec)
18414 alc663_m51va_speaker_automute(codec);
18415 alc_mic_automute(codec);
18418 /* ***************** Mode1 ******************************/
18419 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
18421 static void alc663_mode1_setup(struct hda_codec *codec)
18423 struct alc_spec *spec = codec->spec;
18424 spec->ext_mic.pin = 0x18;
18425 spec->ext_mic.mux_idx = 0;
18426 spec->int_mic.pin = 0x19;
18427 spec->int_mic.mux_idx = 1;
18428 spec->auto_mic = 1;
18431 #define alc663_mode1_inithook alc663_m51va_inithook
18433 /* ***************** Mode2 ******************************/
18434 static void alc662_mode2_unsol_event(struct hda_codec *codec,
18435 unsigned int res)
18437 switch (res >> 26) {
18438 case ALC880_HP_EVENT:
18439 alc662_f5z_speaker_automute(codec);
18440 break;
18441 case ALC880_MIC_EVENT:
18442 alc_mic_automute(codec);
18443 break;
18447 #define alc662_mode2_setup alc663_mode1_setup
18449 static void alc662_mode2_inithook(struct hda_codec *codec)
18451 alc662_f5z_speaker_automute(codec);
18452 alc_mic_automute(codec);
18454 /* ***************** Mode3 ******************************/
18455 static void alc663_mode3_unsol_event(struct hda_codec *codec,
18456 unsigned int res)
18458 switch (res >> 26) {
18459 case ALC880_HP_EVENT:
18460 alc663_two_hp_m1_speaker_automute(codec);
18461 break;
18462 case ALC880_MIC_EVENT:
18463 alc_mic_automute(codec);
18464 break;
18468 #define alc663_mode3_setup alc663_mode1_setup
18470 static void alc663_mode3_inithook(struct hda_codec *codec)
18472 alc663_two_hp_m1_speaker_automute(codec);
18473 alc_mic_automute(codec);
18475 /* ***************** Mode4 ******************************/
18476 static void alc663_mode4_unsol_event(struct hda_codec *codec,
18477 unsigned int res)
18479 switch (res >> 26) {
18480 case ALC880_HP_EVENT:
18481 alc663_21jd_two_speaker_automute(codec);
18482 break;
18483 case ALC880_MIC_EVENT:
18484 alc_mic_automute(codec);
18485 break;
18489 #define alc663_mode4_setup alc663_mode1_setup
18491 static void alc663_mode4_inithook(struct hda_codec *codec)
18493 alc663_21jd_two_speaker_automute(codec);
18494 alc_mic_automute(codec);
18496 /* ***************** Mode5 ******************************/
18497 static void alc663_mode5_unsol_event(struct hda_codec *codec,
18498 unsigned int res)
18500 switch (res >> 26) {
18501 case ALC880_HP_EVENT:
18502 alc663_15jd_two_speaker_automute(codec);
18503 break;
18504 case ALC880_MIC_EVENT:
18505 alc_mic_automute(codec);
18506 break;
18510 #define alc663_mode5_setup alc663_mode1_setup
18512 static void alc663_mode5_inithook(struct hda_codec *codec)
18514 alc663_15jd_two_speaker_automute(codec);
18515 alc_mic_automute(codec);
18517 /* ***************** Mode6 ******************************/
18518 static void alc663_mode6_unsol_event(struct hda_codec *codec,
18519 unsigned int res)
18521 switch (res >> 26) {
18522 case ALC880_HP_EVENT:
18523 alc663_two_hp_m2_speaker_automute(codec);
18524 break;
18525 case ALC880_MIC_EVENT:
18526 alc_mic_automute(codec);
18527 break;
18531 #define alc663_mode6_setup alc663_mode1_setup
18533 static void alc663_mode6_inithook(struct hda_codec *codec)
18535 alc663_two_hp_m2_speaker_automute(codec);
18536 alc_mic_automute(codec);
18539 /* ***************** Mode7 ******************************/
18540 static void alc663_mode7_unsol_event(struct hda_codec *codec,
18541 unsigned int res)
18543 switch (res >> 26) {
18544 case ALC880_HP_EVENT:
18545 alc663_two_hp_m7_speaker_automute(codec);
18546 break;
18547 case ALC880_MIC_EVENT:
18548 alc_mic_automute(codec);
18549 break;
18553 #define alc663_mode7_setup alc663_mode1_setup
18555 static void alc663_mode7_inithook(struct hda_codec *codec)
18557 alc663_two_hp_m7_speaker_automute(codec);
18558 alc_mic_automute(codec);
18561 /* ***************** Mode8 ******************************/
18562 static void alc663_mode8_unsol_event(struct hda_codec *codec,
18563 unsigned int res)
18565 switch (res >> 26) {
18566 case ALC880_HP_EVENT:
18567 alc663_two_hp_m8_speaker_automute(codec);
18568 break;
18569 case ALC880_MIC_EVENT:
18570 alc_mic_automute(codec);
18571 break;
18575 #define alc663_mode8_setup alc663_m51va_setup
18577 static void alc663_mode8_inithook(struct hda_codec *codec)
18579 alc663_two_hp_m8_speaker_automute(codec);
18580 alc_mic_automute(codec);
18583 static void alc663_g71v_hp_automute(struct hda_codec *codec)
18585 unsigned int present;
18586 unsigned char bits;
18588 present = snd_hda_jack_detect(codec, 0x21);
18589 bits = present ? HDA_AMP_MUTE : 0;
18590 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
18591 HDA_AMP_MUTE, bits);
18592 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18593 HDA_AMP_MUTE, bits);
18596 static void alc663_g71v_front_automute(struct hda_codec *codec)
18598 unsigned int present;
18599 unsigned char bits;
18601 present = snd_hda_jack_detect(codec, 0x15);
18602 bits = present ? HDA_AMP_MUTE : 0;
18603 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
18604 HDA_AMP_MUTE, bits);
18607 static void alc663_g71v_unsol_event(struct hda_codec *codec,
18608 unsigned int res)
18610 switch (res >> 26) {
18611 case ALC880_HP_EVENT:
18612 alc663_g71v_hp_automute(codec);
18613 break;
18614 case ALC880_FRONT_EVENT:
18615 alc663_g71v_front_automute(codec);
18616 break;
18617 case ALC880_MIC_EVENT:
18618 alc_mic_automute(codec);
18619 break;
18623 #define alc663_g71v_setup alc663_m51va_setup
18625 static void alc663_g71v_inithook(struct hda_codec *codec)
18627 alc663_g71v_front_automute(codec);
18628 alc663_g71v_hp_automute(codec);
18629 alc_mic_automute(codec);
18632 static void alc663_g50v_unsol_event(struct hda_codec *codec,
18633 unsigned int res)
18635 switch (res >> 26) {
18636 case ALC880_HP_EVENT:
18637 alc663_m51va_speaker_automute(codec);
18638 break;
18639 case ALC880_MIC_EVENT:
18640 alc_mic_automute(codec);
18641 break;
18645 #define alc663_g50v_setup alc663_m51va_setup
18647 static void alc663_g50v_inithook(struct hda_codec *codec)
18649 alc663_m51va_speaker_automute(codec);
18650 alc_mic_automute(codec);
18653 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18654 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18655 ALC262_HIPPO_MASTER_SWITCH,
18657 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18658 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18659 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18662 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18663 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18664 { } /* end */
18667 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18668 /* Master Playback automatically created from Speaker and Headphone */
18669 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18670 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18671 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18676 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18678 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18679 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18680 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18681 { } /* end */
18684 #ifdef CONFIG_SND_HDA_POWER_SAVE
18685 #define alc662_loopbacks alc880_loopbacks
18686 #endif
18689 /* pcm configuration: identical with ALC880 */
18690 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18691 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18692 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18693 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18696 * configuration and preset
18698 static const char * const alc662_models[ALC662_MODEL_LAST] = {
18699 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18700 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18701 [ALC662_3ST_6ch] = "3stack-6ch",
18702 [ALC662_5ST_DIG] = "6stack-dig",
18703 [ALC662_LENOVO_101E] = "lenovo-101e",
18704 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18705 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18706 [ALC662_ECS] = "ecs",
18707 [ALC663_ASUS_M51VA] = "m51va",
18708 [ALC663_ASUS_G71V] = "g71v",
18709 [ALC663_ASUS_H13] = "h13",
18710 [ALC663_ASUS_G50V] = "g50v",
18711 [ALC663_ASUS_MODE1] = "asus-mode1",
18712 [ALC662_ASUS_MODE2] = "asus-mode2",
18713 [ALC663_ASUS_MODE3] = "asus-mode3",
18714 [ALC663_ASUS_MODE4] = "asus-mode4",
18715 [ALC663_ASUS_MODE5] = "asus-mode5",
18716 [ALC663_ASUS_MODE6] = "asus-mode6",
18717 [ALC663_ASUS_MODE7] = "asus-mode7",
18718 [ALC663_ASUS_MODE8] = "asus-mode8",
18719 [ALC272_DELL] = "dell",
18720 [ALC272_DELL_ZM1] = "dell-zm1",
18721 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18722 [ALC662_AUTO] = "auto",
18725 static struct snd_pci_quirk alc662_cfg_tbl[] = {
18726 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18727 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18728 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18729 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18730 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18731 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18732 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18733 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18734 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18735 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18736 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18737 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18738 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18739 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18740 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18741 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18742 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18743 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18744 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18745 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18746 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18747 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18748 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18749 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18750 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18751 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18752 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18753 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18754 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18755 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18756 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18757 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18758 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18759 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18760 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18761 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18762 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18763 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18764 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18765 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18766 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18767 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18768 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18769 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18770 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18771 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18772 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18773 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18774 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18775 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18776 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18777 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18778 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18779 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18780 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18781 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18782 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18783 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18784 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18785 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18786 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18787 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18788 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18789 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18790 ALC662_3ST_6ch_DIG),
18791 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18792 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18793 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18794 ALC662_3ST_6ch_DIG),
18795 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18796 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18797 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18798 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18799 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18800 ALC662_3ST_6ch_DIG),
18801 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18802 ALC663_ASUS_H13),
18806 static struct alc_config_preset alc662_presets[] = {
18807 [ALC662_3ST_2ch_DIG] = {
18808 .mixers = { alc662_3ST_2ch_mixer },
18809 .init_verbs = { alc662_init_verbs },
18810 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18811 .dac_nids = alc662_dac_nids,
18812 .dig_out_nid = ALC662_DIGOUT_NID,
18813 .dig_in_nid = ALC662_DIGIN_NID,
18814 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18815 .channel_mode = alc662_3ST_2ch_modes,
18816 .input_mux = &alc662_capture_source,
18818 [ALC662_3ST_6ch_DIG] = {
18819 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18820 .init_verbs = { alc662_init_verbs },
18821 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18822 .dac_nids = alc662_dac_nids,
18823 .dig_out_nid = ALC662_DIGOUT_NID,
18824 .dig_in_nid = ALC662_DIGIN_NID,
18825 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18826 .channel_mode = alc662_3ST_6ch_modes,
18827 .need_dac_fix = 1,
18828 .input_mux = &alc662_capture_source,
18830 [ALC662_3ST_6ch] = {
18831 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18832 .init_verbs = { alc662_init_verbs },
18833 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18834 .dac_nids = alc662_dac_nids,
18835 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18836 .channel_mode = alc662_3ST_6ch_modes,
18837 .need_dac_fix = 1,
18838 .input_mux = &alc662_capture_source,
18840 [ALC662_5ST_DIG] = {
18841 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18842 .init_verbs = { alc662_init_verbs },
18843 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18844 .dac_nids = alc662_dac_nids,
18845 .dig_out_nid = ALC662_DIGOUT_NID,
18846 .dig_in_nid = ALC662_DIGIN_NID,
18847 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18848 .channel_mode = alc662_5stack_modes,
18849 .input_mux = &alc662_capture_source,
18851 [ALC662_LENOVO_101E] = {
18852 .mixers = { alc662_lenovo_101e_mixer },
18853 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
18854 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18855 .dac_nids = alc662_dac_nids,
18856 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18857 .channel_mode = alc662_3ST_2ch_modes,
18858 .input_mux = &alc662_lenovo_101e_capture_source,
18859 .unsol_event = alc662_lenovo_101e_unsol_event,
18860 .init_hook = alc662_lenovo_101e_all_automute,
18862 [ALC662_ASUS_EEEPC_P701] = {
18863 .mixers = { alc662_eeepc_p701_mixer },
18864 .init_verbs = { alc662_init_verbs,
18865 alc662_eeepc_sue_init_verbs },
18866 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18867 .dac_nids = alc662_dac_nids,
18868 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18869 .channel_mode = alc662_3ST_2ch_modes,
18870 .unsol_event = alc662_eeepc_unsol_event,
18871 .setup = alc662_eeepc_setup,
18872 .init_hook = alc662_eeepc_inithook,
18874 [ALC662_ASUS_EEEPC_EP20] = {
18875 .mixers = { alc662_eeepc_ep20_mixer,
18876 alc662_chmode_mixer },
18877 .init_verbs = { alc662_init_verbs,
18878 alc662_eeepc_ep20_sue_init_verbs },
18879 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18880 .dac_nids = alc662_dac_nids,
18881 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18882 .channel_mode = alc662_3ST_6ch_modes,
18883 .input_mux = &alc662_lenovo_101e_capture_source,
18884 .unsol_event = alc662_eeepc_unsol_event,
18885 .setup = alc662_eeepc_ep20_setup,
18886 .init_hook = alc662_eeepc_ep20_inithook,
18888 [ALC662_ECS] = {
18889 .mixers = { alc662_ecs_mixer },
18890 .init_verbs = { alc662_init_verbs,
18891 alc662_ecs_init_verbs },
18892 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18893 .dac_nids = alc662_dac_nids,
18894 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18895 .channel_mode = alc662_3ST_2ch_modes,
18896 .unsol_event = alc662_eeepc_unsol_event,
18897 .setup = alc662_eeepc_setup,
18898 .init_hook = alc662_eeepc_inithook,
18900 [ALC663_ASUS_M51VA] = {
18901 .mixers = { alc663_m51va_mixer },
18902 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18903 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18904 .dac_nids = alc662_dac_nids,
18905 .dig_out_nid = ALC662_DIGOUT_NID,
18906 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18907 .channel_mode = alc662_3ST_2ch_modes,
18908 .unsol_event = alc663_m51va_unsol_event,
18909 .setup = alc663_m51va_setup,
18910 .init_hook = alc663_m51va_inithook,
18912 [ALC663_ASUS_G71V] = {
18913 .mixers = { alc663_g71v_mixer },
18914 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
18915 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18916 .dac_nids = alc662_dac_nids,
18917 .dig_out_nid = ALC662_DIGOUT_NID,
18918 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18919 .channel_mode = alc662_3ST_2ch_modes,
18920 .unsol_event = alc663_g71v_unsol_event,
18921 .setup = alc663_g71v_setup,
18922 .init_hook = alc663_g71v_inithook,
18924 [ALC663_ASUS_H13] = {
18925 .mixers = { alc663_m51va_mixer },
18926 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
18927 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18928 .dac_nids = alc662_dac_nids,
18929 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18930 .channel_mode = alc662_3ST_2ch_modes,
18931 .unsol_event = alc663_m51va_unsol_event,
18932 .init_hook = alc663_m51va_inithook,
18934 [ALC663_ASUS_G50V] = {
18935 .mixers = { alc663_g50v_mixer },
18936 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18937 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18938 .dac_nids = alc662_dac_nids,
18939 .dig_out_nid = ALC662_DIGOUT_NID,
18940 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18941 .channel_mode = alc662_3ST_6ch_modes,
18942 .input_mux = &alc663_capture_source,
18943 .unsol_event = alc663_g50v_unsol_event,
18944 .setup = alc663_g50v_setup,
18945 .init_hook = alc663_g50v_inithook,
18947 [ALC663_ASUS_MODE1] = {
18948 .mixers = { alc663_m51va_mixer },
18949 .cap_mixer = alc662_auto_capture_mixer,
18950 .init_verbs = { alc662_init_verbs,
18951 alc663_21jd_amic_init_verbs },
18952 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18953 .hp_nid = 0x03,
18954 .dac_nids = alc662_dac_nids,
18955 .dig_out_nid = ALC662_DIGOUT_NID,
18956 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18957 .channel_mode = alc662_3ST_2ch_modes,
18958 .unsol_event = alc663_mode1_unsol_event,
18959 .setup = alc663_mode1_setup,
18960 .init_hook = alc663_mode1_inithook,
18962 [ALC662_ASUS_MODE2] = {
18963 .mixers = { alc662_1bjd_mixer },
18964 .cap_mixer = alc662_auto_capture_mixer,
18965 .init_verbs = { alc662_init_verbs,
18966 alc662_1bjd_amic_init_verbs },
18967 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18968 .dac_nids = alc662_dac_nids,
18969 .dig_out_nid = ALC662_DIGOUT_NID,
18970 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18971 .channel_mode = alc662_3ST_2ch_modes,
18972 .unsol_event = alc662_mode2_unsol_event,
18973 .setup = alc662_mode2_setup,
18974 .init_hook = alc662_mode2_inithook,
18976 [ALC663_ASUS_MODE3] = {
18977 .mixers = { alc663_two_hp_m1_mixer },
18978 .cap_mixer = alc662_auto_capture_mixer,
18979 .init_verbs = { alc662_init_verbs,
18980 alc663_two_hp_amic_m1_init_verbs },
18981 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18982 .hp_nid = 0x03,
18983 .dac_nids = alc662_dac_nids,
18984 .dig_out_nid = ALC662_DIGOUT_NID,
18985 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18986 .channel_mode = alc662_3ST_2ch_modes,
18987 .unsol_event = alc663_mode3_unsol_event,
18988 .setup = alc663_mode3_setup,
18989 .init_hook = alc663_mode3_inithook,
18991 [ALC663_ASUS_MODE4] = {
18992 .mixers = { alc663_asus_21jd_clfe_mixer },
18993 .cap_mixer = alc662_auto_capture_mixer,
18994 .init_verbs = { alc662_init_verbs,
18995 alc663_21jd_amic_init_verbs},
18996 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18997 .hp_nid = 0x03,
18998 .dac_nids = alc662_dac_nids,
18999 .dig_out_nid = ALC662_DIGOUT_NID,
19000 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19001 .channel_mode = alc662_3ST_2ch_modes,
19002 .unsol_event = alc663_mode4_unsol_event,
19003 .setup = alc663_mode4_setup,
19004 .init_hook = alc663_mode4_inithook,
19006 [ALC663_ASUS_MODE5] = {
19007 .mixers = { alc663_asus_15jd_clfe_mixer },
19008 .cap_mixer = alc662_auto_capture_mixer,
19009 .init_verbs = { alc662_init_verbs,
19010 alc663_15jd_amic_init_verbs },
19011 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19012 .hp_nid = 0x03,
19013 .dac_nids = alc662_dac_nids,
19014 .dig_out_nid = ALC662_DIGOUT_NID,
19015 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19016 .channel_mode = alc662_3ST_2ch_modes,
19017 .unsol_event = alc663_mode5_unsol_event,
19018 .setup = alc663_mode5_setup,
19019 .init_hook = alc663_mode5_inithook,
19021 [ALC663_ASUS_MODE6] = {
19022 .mixers = { alc663_two_hp_m2_mixer },
19023 .cap_mixer = alc662_auto_capture_mixer,
19024 .init_verbs = { alc662_init_verbs,
19025 alc663_two_hp_amic_m2_init_verbs },
19026 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19027 .hp_nid = 0x03,
19028 .dac_nids = alc662_dac_nids,
19029 .dig_out_nid = ALC662_DIGOUT_NID,
19030 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19031 .channel_mode = alc662_3ST_2ch_modes,
19032 .unsol_event = alc663_mode6_unsol_event,
19033 .setup = alc663_mode6_setup,
19034 .init_hook = alc663_mode6_inithook,
19036 [ALC663_ASUS_MODE7] = {
19037 .mixers = { alc663_mode7_mixer },
19038 .cap_mixer = alc662_auto_capture_mixer,
19039 .init_verbs = { alc662_init_verbs,
19040 alc663_mode7_init_verbs },
19041 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19042 .hp_nid = 0x03,
19043 .dac_nids = alc662_dac_nids,
19044 .dig_out_nid = ALC662_DIGOUT_NID,
19045 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19046 .channel_mode = alc662_3ST_2ch_modes,
19047 .unsol_event = alc663_mode7_unsol_event,
19048 .setup = alc663_mode7_setup,
19049 .init_hook = alc663_mode7_inithook,
19051 [ALC663_ASUS_MODE8] = {
19052 .mixers = { alc663_mode8_mixer },
19053 .cap_mixer = alc662_auto_capture_mixer,
19054 .init_verbs = { alc662_init_verbs,
19055 alc663_mode8_init_verbs },
19056 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
19057 .hp_nid = 0x03,
19058 .dac_nids = alc662_dac_nids,
19059 .dig_out_nid = ALC662_DIGOUT_NID,
19060 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19061 .channel_mode = alc662_3ST_2ch_modes,
19062 .unsol_event = alc663_mode8_unsol_event,
19063 .setup = alc663_mode8_setup,
19064 .init_hook = alc663_mode8_inithook,
19066 [ALC272_DELL] = {
19067 .mixers = { alc663_m51va_mixer },
19068 .cap_mixer = alc272_auto_capture_mixer,
19069 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
19070 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19071 .dac_nids = alc662_dac_nids,
19072 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19073 .adc_nids = alc272_adc_nids,
19074 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
19075 .capsrc_nids = alc272_capsrc_nids,
19076 .channel_mode = alc662_3ST_2ch_modes,
19077 .unsol_event = alc663_m51va_unsol_event,
19078 .setup = alc663_m51va_setup,
19079 .init_hook = alc663_m51va_inithook,
19081 [ALC272_DELL_ZM1] = {
19082 .mixers = { alc663_m51va_mixer },
19083 .cap_mixer = alc662_auto_capture_mixer,
19084 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
19085 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19086 .dac_nids = alc662_dac_nids,
19087 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19088 .adc_nids = alc662_adc_nids,
19089 .num_adc_nids = 1,
19090 .capsrc_nids = alc662_capsrc_nids,
19091 .channel_mode = alc662_3ST_2ch_modes,
19092 .unsol_event = alc663_m51va_unsol_event,
19093 .setup = alc663_m51va_setup,
19094 .init_hook = alc663_m51va_inithook,
19096 [ALC272_SAMSUNG_NC10] = {
19097 .mixers = { alc272_nc10_mixer },
19098 .init_verbs = { alc662_init_verbs,
19099 alc663_21jd_amic_init_verbs },
19100 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
19101 .dac_nids = alc272_dac_nids,
19102 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
19103 .channel_mode = alc662_3ST_2ch_modes,
19104 /*.input_mux = &alc272_nc10_capture_source,*/
19105 .unsol_event = alc663_mode4_unsol_event,
19106 .setup = alc663_mode4_setup,
19107 .init_hook = alc663_mode4_inithook,
19113 * BIOS auto configuration
19116 /* convert from MIX nid to DAC */
19117 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
19119 if (nid == 0x0f)
19120 return 0x02;
19121 else if (nid >= 0x0c && nid <= 0x0e)
19122 return nid - 0x0c + 0x02;
19123 else if (nid == 0x26) /* ALC887-VD has this DAC too */
19124 return 0x25;
19125 else
19126 return 0;
19129 /* get MIX nid connected to the given pin targeted to DAC */
19130 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
19131 hda_nid_t dac)
19133 hda_nid_t mix[5];
19134 int i, num;
19136 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
19137 for (i = 0; i < num; i++) {
19138 if (alc662_mix_to_dac(mix[i]) == dac)
19139 return mix[i];
19141 return 0;
19144 /* look for an empty DAC slot */
19145 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
19147 struct alc_spec *spec = codec->spec;
19148 hda_nid_t srcs[5];
19149 int i, j, num;
19151 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
19152 if (num < 0)
19153 return 0;
19154 for (i = 0; i < num; i++) {
19155 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
19156 if (!nid)
19157 continue;
19158 for (j = 0; j < spec->multiout.num_dacs; j++)
19159 if (spec->multiout.dac_nids[j] == nid)
19160 break;
19161 if (j >= spec->multiout.num_dacs)
19162 return nid;
19164 return 0;
19167 /* fill in the dac_nids table from the parsed pin configuration */
19168 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19169 const struct auto_pin_cfg *cfg)
19171 struct alc_spec *spec = codec->spec;
19172 int i;
19173 hda_nid_t dac;
19175 spec->multiout.dac_nids = spec->private_dac_nids;
19176 for (i = 0; i < cfg->line_outs; i++) {
19177 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
19178 if (!dac)
19179 continue;
19180 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19182 return 0;
19185 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19186 hda_nid_t nid, int idx, unsigned int chs)
19188 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19189 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19192 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19193 hda_nid_t nid, int idx, unsigned int chs)
19195 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19196 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19199 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19200 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19201 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19202 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19203 #define alc662_add_stereo_vol(spec, pfx, nid) \
19204 alc662_add_vol_ctl(spec, pfx, nid, 3)
19205 #define alc662_add_stereo_sw(spec, pfx, nid) \
19206 alc662_add_sw_ctl(spec, pfx, nid, 3)
19208 /* add playback controls from the parsed DAC table */
19209 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19210 const struct auto_pin_cfg *cfg)
19212 struct alc_spec *spec = codec->spec;
19213 static const char * const chname[4] = {
19214 "Front", "Surround", NULL /*CLFE*/, "Side"
19216 const char *pfx = alc_get_line_out_pfx(cfg, true);
19217 hda_nid_t nid, mix;
19218 int i, err;
19220 for (i = 0; i < cfg->line_outs; i++) {
19221 nid = spec->multiout.dac_nids[i];
19222 if (!nid)
19223 continue;
19224 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19225 if (!mix)
19226 continue;
19227 if (!pfx && i == 2) {
19228 /* Center/LFE */
19229 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19230 if (err < 0)
19231 return err;
19232 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19233 if (err < 0)
19234 return err;
19235 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19236 if (err < 0)
19237 return err;
19238 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19239 if (err < 0)
19240 return err;
19241 } else {
19242 const char *name = pfx;
19243 if (!name)
19244 name = chname[i];
19245 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
19246 if (err < 0)
19247 return err;
19248 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
19249 if (err < 0)
19250 return err;
19253 return 0;
19256 /* add playback controls for speaker and HP outputs */
19257 /* return DAC nid if any new DAC is assigned */
19258 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19259 const char *pfx)
19261 struct alc_spec *spec = codec->spec;
19262 hda_nid_t nid, mix;
19263 int err;
19265 if (!pin)
19266 return 0;
19267 nid = alc662_look_for_dac(codec, pin);
19268 if (!nid) {
19269 /* the corresponding DAC is already occupied */
19270 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19271 return 0; /* no way */
19272 /* create a switch only */
19273 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19274 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19277 mix = alc662_dac_to_mix(codec, pin, nid);
19278 if (!mix)
19279 return 0;
19280 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19281 if (err < 0)
19282 return err;
19283 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19284 if (err < 0)
19285 return err;
19286 return nid;
19289 /* create playback/capture controls for input pins */
19290 #define alc662_auto_create_input_ctls \
19291 alc882_auto_create_input_ctls
19293 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19294 hda_nid_t nid, int pin_type,
19295 hda_nid_t dac)
19297 int i, num;
19298 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19300 alc_set_pin_output(codec, nid, pin_type);
19301 /* need the manual connection? */
19302 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19303 if (num <= 1)
19304 return;
19305 for (i = 0; i < num; i++) {
19306 if (alc662_mix_to_dac(srcs[i]) != dac)
19307 continue;
19308 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
19309 return;
19313 static void alc662_auto_init_multi_out(struct hda_codec *codec)
19315 struct alc_spec *spec = codec->spec;
19316 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19317 int i;
19319 for (i = 0; i <= HDA_SIDE; i++) {
19320 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19321 if (nid)
19322 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19323 spec->multiout.dac_nids[i]);
19327 static void alc662_auto_init_hp_out(struct hda_codec *codec)
19329 struct alc_spec *spec = codec->spec;
19330 hda_nid_t pin;
19332 pin = spec->autocfg.hp_pins[0];
19333 if (pin)
19334 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19335 spec->multiout.hp_nid);
19336 pin = spec->autocfg.speaker_pins[0];
19337 if (pin)
19338 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19339 spec->multiout.extra_out_nid[0]);
19342 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19344 static void alc662_auto_init_analog_input(struct hda_codec *codec)
19346 struct alc_spec *spec = codec->spec;
19347 struct auto_pin_cfg *cfg = &spec->autocfg;
19348 int i;
19350 for (i = 0; i < cfg->num_inputs; i++) {
19351 hda_nid_t nid = cfg->inputs[i].pin;
19352 if (alc_is_input_pin(codec, nid)) {
19353 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19354 if (nid != ALC662_PIN_CD_NID &&
19355 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19356 snd_hda_codec_write(codec, nid, 0,
19357 AC_VERB_SET_AMP_GAIN_MUTE,
19358 AMP_OUT_MUTE);
19363 #define alc662_auto_init_input_src alc882_auto_init_input_src
19365 static int alc662_parse_auto_config(struct hda_codec *codec)
19367 struct alc_spec *spec = codec->spec;
19368 int err;
19369 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19371 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19372 alc662_ignore);
19373 if (err < 0)
19374 return err;
19375 if (!spec->autocfg.line_outs)
19376 return 0; /* can't find valid BIOS pin config */
19378 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19379 if (err < 0)
19380 return err;
19381 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19382 if (err < 0)
19383 return err;
19384 err = alc662_auto_create_extra_out(codec,
19385 spec->autocfg.speaker_pins[0],
19386 "Speaker");
19387 if (err < 0)
19388 return err;
19389 if (err)
19390 spec->multiout.extra_out_nid[0] = err;
19391 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19392 "Headphone");
19393 if (err < 0)
19394 return err;
19395 if (err)
19396 spec->multiout.hp_nid = err;
19397 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19398 if (err < 0)
19399 return err;
19401 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19403 alc_auto_parse_digital(codec);
19405 if (spec->kctls.list)
19406 add_mixer(spec, spec->kctls.list);
19408 spec->num_mux_defs = 1;
19409 spec->input_mux = &spec->private_imux[0];
19411 add_verb(spec, alc662_init_verbs);
19412 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19413 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19414 add_verb(spec, alc663_init_verbs);
19416 if (codec->vendor_id == 0x10ec0272)
19417 add_verb(spec, alc272_init_verbs);
19419 err = alc_auto_add_mic_boost(codec);
19420 if (err < 0)
19421 return err;
19423 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19424 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19425 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19426 else
19427 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19429 return 1;
19432 /* additional initialization for auto-configuration model */
19433 static void alc662_auto_init(struct hda_codec *codec)
19435 struct alc_spec *spec = codec->spec;
19436 alc662_auto_init_multi_out(codec);
19437 alc662_auto_init_hp_out(codec);
19438 alc662_auto_init_analog_input(codec);
19439 alc662_auto_init_input_src(codec);
19440 alc_auto_init_digital(codec);
19441 if (spec->unsol_event)
19442 alc_inithook(codec);
19445 static void alc272_fixup_mario(struct hda_codec *codec,
19446 const struct alc_fixup *fix, int action)
19448 if (action != ALC_FIXUP_ACT_PROBE)
19449 return;
19450 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19451 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19452 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19453 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19454 (0 << AC_AMPCAP_MUTE_SHIFT)))
19455 printk(KERN_WARNING
19456 "hda_codec: failed to override amp caps for NID 0x2\n");
19459 enum {
19460 ALC662_FIXUP_ASPIRE,
19461 ALC662_FIXUP_IDEAPAD,
19462 ALC272_FIXUP_MARIO,
19463 ALC662_FIXUP_CZC_P10T,
19466 static const struct alc_fixup alc662_fixups[] = {
19467 [ALC662_FIXUP_ASPIRE] = {
19468 .type = ALC_FIXUP_PINS,
19469 .v.pins = (const struct alc_pincfg[]) {
19470 { 0x15, 0x99130112 }, /* subwoofer */
19474 [ALC662_FIXUP_IDEAPAD] = {
19475 .type = ALC_FIXUP_PINS,
19476 .v.pins = (const struct alc_pincfg[]) {
19477 { 0x17, 0x99130112 }, /* subwoofer */
19481 [ALC272_FIXUP_MARIO] = {
19482 .type = ALC_FIXUP_FUNC,
19483 .v.func = alc272_fixup_mario,
19485 [ALC662_FIXUP_CZC_P10T] = {
19486 .type = ALC_FIXUP_VERBS,
19487 .v.verbs = (const struct hda_verb[]) {
19488 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19494 static struct snd_pci_quirk alc662_fixup_tbl[] = {
19495 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19496 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19497 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19498 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19499 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19503 static const struct alc_model_fixup alc662_fixup_models[] = {
19504 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19509 static int patch_alc662(struct hda_codec *codec)
19511 struct alc_spec *spec;
19512 int err, board_config;
19513 int coef;
19515 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19516 if (!spec)
19517 return -ENOMEM;
19519 codec->spec = spec;
19521 alc_auto_parse_customize_define(codec);
19523 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19525 coef = alc_read_coef_idx(codec, 0);
19526 if (coef == 0x8020 || coef == 0x8011)
19527 alc_codec_rename(codec, "ALC661");
19528 else if (coef & (1 << 14) &&
19529 codec->bus->pci->subsystem_vendor == 0x1025 &&
19530 spec->cdefine.platform_type == 1)
19531 alc_codec_rename(codec, "ALC272X");
19532 else if (coef == 0x4011)
19533 alc_codec_rename(codec, "ALC656");
19535 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19536 alc662_models,
19537 alc662_cfg_tbl);
19538 if (board_config < 0) {
19539 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19540 codec->chip_name);
19541 board_config = ALC662_AUTO;
19544 if (board_config == ALC662_AUTO) {
19545 alc_pick_fixup(codec, alc662_fixup_models,
19546 alc662_fixup_tbl, alc662_fixups);
19547 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19548 /* automatic parse from the BIOS config */
19549 err = alc662_parse_auto_config(codec);
19550 if (err < 0) {
19551 alc_free(codec);
19552 return err;
19553 } else if (!err) {
19554 printk(KERN_INFO
19555 "hda_codec: Cannot set up configuration "
19556 "from BIOS. Using base mode...\n");
19557 board_config = ALC662_3ST_2ch_DIG;
19561 if (has_cdefine_beep(codec)) {
19562 err = snd_hda_attach_beep_device(codec, 0x1);
19563 if (err < 0) {
19564 alc_free(codec);
19565 return err;
19569 if (board_config != ALC662_AUTO)
19570 setup_preset(codec, &alc662_presets[board_config]);
19572 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19573 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19575 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19576 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19578 if (!spec->adc_nids) {
19579 spec->adc_nids = alc662_adc_nids;
19580 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19582 if (!spec->capsrc_nids)
19583 spec->capsrc_nids = alc662_capsrc_nids;
19585 if (!spec->cap_mixer)
19586 set_capture_mixer(codec);
19588 if (has_cdefine_beep(codec)) {
19589 switch (codec->vendor_id) {
19590 case 0x10ec0662:
19591 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19592 break;
19593 case 0x10ec0272:
19594 case 0x10ec0663:
19595 case 0x10ec0665:
19596 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19597 break;
19598 case 0x10ec0273:
19599 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19600 break;
19603 spec->vmaster_nid = 0x02;
19605 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19607 codec->patch_ops = alc_patch_ops;
19608 if (board_config == ALC662_AUTO)
19609 spec->init_hook = alc662_auto_init;
19611 alc_init_jacks(codec);
19613 #ifdef CONFIG_SND_HDA_POWER_SAVE
19614 if (!spec->loopback.amplist)
19615 spec->loopback.amplist = alc662_loopbacks;
19616 #endif
19618 return 0;
19621 static int patch_alc888(struct hda_codec *codec)
19623 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19624 kfree(codec->chip_name);
19625 if (codec->vendor_id == 0x10ec0887)
19626 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19627 else
19628 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19629 if (!codec->chip_name) {
19630 alc_free(codec);
19631 return -ENOMEM;
19633 return patch_alc662(codec);
19635 return patch_alc882(codec);
19639 * ALC680 support
19641 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19642 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19643 #define alc680_modes alc260_modes
19645 static hda_nid_t alc680_dac_nids[3] = {
19646 /* Lout1, Lout2, hp */
19647 0x02, 0x03, 0x04
19650 static hda_nid_t alc680_adc_nids[3] = {
19651 /* ADC0-2 */
19652 /* DMIC, MIC, Line-in*/
19653 0x07, 0x08, 0x09
19657 * Analog capture ADC cgange
19659 static void alc680_rec_autoswitch(struct hda_codec *codec)
19661 struct alc_spec *spec = codec->spec;
19662 struct auto_pin_cfg *cfg = &spec->autocfg;
19663 int pin_found = 0;
19664 int type_found = AUTO_PIN_LAST;
19665 hda_nid_t nid;
19666 int i;
19668 for (i = 0; i < cfg->num_inputs; i++) {
19669 nid = cfg->inputs[i].pin;
19670 if (!(snd_hda_query_pin_caps(codec, nid) &
19671 AC_PINCAP_PRES_DETECT))
19672 continue;
19673 if (snd_hda_jack_detect(codec, nid)) {
19674 if (cfg->inputs[i].type < type_found) {
19675 type_found = cfg->inputs[i].type;
19676 pin_found = nid;
19681 nid = 0x07;
19682 if (pin_found)
19683 snd_hda_get_connections(codec, pin_found, &nid, 1);
19685 if (nid != spec->cur_adc)
19686 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19687 spec->cur_adc = nid;
19688 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19689 spec->cur_adc_format);
19692 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19693 struct hda_codec *codec,
19694 unsigned int stream_tag,
19695 unsigned int format,
19696 struct snd_pcm_substream *substream)
19698 struct alc_spec *spec = codec->spec;
19700 spec->cur_adc = 0x07;
19701 spec->cur_adc_stream_tag = stream_tag;
19702 spec->cur_adc_format = format;
19704 alc680_rec_autoswitch(codec);
19705 return 0;
19708 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19709 struct hda_codec *codec,
19710 struct snd_pcm_substream *substream)
19712 snd_hda_codec_cleanup_stream(codec, 0x07);
19713 snd_hda_codec_cleanup_stream(codec, 0x08);
19714 snd_hda_codec_cleanup_stream(codec, 0x09);
19715 return 0;
19718 static struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19719 .substreams = 1, /* can be overridden */
19720 .channels_min = 2,
19721 .channels_max = 2,
19722 /* NID is set in alc_build_pcms */
19723 .ops = {
19724 .prepare = alc680_capture_pcm_prepare,
19725 .cleanup = alc680_capture_pcm_cleanup
19729 static struct snd_kcontrol_new alc680_base_mixer[] = {
19730 /* output mixer control */
19731 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19732 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19734 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19735 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19736 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19737 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19741 static struct hda_bind_ctls alc680_bind_cap_vol = {
19742 .ops = &snd_hda_bind_vol,
19743 .values = {
19744 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19746 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19751 static struct hda_bind_ctls alc680_bind_cap_switch = {
19752 .ops = &snd_hda_bind_sw,
19753 .values = {
19754 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19755 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19756 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19761 static struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19762 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19763 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19764 { } /* end */
19768 * generic initialization of ADC, input mixers and output mixers
19770 static struct hda_verb alc680_init_verbs[] = {
19771 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19772 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19773 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19775 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19777 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19778 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19779 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19782 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19783 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19784 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19785 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19788 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19789 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19790 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19795 /* toggle speaker-output according to the hp-jack state */
19796 static void alc680_base_setup(struct hda_codec *codec)
19798 struct alc_spec *spec = codec->spec;
19800 spec->autocfg.hp_pins[0] = 0x16;
19801 spec->autocfg.speaker_pins[0] = 0x14;
19802 spec->autocfg.speaker_pins[1] = 0x15;
19803 spec->autocfg.num_inputs = 2;
19804 spec->autocfg.inputs[0].pin = 0x18;
19805 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19806 spec->autocfg.inputs[1].pin = 0x19;
19807 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19810 static void alc680_unsol_event(struct hda_codec *codec,
19811 unsigned int res)
19813 if ((res >> 26) == ALC880_HP_EVENT)
19814 alc_automute_amp(codec);
19815 if ((res >> 26) == ALC880_MIC_EVENT)
19816 alc680_rec_autoswitch(codec);
19819 static void alc680_inithook(struct hda_codec *codec)
19821 alc_automute_amp(codec);
19822 alc680_rec_autoswitch(codec);
19825 /* create input playback/capture controls for the given pin */
19826 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19827 const char *ctlname, int idx)
19829 hda_nid_t dac;
19830 int err;
19832 switch (nid) {
19833 case 0x14:
19834 dac = 0x02;
19835 break;
19836 case 0x15:
19837 dac = 0x03;
19838 break;
19839 case 0x16:
19840 dac = 0x04;
19841 break;
19842 default:
19843 return 0;
19845 if (spec->multiout.dac_nids[0] != dac &&
19846 spec->multiout.dac_nids[1] != dac) {
19847 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19848 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19849 HDA_OUTPUT));
19850 if (err < 0)
19851 return err;
19853 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19854 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19856 if (err < 0)
19857 return err;
19858 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
19861 return 0;
19864 /* add playback controls from the parsed DAC table */
19865 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19866 const struct auto_pin_cfg *cfg)
19868 hda_nid_t nid;
19869 int err;
19871 spec->multiout.dac_nids = spec->private_dac_nids;
19873 nid = cfg->line_out_pins[0];
19874 if (nid) {
19875 const char *name;
19876 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19877 name = "Speaker";
19878 else
19879 name = "Front";
19880 err = alc680_new_analog_output(spec, nid, name, 0);
19881 if (err < 0)
19882 return err;
19885 nid = cfg->speaker_pins[0];
19886 if (nid) {
19887 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19888 if (err < 0)
19889 return err;
19891 nid = cfg->hp_pins[0];
19892 if (nid) {
19893 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19894 if (err < 0)
19895 return err;
19898 return 0;
19901 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19902 hda_nid_t nid, int pin_type)
19904 alc_set_pin_output(codec, nid, pin_type);
19907 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19909 struct alc_spec *spec = codec->spec;
19910 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19911 if (nid) {
19912 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19913 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19917 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19919 struct alc_spec *spec = codec->spec;
19920 hda_nid_t pin;
19922 pin = spec->autocfg.hp_pins[0];
19923 if (pin)
19924 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19925 pin = spec->autocfg.speaker_pins[0];
19926 if (pin)
19927 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19930 /* pcm configuration: identical with ALC880 */
19931 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19932 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19933 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19934 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19935 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19938 * BIOS auto configuration
19940 static int alc680_parse_auto_config(struct hda_codec *codec)
19942 struct alc_spec *spec = codec->spec;
19943 int err;
19944 static hda_nid_t alc680_ignore[] = { 0 };
19946 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19947 alc680_ignore);
19948 if (err < 0)
19949 return err;
19951 if (!spec->autocfg.line_outs) {
19952 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19953 spec->multiout.max_channels = 2;
19954 spec->no_analog = 1;
19955 goto dig_only;
19957 return 0; /* can't find valid BIOS pin config */
19959 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19960 if (err < 0)
19961 return err;
19963 spec->multiout.max_channels = 2;
19965 dig_only:
19966 /* digital only support output */
19967 alc_auto_parse_digital(codec);
19968 if (spec->kctls.list)
19969 add_mixer(spec, spec->kctls.list);
19971 add_verb(spec, alc680_init_verbs);
19973 err = alc_auto_add_mic_boost(codec);
19974 if (err < 0)
19975 return err;
19977 return 1;
19980 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19982 /* init callback for auto-configuration model -- overriding the default init */
19983 static void alc680_auto_init(struct hda_codec *codec)
19985 struct alc_spec *spec = codec->spec;
19986 alc680_auto_init_multi_out(codec);
19987 alc680_auto_init_hp_out(codec);
19988 alc680_auto_init_analog_input(codec);
19989 alc_auto_init_digital(codec);
19990 if (spec->unsol_event)
19991 alc_inithook(codec);
19995 * configuration and preset
19997 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19998 [ALC680_BASE] = "base",
19999 [ALC680_AUTO] = "auto",
20002 static struct snd_pci_quirk alc680_cfg_tbl[] = {
20003 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20007 static struct alc_config_preset alc680_presets[] = {
20008 [ALC680_BASE] = {
20009 .mixers = { alc680_base_mixer },
20010 .cap_mixer = alc680_master_capture_mixer,
20011 .init_verbs = { alc680_init_verbs },
20012 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20013 .dac_nids = alc680_dac_nids,
20014 .dig_out_nid = ALC680_DIGOUT_NID,
20015 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20016 .channel_mode = alc680_modes,
20017 .unsol_event = alc680_unsol_event,
20018 .setup = alc680_base_setup,
20019 .init_hook = alc680_inithook,
20024 static int patch_alc680(struct hda_codec *codec)
20026 struct alc_spec *spec;
20027 int board_config;
20028 int err;
20030 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20031 if (spec == NULL)
20032 return -ENOMEM;
20034 codec->spec = spec;
20036 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20037 alc680_models,
20038 alc680_cfg_tbl);
20040 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20041 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20042 codec->chip_name);
20043 board_config = ALC680_AUTO;
20046 if (board_config == ALC680_AUTO) {
20047 /* automatic parse from the BIOS config */
20048 err = alc680_parse_auto_config(codec);
20049 if (err < 0) {
20050 alc_free(codec);
20051 return err;
20052 } else if (!err) {
20053 printk(KERN_INFO
20054 "hda_codec: Cannot set up configuration "
20055 "from BIOS. Using base mode...\n");
20056 board_config = ALC680_BASE;
20060 if (board_config != ALC680_AUTO)
20061 setup_preset(codec, &alc680_presets[board_config]);
20063 spec->stream_analog_playback = &alc680_pcm_analog_playback;
20064 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20065 spec->stream_digital_playback = &alc680_pcm_digital_playback;
20066 spec->stream_digital_capture = &alc680_pcm_digital_capture;
20068 if (!spec->adc_nids) {
20069 spec->adc_nids = alc680_adc_nids;
20070 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20073 if (!spec->cap_mixer)
20074 set_capture_mixer(codec);
20076 spec->vmaster_nid = 0x02;
20078 codec->patch_ops = alc_patch_ops;
20079 if (board_config == ALC680_AUTO)
20080 spec->init_hook = alc680_auto_init;
20082 return 0;
20086 * patch entries
20088 static struct hda_codec_preset snd_hda_preset_realtek[] = {
20089 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20090 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20091 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20092 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20093 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20094 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20095 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20096 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20097 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20098 .patch = patch_alc861 },
20099 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20100 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20101 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20102 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20103 .patch = patch_alc882 },
20104 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20105 .patch = patch_alc662 },
20106 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20107 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20108 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20109 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20110 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20111 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20112 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20113 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20114 .patch = patch_alc882 },
20115 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20116 .patch = patch_alc882 },
20117 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20118 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20119 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20120 .patch = patch_alc882 },
20121 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20122 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20123 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20124 {} /* terminator */
20127 MODULE_ALIAS("snd-hda-codec-id:10ec*");
20129 MODULE_LICENSE("GPL");
20130 MODULE_DESCRIPTION("Realtek HD-audio codec");
20132 static struct hda_codec_preset_list realtek_list = {
20133 .preset = snd_hda_preset_realtek,
20134 .owner = THIS_MODULE,
20137 static int __init patch_realtek_init(void)
20139 return snd_hda_add_codec_preset(&realtek_list);
20142 static void __exit patch_realtek_exit(void)
20144 snd_hda_delete_codec_preset(&realtek_list);
20147 module_init(patch_realtek_init)
20148 module_exit(patch_realtek_exit)