ALSA: hda: Use ALC880_F1734 quirk for Fujitsu Siemens AMILO Xi 1526
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / pci / hda / patch_realtek.c
blobb486daa17bd0b4df62cd7e4b56928dc093259fe8
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
4 * HD audio interface patch for ALC 260/880/882 codecs
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_beep.h"
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
40 /* ALC880 board config type */
41 enum {
42 ALC880_3ST,
43 ALC880_3ST_DIG,
44 ALC880_5ST,
45 ALC880_5ST_DIG,
46 ALC880_W810,
47 ALC880_Z71V,
48 ALC880_6ST,
49 ALC880_6ST_DIG,
50 ALC880_F1734,
51 ALC880_ASUS,
52 ALC880_ASUS_DIG,
53 ALC880_ASUS_W1V,
54 ALC880_ASUS_DIG2,
55 ALC880_FUJITSU,
56 ALC880_UNIWILL_DIG,
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
59 ALC880_CLEVO,
60 ALC880_TCL_S700,
61 ALC880_LG,
62 ALC880_LG_LW,
63 ALC880_MEDION_RIM,
64 #ifdef CONFIG_SND_DEBUG
65 ALC880_TEST,
66 #endif
67 ALC880_AUTO,
68 ALC880_MODEL_LAST /* last tag */
71 /* ALC260 models */
72 enum {
73 ALC260_BASIC,
74 ALC260_HP,
75 ALC260_HP_DC7600,
76 ALC260_HP_3013,
77 ALC260_FUJITSU_S702X,
78 ALC260_ACER,
79 ALC260_WILL,
80 ALC260_REPLACER_672V,
81 ALC260_FAVORIT100,
82 #ifdef CONFIG_SND_DEBUG
83 ALC260_TEST,
84 #endif
85 ALC260_AUTO,
86 ALC260_MODEL_LAST /* last tag */
89 /* ALC262 models */
90 enum {
91 ALC262_BASIC,
92 ALC262_HIPPO,
93 ALC262_HIPPO_1,
94 ALC262_FUJITSU,
95 ALC262_HP_BPC,
96 ALC262_HP_BPC_D7000_WL,
97 ALC262_HP_BPC_D7000_WF,
98 ALC262_HP_TC_T5735,
99 ALC262_HP_RP5700,
100 ALC262_BENQ_ED8,
101 ALC262_SONY_ASSAMD,
102 ALC262_BENQ_T31,
103 ALC262_ULTRA,
104 ALC262_LENOVO_3000,
105 ALC262_NEC,
106 ALC262_TOSHIBA_S06,
107 ALC262_TOSHIBA_RX1,
108 ALC262_TYAN,
109 ALC262_AUTO,
110 ALC262_MODEL_LAST /* last tag */
113 /* ALC268 models */
114 enum {
115 ALC267_QUANTA_IL1,
116 ALC268_3ST,
117 ALC268_TOSHIBA,
118 ALC268_ACER,
119 ALC268_ACER_DMIC,
120 ALC268_ACER_ASPIRE_ONE,
121 ALC268_DELL,
122 ALC268_ZEPTO,
123 #ifdef CONFIG_SND_DEBUG
124 ALC268_TEST,
125 #endif
126 ALC268_AUTO,
127 ALC268_MODEL_LAST /* last tag */
130 /* ALC269 models */
131 enum {
132 ALC269_BASIC,
133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_AMIC,
135 ALC269_ASUS_DMIC,
136 ALC269_FUJITSU,
137 ALC269_LIFEBOOK,
138 ALC269_AUTO,
139 ALC269_MODEL_LAST /* last tag */
142 /* ALC861 models */
143 enum {
144 ALC861_3ST,
145 ALC660_3ST,
146 ALC861_3ST_DIG,
147 ALC861_6ST_DIG,
148 ALC861_UNIWILL_M31,
149 ALC861_TOSHIBA,
150 ALC861_ASUS,
151 ALC861_ASUS_LAPTOP,
152 ALC861_AUTO,
153 ALC861_MODEL_LAST,
156 /* ALC861-VD models */
157 enum {
158 ALC660VD_3ST,
159 ALC660VD_3ST_DIG,
160 ALC660VD_ASUS_V1S,
161 ALC861VD_3ST,
162 ALC861VD_3ST_DIG,
163 ALC861VD_6ST_DIG,
164 ALC861VD_LENOVO,
165 ALC861VD_DALLAS,
166 ALC861VD_HP,
167 ALC861VD_AUTO,
168 ALC861VD_MODEL_LAST,
171 /* ALC662 models */
172 enum {
173 ALC662_3ST_2ch_DIG,
174 ALC662_3ST_6ch_DIG,
175 ALC662_3ST_6ch,
176 ALC662_5ST_DIG,
177 ALC662_LENOVO_101E,
178 ALC662_ASUS_EEEPC_P701,
179 ALC662_ASUS_EEEPC_EP20,
180 ALC663_ASUS_M51VA,
181 ALC663_ASUS_G71V,
182 ALC663_ASUS_H13,
183 ALC663_ASUS_G50V,
184 ALC662_ECS,
185 ALC663_ASUS_MODE1,
186 ALC662_ASUS_MODE2,
187 ALC663_ASUS_MODE3,
188 ALC663_ASUS_MODE4,
189 ALC663_ASUS_MODE5,
190 ALC663_ASUS_MODE6,
191 ALC663_ASUS_MODE7,
192 ALC663_ASUS_MODE8,
193 ALC272_DELL,
194 ALC272_DELL_ZM1,
195 ALC272_SAMSUNG_NC10,
196 ALC662_AUTO,
197 ALC662_MODEL_LAST,
200 /* ALC882 models */
201 enum {
202 ALC882_3ST_DIG,
203 ALC882_6ST_DIG,
204 ALC882_ARIMA,
205 ALC882_W2JC,
206 ALC882_TARGA,
207 ALC882_ASUS_A7J,
208 ALC882_ASUS_A7M,
209 ALC885_MACPRO,
210 ALC885_MBP3,
211 ALC885_MB5,
212 ALC885_IMAC24,
213 ALC885_IMAC91,
214 ALC883_3ST_2ch_DIG,
215 ALC883_3ST_6ch_DIG,
216 ALC883_3ST_6ch,
217 ALC883_6ST_DIG,
218 ALC883_TARGA_DIG,
219 ALC883_TARGA_2ch_DIG,
220 ALC883_TARGA_8ch_DIG,
221 ALC883_ACER,
222 ALC883_ACER_ASPIRE,
223 ALC888_ACER_ASPIRE_4930G,
224 ALC888_ACER_ASPIRE_6530G,
225 ALC888_ACER_ASPIRE_8930G,
226 ALC888_ACER_ASPIRE_7730G,
227 ALC883_MEDION,
228 ALC883_MEDION_MD2,
229 ALC883_LAPTOP_EAPD,
230 ALC883_LENOVO_101E_2ch,
231 ALC883_LENOVO_NB0763,
232 ALC888_LENOVO_MS7195_DIG,
233 ALC888_LENOVO_SKY,
234 ALC883_HAIER_W66,
235 ALC888_3ST_HP,
236 ALC888_6ST_DELL,
237 ALC883_MITAC,
238 ALC883_CLEVO_M540R,
239 ALC883_CLEVO_M720,
240 ALC883_FUJITSU_PI2515,
241 ALC888_FUJITSU_XA3530,
242 ALC883_3ST_6ch_INTEL,
243 ALC889A_INTEL,
244 ALC889_INTEL,
245 ALC888_ASUS_M90V,
246 ALC888_ASUS_EEE1601,
247 ALC889A_MB31,
248 ALC1200_ASUS_P5Q,
249 ALC883_SONY_VAIO_TT,
250 ALC882_AUTO,
251 ALC882_MODEL_LAST,
254 /* for GPIO Poll */
255 #define GPIO_MASK 0x03
257 /* extra amp-initialization sequence types */
258 enum {
259 ALC_INIT_NONE,
260 ALC_INIT_DEFAULT,
261 ALC_INIT_GPIO1,
262 ALC_INIT_GPIO2,
263 ALC_INIT_GPIO3,
266 struct alc_mic_route {
267 hda_nid_t pin;
268 unsigned char mux_idx;
269 unsigned char amix_idx;
272 #define MUX_IDX_UNDEF ((unsigned char)-1)
274 struct alc_spec {
275 /* codec parameterization */
276 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
277 unsigned int num_mixers;
278 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
279 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
281 const struct hda_verb *init_verbs[10]; /* initialization verbs
282 * don't forget NULL
283 * termination!
285 unsigned int num_init_verbs;
287 char stream_name_analog[32]; /* analog PCM stream */
288 struct hda_pcm_stream *stream_analog_playback;
289 struct hda_pcm_stream *stream_analog_capture;
290 struct hda_pcm_stream *stream_analog_alt_playback;
291 struct hda_pcm_stream *stream_analog_alt_capture;
293 char stream_name_digital[32]; /* digital PCM stream */
294 struct hda_pcm_stream *stream_digital_playback;
295 struct hda_pcm_stream *stream_digital_capture;
297 /* playback */
298 struct hda_multi_out multiout; /* playback set-up
299 * max_channels, dacs must be set
300 * dig_out_nid and hp_nid are optional
302 hda_nid_t alt_dac_nid;
303 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
304 int dig_out_type;
306 /* capture */
307 unsigned int num_adc_nids;
308 hda_nid_t *adc_nids;
309 hda_nid_t *capsrc_nids;
310 hda_nid_t dig_in_nid; /* digital-in NID; optional */
312 /* capture source */
313 unsigned int num_mux_defs;
314 const struct hda_input_mux *input_mux;
315 unsigned int cur_mux[3];
316 struct alc_mic_route ext_mic;
317 struct alc_mic_route int_mic;
319 /* channel model */
320 const struct hda_channel_mode *channel_mode;
321 int num_channel_mode;
322 int need_dac_fix;
323 int const_channel_count;
324 int ext_channel_count;
326 /* PCM information */
327 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
329 /* dynamic controls, init_verbs and input_mux */
330 struct auto_pin_cfg autocfg;
331 struct snd_array kctls;
332 struct hda_input_mux private_imux[3];
333 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
334 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
335 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
337 /* hooks */
338 void (*init_hook)(struct hda_codec *codec);
339 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
340 #ifdef CONFIG_SND_HDA_POWER_SAVE
341 void (*power_hook)(struct hda_codec *codec, int power);
342 #endif
344 /* for pin sensing */
345 unsigned int sense_updated: 1;
346 unsigned int jack_present: 1;
347 unsigned int master_sw: 1;
348 unsigned int auto_mic:1;
350 /* other flags */
351 unsigned int no_analog :1; /* digital I/O only */
352 int init_amp;
354 /* for virtual master */
355 hda_nid_t vmaster_nid;
356 #ifdef CONFIG_SND_HDA_POWER_SAVE
357 struct hda_loopback_check loopback;
358 #endif
360 /* for PLL fix */
361 hda_nid_t pll_nid;
362 unsigned int pll_coef_idx, pll_coef_bit;
366 * configuration template - to be copied to the spec instance
368 struct alc_config_preset {
369 struct snd_kcontrol_new *mixers[5]; /* should be identical size
370 * with spec
372 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
373 const struct hda_verb *init_verbs[5];
374 unsigned int num_dacs;
375 hda_nid_t *dac_nids;
376 hda_nid_t dig_out_nid; /* optional */
377 hda_nid_t hp_nid; /* optional */
378 hda_nid_t *slave_dig_outs;
379 unsigned int num_adc_nids;
380 hda_nid_t *adc_nids;
381 hda_nid_t *capsrc_nids;
382 hda_nid_t dig_in_nid;
383 unsigned int num_channel_mode;
384 const struct hda_channel_mode *channel_mode;
385 int need_dac_fix;
386 int const_channel_count;
387 unsigned int num_mux_defs;
388 const struct hda_input_mux *input_mux;
389 void (*unsol_event)(struct hda_codec *, unsigned int);
390 void (*setup)(struct hda_codec *);
391 void (*init_hook)(struct hda_codec *);
392 #ifdef CONFIG_SND_HDA_POWER_SAVE
393 struct hda_amp_list *loopbacks;
394 void (*power_hook)(struct hda_codec *codec, int power);
395 #endif
400 * input MUX handling
402 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
403 struct snd_ctl_elem_info *uinfo)
405 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
406 struct alc_spec *spec = codec->spec;
407 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
408 if (mux_idx >= spec->num_mux_defs)
409 mux_idx = 0;
410 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
411 mux_idx = 0;
412 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
415 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
416 struct snd_ctl_elem_value *ucontrol)
418 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
419 struct alc_spec *spec = codec->spec;
420 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
422 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
423 return 0;
426 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
427 struct snd_ctl_elem_value *ucontrol)
429 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
430 struct alc_spec *spec = codec->spec;
431 const struct hda_input_mux *imux;
432 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
433 unsigned int mux_idx;
434 hda_nid_t nid = spec->capsrc_nids ?
435 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
436 unsigned int type;
438 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
439 imux = &spec->input_mux[mux_idx];
440 if (!imux->num_items && mux_idx > 0)
441 imux = &spec->input_mux[0];
443 type = get_wcaps_type(get_wcaps(codec, nid));
444 if (type == AC_WID_AUD_MIX) {
445 /* Matrix-mixer style (e.g. ALC882) */
446 unsigned int *cur_val = &spec->cur_mux[adc_idx];
447 unsigned int i, idx;
449 idx = ucontrol->value.enumerated.item[0];
450 if (idx >= imux->num_items)
451 idx = imux->num_items - 1;
452 if (*cur_val == idx)
453 return 0;
454 for (i = 0; i < imux->num_items; i++) {
455 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
456 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
457 imux->items[i].index,
458 HDA_AMP_MUTE, v);
460 *cur_val = idx;
461 return 1;
462 } else {
463 /* MUX style (e.g. ALC880) */
464 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
465 &spec->cur_mux[adc_idx]);
470 * channel mode setting
472 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_info *uinfo)
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
477 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
478 spec->num_channel_mode);
481 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
482 struct snd_ctl_elem_value *ucontrol)
484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
485 struct alc_spec *spec = codec->spec;
486 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
487 spec->num_channel_mode,
488 spec->ext_channel_count);
491 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol)
494 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
495 struct alc_spec *spec = codec->spec;
496 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
497 spec->num_channel_mode,
498 &spec->ext_channel_count);
499 if (err >= 0 && !spec->const_channel_count) {
500 spec->multiout.max_channels = spec->ext_channel_count;
501 if (spec->need_dac_fix)
502 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
504 return err;
508 * Control the mode of pin widget settings via the mixer. "pc" is used
509 * instead of "%" to avoid consequences of accidently treating the % as
510 * being part of a format specifier. Maximum allowed length of a value is
511 * 63 characters plus NULL terminator.
513 * Note: some retasking pin complexes seem to ignore requests for input
514 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
515 * are requested. Therefore order this list so that this behaviour will not
516 * cause problems when mixer clients move through the enum sequentially.
517 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
518 * March 2006.
520 static char *alc_pin_mode_names[] = {
521 "Mic 50pc bias", "Mic 80pc bias",
522 "Line in", "Line out", "Headphone out",
524 static unsigned char alc_pin_mode_values[] = {
525 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
527 /* The control can present all 5 options, or it can limit the options based
528 * in the pin being assumed to be exclusively an input or an output pin. In
529 * addition, "input" pins may or may not process the mic bias option
530 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
531 * accept requests for bias as of chip versions up to March 2006) and/or
532 * wiring in the computer.
534 #define ALC_PIN_DIR_IN 0x00
535 #define ALC_PIN_DIR_OUT 0x01
536 #define ALC_PIN_DIR_INOUT 0x02
537 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
538 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
540 /* Info about the pin modes supported by the different pin direction modes.
541 * For each direction the minimum and maximum values are given.
543 static signed char alc_pin_mode_dir_info[5][2] = {
544 { 0, 2 }, /* ALC_PIN_DIR_IN */
545 { 3, 4 }, /* ALC_PIN_DIR_OUT */
546 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
547 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
548 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
550 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
551 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
552 #define alc_pin_mode_n_items(_dir) \
553 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
555 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
556 struct snd_ctl_elem_info *uinfo)
558 unsigned int item_num = uinfo->value.enumerated.item;
559 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
561 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
562 uinfo->count = 1;
563 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
565 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
566 item_num = alc_pin_mode_min(dir);
567 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
568 return 0;
571 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
572 struct snd_ctl_elem_value *ucontrol)
574 unsigned int i;
575 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
576 hda_nid_t nid = kcontrol->private_value & 0xffff;
577 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
578 long *valp = ucontrol->value.integer.value;
579 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
580 AC_VERB_GET_PIN_WIDGET_CONTROL,
581 0x00);
583 /* Find enumerated value for current pinctl setting */
584 i = alc_pin_mode_min(dir);
585 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
586 i++;
587 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
588 return 0;
591 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
594 signed int change;
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 hda_nid_t nid = kcontrol->private_value & 0xffff;
597 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
598 long val = *ucontrol->value.integer.value;
599 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
600 AC_VERB_GET_PIN_WIDGET_CONTROL,
601 0x00);
603 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
604 val = alc_pin_mode_min(dir);
606 change = pinctl != alc_pin_mode_values[val];
607 if (change) {
608 /* Set pin mode to that requested */
609 snd_hda_codec_write_cache(codec, nid, 0,
610 AC_VERB_SET_PIN_WIDGET_CONTROL,
611 alc_pin_mode_values[val]);
613 /* Also enable the retasking pin's input/output as required
614 * for the requested pin mode. Enum values of 2 or less are
615 * input modes.
617 * Dynamically switching the input/output buffers probably
618 * reduces noise slightly (particularly on input) so we'll
619 * do it. However, having both input and output buffers
620 * enabled simultaneously doesn't seem to be problematic if
621 * this turns out to be necessary in the future.
623 if (val <= 2) {
624 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
625 HDA_AMP_MUTE, HDA_AMP_MUTE);
626 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
627 HDA_AMP_MUTE, 0);
628 } else {
629 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
630 HDA_AMP_MUTE, HDA_AMP_MUTE);
631 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
632 HDA_AMP_MUTE, 0);
635 return change;
638 #define ALC_PIN_MODE(xname, nid, dir) \
639 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
640 .info = alc_pin_mode_info, \
641 .get = alc_pin_mode_get, \
642 .put = alc_pin_mode_put, \
643 .private_value = nid | (dir<<16) }
645 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
646 * together using a mask with more than one bit set. This control is
647 * currently used only by the ALC260 test model. At this stage they are not
648 * needed for any "production" models.
650 #ifdef CONFIG_SND_DEBUG
651 #define alc_gpio_data_info snd_ctl_boolean_mono_info
653 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
654 struct snd_ctl_elem_value *ucontrol)
656 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
657 hda_nid_t nid = kcontrol->private_value & 0xffff;
658 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
659 long *valp = ucontrol->value.integer.value;
660 unsigned int val = snd_hda_codec_read(codec, nid, 0,
661 AC_VERB_GET_GPIO_DATA, 0x00);
663 *valp = (val & mask) != 0;
664 return 0;
666 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
669 signed int change;
670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
671 hda_nid_t nid = kcontrol->private_value & 0xffff;
672 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
673 long val = *ucontrol->value.integer.value;
674 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
675 AC_VERB_GET_GPIO_DATA,
676 0x00);
678 /* Set/unset the masked GPIO bit(s) as needed */
679 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
680 if (val == 0)
681 gpio_data &= ~mask;
682 else
683 gpio_data |= mask;
684 snd_hda_codec_write_cache(codec, nid, 0,
685 AC_VERB_SET_GPIO_DATA, gpio_data);
687 return change;
689 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
690 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
691 .info = alc_gpio_data_info, \
692 .get = alc_gpio_data_get, \
693 .put = alc_gpio_data_put, \
694 .private_value = nid | (mask<<16) }
695 #endif /* CONFIG_SND_DEBUG */
697 /* A switch control to allow the enabling of the digital IO pins on the
698 * ALC260. This is incredibly simplistic; the intention of this control is
699 * to provide something in the test model allowing digital outputs to be
700 * identified if present. If models are found which can utilise these
701 * outputs a more complete mixer control can be devised for those models if
702 * necessary.
704 #ifdef CONFIG_SND_DEBUG
705 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
707 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
708 struct snd_ctl_elem_value *ucontrol)
710 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
711 hda_nid_t nid = kcontrol->private_value & 0xffff;
712 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
713 long *valp = ucontrol->value.integer.value;
714 unsigned int val = snd_hda_codec_read(codec, nid, 0,
715 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
717 *valp = (val & mask) != 0;
718 return 0;
720 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *ucontrol)
723 signed int change;
724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
725 hda_nid_t nid = kcontrol->private_value & 0xffff;
726 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
727 long val = *ucontrol->value.integer.value;
728 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
729 AC_VERB_GET_DIGI_CONVERT_1,
730 0x00);
732 /* Set/unset the masked control bit(s) as needed */
733 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
734 if (val==0)
735 ctrl_data &= ~mask;
736 else
737 ctrl_data |= mask;
738 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
739 ctrl_data);
741 return change;
743 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
744 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
745 .info = alc_spdif_ctrl_info, \
746 .get = alc_spdif_ctrl_get, \
747 .put = alc_spdif_ctrl_put, \
748 .private_value = nid | (mask<<16) }
749 #endif /* CONFIG_SND_DEBUG */
751 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
752 * Again, this is only used in the ALC26x test models to help identify when
753 * the EAPD line must be asserted for features to work.
755 #ifdef CONFIG_SND_DEBUG
756 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
758 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
759 struct snd_ctl_elem_value *ucontrol)
761 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
762 hda_nid_t nid = kcontrol->private_value & 0xffff;
763 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
764 long *valp = ucontrol->value.integer.value;
765 unsigned int val = snd_hda_codec_read(codec, nid, 0,
766 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
768 *valp = (val & mask) != 0;
769 return 0;
772 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
773 struct snd_ctl_elem_value *ucontrol)
775 int change;
776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
777 hda_nid_t nid = kcontrol->private_value & 0xffff;
778 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
779 long val = *ucontrol->value.integer.value;
780 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
781 AC_VERB_GET_EAPD_BTLENABLE,
782 0x00);
784 /* Set/unset the masked control bit(s) as needed */
785 change = (!val ? 0 : mask) != (ctrl_data & mask);
786 if (!val)
787 ctrl_data &= ~mask;
788 else
789 ctrl_data |= mask;
790 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
791 ctrl_data);
793 return change;
796 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
797 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
798 .info = alc_eapd_ctrl_info, \
799 .get = alc_eapd_ctrl_get, \
800 .put = alc_eapd_ctrl_put, \
801 .private_value = nid | (mask<<16) }
802 #endif /* CONFIG_SND_DEBUG */
805 * set up the input pin config (depending on the given auto-pin type)
807 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
808 int auto_pin_type)
810 unsigned int val = PIN_IN;
812 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
813 unsigned int pincap;
814 pincap = snd_hda_query_pin_caps(codec, nid);
815 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
816 if (pincap & AC_PINCAP_VREF_80)
817 val = PIN_VREF80;
818 else if (pincap & AC_PINCAP_VREF_50)
819 val = PIN_VREF50;
820 else if (pincap & AC_PINCAP_VREF_100)
821 val = PIN_VREF100;
822 else if (pincap & AC_PINCAP_VREF_GRD)
823 val = PIN_VREFGRD;
825 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
830 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
832 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
833 return;
834 spec->mixers[spec->num_mixers++] = mix;
837 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
839 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
840 return;
841 spec->init_verbs[spec->num_init_verbs++] = verb;
844 #ifdef CONFIG_PROC_FS
846 * hook for proc
848 static void print_realtek_coef(struct snd_info_buffer *buffer,
849 struct hda_codec *codec, hda_nid_t nid)
851 int coeff;
853 if (nid != 0x20)
854 return;
855 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
856 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
857 coeff = snd_hda_codec_read(codec, nid, 0,
858 AC_VERB_GET_COEF_INDEX, 0);
859 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
861 #else
862 #define print_realtek_coef NULL
863 #endif
866 * set up from the preset table
868 static void setup_preset(struct hda_codec *codec,
869 const struct alc_config_preset *preset)
871 struct alc_spec *spec = codec->spec;
872 int i;
874 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
875 add_mixer(spec, preset->mixers[i]);
876 spec->cap_mixer = preset->cap_mixer;
877 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
878 i++)
879 add_verb(spec, preset->init_verbs[i]);
881 spec->channel_mode = preset->channel_mode;
882 spec->num_channel_mode = preset->num_channel_mode;
883 spec->need_dac_fix = preset->need_dac_fix;
884 spec->const_channel_count = preset->const_channel_count;
886 if (preset->const_channel_count)
887 spec->multiout.max_channels = preset->const_channel_count;
888 else
889 spec->multiout.max_channels = spec->channel_mode[0].channels;
890 spec->ext_channel_count = spec->channel_mode[0].channels;
892 spec->multiout.num_dacs = preset->num_dacs;
893 spec->multiout.dac_nids = preset->dac_nids;
894 spec->multiout.dig_out_nid = preset->dig_out_nid;
895 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
896 spec->multiout.hp_nid = preset->hp_nid;
898 spec->num_mux_defs = preset->num_mux_defs;
899 if (!spec->num_mux_defs)
900 spec->num_mux_defs = 1;
901 spec->input_mux = preset->input_mux;
903 spec->num_adc_nids = preset->num_adc_nids;
904 spec->adc_nids = preset->adc_nids;
905 spec->capsrc_nids = preset->capsrc_nids;
906 spec->dig_in_nid = preset->dig_in_nid;
908 spec->unsol_event = preset->unsol_event;
909 spec->init_hook = preset->init_hook;
910 #ifdef CONFIG_SND_HDA_POWER_SAVE
911 spec->power_hook = preset->power_hook;
912 spec->loopback.amplist = preset->loopbacks;
913 #endif
915 if (preset->setup)
916 preset->setup(codec);
919 /* Enable GPIO mask and set output */
920 static struct hda_verb alc_gpio1_init_verbs[] = {
921 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
922 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
923 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
927 static struct hda_verb alc_gpio2_init_verbs[] = {
928 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
929 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
930 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
934 static struct hda_verb alc_gpio3_init_verbs[] = {
935 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
937 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
942 * Fix hardware PLL issue
943 * On some codecs, the analog PLL gating control must be off while
944 * the default value is 1.
946 static void alc_fix_pll(struct hda_codec *codec)
948 struct alc_spec *spec = codec->spec;
949 unsigned int val;
951 if (!spec->pll_nid)
952 return;
953 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
954 spec->pll_coef_idx);
955 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
956 AC_VERB_GET_PROC_COEF, 0);
957 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
958 spec->pll_coef_idx);
959 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
960 val & ~(1 << spec->pll_coef_bit));
963 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
964 unsigned int coef_idx, unsigned int coef_bit)
966 struct alc_spec *spec = codec->spec;
967 spec->pll_nid = nid;
968 spec->pll_coef_idx = coef_idx;
969 spec->pll_coef_bit = coef_bit;
970 alc_fix_pll(codec);
973 static void alc_automute_pin(struct hda_codec *codec)
975 struct alc_spec *spec = codec->spec;
976 unsigned int nid = spec->autocfg.hp_pins[0];
977 int i;
979 if (!nid)
980 return;
981 spec->jack_present = snd_hda_jack_detect(codec, nid);
982 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
983 nid = spec->autocfg.speaker_pins[i];
984 if (!nid)
985 break;
986 snd_hda_codec_write(codec, nid, 0,
987 AC_VERB_SET_PIN_WIDGET_CONTROL,
988 spec->jack_present ? 0 : PIN_OUT);
992 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
993 hda_nid_t nid)
995 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
996 int i, nums;
998 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
999 for (i = 0; i < nums; i++)
1000 if (conn[i] == nid)
1001 return i;
1002 return -1;
1005 static void alc_mic_automute(struct hda_codec *codec)
1007 struct alc_spec *spec = codec->spec;
1008 struct alc_mic_route *dead, *alive;
1009 unsigned int present, type;
1010 hda_nid_t cap_nid;
1012 if (!spec->auto_mic)
1013 return;
1014 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1015 return;
1016 if (snd_BUG_ON(!spec->adc_nids))
1017 return;
1019 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1021 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1022 if (present) {
1023 alive = &spec->ext_mic;
1024 dead = &spec->int_mic;
1025 } else {
1026 alive = &spec->int_mic;
1027 dead = &spec->ext_mic;
1030 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1031 if (type == AC_WID_AUD_MIX) {
1032 /* Matrix-mixer style (e.g. ALC882) */
1033 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1034 alive->mux_idx,
1035 HDA_AMP_MUTE, 0);
1036 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1037 dead->mux_idx,
1038 HDA_AMP_MUTE, HDA_AMP_MUTE);
1039 } else {
1040 /* MUX style (e.g. ALC880) */
1041 snd_hda_codec_write_cache(codec, cap_nid, 0,
1042 AC_VERB_SET_CONNECT_SEL,
1043 alive->mux_idx);
1046 /* FIXME: analog mixer */
1049 /* unsolicited event for HP jack sensing */
1050 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1052 if (codec->vendor_id == 0x10ec0880)
1053 res >>= 28;
1054 else
1055 res >>= 26;
1056 switch (res) {
1057 case ALC880_HP_EVENT:
1058 alc_automute_pin(codec);
1059 break;
1060 case ALC880_MIC_EVENT:
1061 alc_mic_automute(codec);
1062 break;
1066 static void alc_inithook(struct hda_codec *codec)
1068 alc_automute_pin(codec);
1069 alc_mic_automute(codec);
1072 /* additional initialization for ALC888 variants */
1073 static void alc888_coef_init(struct hda_codec *codec)
1075 unsigned int tmp;
1077 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1078 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1079 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1080 if ((tmp & 0xf0) == 0x20)
1081 /* alc888S-VC */
1082 snd_hda_codec_read(codec, 0x20, 0,
1083 AC_VERB_SET_PROC_COEF, 0x830);
1084 else
1085 /* alc888-VB */
1086 snd_hda_codec_read(codec, 0x20, 0,
1087 AC_VERB_SET_PROC_COEF, 0x3030);
1090 static void alc889_coef_init(struct hda_codec *codec)
1092 unsigned int tmp;
1094 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1095 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1096 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1100 /* turn on/off EAPD control (only if available) */
1101 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1103 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1104 return;
1105 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1106 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1107 on ? 2 : 0);
1110 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1112 unsigned int tmp;
1114 switch (type) {
1115 case ALC_INIT_GPIO1:
1116 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1117 break;
1118 case ALC_INIT_GPIO2:
1119 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1120 break;
1121 case ALC_INIT_GPIO3:
1122 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1123 break;
1124 case ALC_INIT_DEFAULT:
1125 switch (codec->vendor_id) {
1126 case 0x10ec0260:
1127 set_eapd(codec, 0x0f, 1);
1128 set_eapd(codec, 0x10, 1);
1129 break;
1130 case 0x10ec0262:
1131 case 0x10ec0267:
1132 case 0x10ec0268:
1133 case 0x10ec0269:
1134 case 0x10ec0270:
1135 case 0x10ec0272:
1136 case 0x10ec0660:
1137 case 0x10ec0662:
1138 case 0x10ec0663:
1139 case 0x10ec0862:
1140 case 0x10ec0889:
1141 set_eapd(codec, 0x14, 1);
1142 set_eapd(codec, 0x15, 1);
1143 break;
1145 switch (codec->vendor_id) {
1146 case 0x10ec0260:
1147 snd_hda_codec_write(codec, 0x1a, 0,
1148 AC_VERB_SET_COEF_INDEX, 7);
1149 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1150 AC_VERB_GET_PROC_COEF, 0);
1151 snd_hda_codec_write(codec, 0x1a, 0,
1152 AC_VERB_SET_COEF_INDEX, 7);
1153 snd_hda_codec_write(codec, 0x1a, 0,
1154 AC_VERB_SET_PROC_COEF,
1155 tmp | 0x2010);
1156 break;
1157 case 0x10ec0262:
1158 case 0x10ec0880:
1159 case 0x10ec0882:
1160 case 0x10ec0883:
1161 case 0x10ec0885:
1162 case 0x10ec0887:
1163 case 0x10ec0889:
1164 alc889_coef_init(codec);
1165 break;
1166 case 0x10ec0888:
1167 alc888_coef_init(codec);
1168 break;
1169 case 0x10ec0267:
1170 case 0x10ec0268:
1171 snd_hda_codec_write(codec, 0x20, 0,
1172 AC_VERB_SET_COEF_INDEX, 7);
1173 tmp = snd_hda_codec_read(codec, 0x20, 0,
1174 AC_VERB_GET_PROC_COEF, 0);
1175 snd_hda_codec_write(codec, 0x20, 0,
1176 AC_VERB_SET_COEF_INDEX, 7);
1177 snd_hda_codec_write(codec, 0x20, 0,
1178 AC_VERB_SET_PROC_COEF,
1179 tmp | 0x3000);
1180 break;
1182 break;
1186 static void alc_init_auto_hp(struct hda_codec *codec)
1188 struct alc_spec *spec = codec->spec;
1190 if (!spec->autocfg.hp_pins[0])
1191 return;
1193 if (!spec->autocfg.speaker_pins[0]) {
1194 if (spec->autocfg.line_out_pins[0] &&
1195 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1196 spec->autocfg.speaker_pins[0] =
1197 spec->autocfg.line_out_pins[0];
1198 else
1199 return;
1202 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1203 spec->autocfg.hp_pins[0]);
1204 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1205 AC_VERB_SET_UNSOLICITED_ENABLE,
1206 AC_USRSP_EN | ALC880_HP_EVENT);
1207 spec->unsol_event = alc_sku_unsol_event;
1210 static void alc_init_auto_mic(struct hda_codec *codec)
1212 struct alc_spec *spec = codec->spec;
1213 struct auto_pin_cfg *cfg = &spec->autocfg;
1214 hda_nid_t fixed, ext;
1215 int i;
1217 /* there must be only two mic inputs exclusively */
1218 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1219 if (cfg->input_pins[i])
1220 return;
1222 fixed = ext = 0;
1223 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1224 hda_nid_t nid = cfg->input_pins[i];
1225 unsigned int defcfg;
1226 if (!nid)
1227 return;
1228 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1229 switch (get_defcfg_connect(defcfg)) {
1230 case AC_JACK_PORT_FIXED:
1231 if (fixed)
1232 return; /* already occupied */
1233 fixed = nid;
1234 break;
1235 case AC_JACK_PORT_COMPLEX:
1236 if (ext)
1237 return; /* already occupied */
1238 ext = nid;
1239 break;
1240 default:
1241 return; /* invalid entry */
1244 if (!ext || !fixed)
1245 return;
1246 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1247 return; /* no unsol support */
1248 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1249 ext, fixed);
1250 spec->ext_mic.pin = ext;
1251 spec->int_mic.pin = fixed;
1252 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1253 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1254 spec->auto_mic = 1;
1255 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1256 AC_VERB_SET_UNSOLICITED_ENABLE,
1257 AC_USRSP_EN | ALC880_MIC_EVENT);
1258 spec->unsol_event = alc_sku_unsol_event;
1261 /* check subsystem ID and set up device-specific initialization;
1262 * return 1 if initialized, 0 if invalid SSID
1264 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1265 * 31 ~ 16 : Manufacture ID
1266 * 15 ~ 8 : SKU ID
1267 * 7 ~ 0 : Assembly ID
1268 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1270 static int alc_subsystem_id(struct hda_codec *codec,
1271 hda_nid_t porta, hda_nid_t porte,
1272 hda_nid_t portd)
1274 unsigned int ass, tmp, i;
1275 unsigned nid;
1276 struct alc_spec *spec = codec->spec;
1278 ass = codec->subsystem_id & 0xffff;
1279 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1280 goto do_sku;
1282 /* invalid SSID, check the special NID pin defcfg instead */
1284 * 31~30 : port connectivity
1285 * 29~21 : reserve
1286 * 20 : PCBEEP input
1287 * 19~16 : Check sum (15:1)
1288 * 15~1 : Custom
1289 * 0 : override
1291 nid = 0x1d;
1292 if (codec->vendor_id == 0x10ec0260)
1293 nid = 0x17;
1294 ass = snd_hda_codec_get_pincfg(codec, nid);
1295 snd_printd("realtek: No valid SSID, "
1296 "checking pincfg 0x%08x for NID 0x%x\n",
1297 ass, nid);
1298 if (!(ass & 1) && !(ass & 0x100000))
1299 return 0;
1300 if ((ass >> 30) != 1) /* no physical connection */
1301 return 0;
1303 /* check sum */
1304 tmp = 0;
1305 for (i = 1; i < 16; i++) {
1306 if ((ass >> i) & 1)
1307 tmp++;
1309 if (((ass >> 16) & 0xf) != tmp)
1310 return 0;
1311 do_sku:
1312 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1313 ass & 0xffff, codec->vendor_id);
1315 * 0 : override
1316 * 1 : Swap Jack
1317 * 2 : 0 --> Desktop, 1 --> Laptop
1318 * 3~5 : External Amplifier control
1319 * 7~6 : Reserved
1321 tmp = (ass & 0x38) >> 3; /* external Amp control */
1322 switch (tmp) {
1323 case 1:
1324 spec->init_amp = ALC_INIT_GPIO1;
1325 break;
1326 case 3:
1327 spec->init_amp = ALC_INIT_GPIO2;
1328 break;
1329 case 7:
1330 spec->init_amp = ALC_INIT_GPIO3;
1331 break;
1332 case 5:
1333 spec->init_amp = ALC_INIT_DEFAULT;
1334 break;
1337 /* is laptop or Desktop and enable the function "Mute internal speaker
1338 * when the external headphone out jack is plugged"
1340 if (!(ass & 0x8000))
1341 return 1;
1343 * 10~8 : Jack location
1344 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1345 * 14~13: Resvered
1346 * 15 : 1 --> enable the function "Mute internal speaker
1347 * when the external headphone out jack is plugged"
1349 if (!spec->autocfg.hp_pins[0]) {
1350 hda_nid_t nid;
1351 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1352 if (tmp == 0)
1353 nid = porta;
1354 else if (tmp == 1)
1355 nid = porte;
1356 else if (tmp == 2)
1357 nid = portd;
1358 else
1359 return 1;
1360 for (i = 0; i < spec->autocfg.line_outs; i++)
1361 if (spec->autocfg.line_out_pins[i] == nid)
1362 return 1;
1363 spec->autocfg.hp_pins[0] = nid;
1366 alc_init_auto_hp(codec);
1367 alc_init_auto_mic(codec);
1368 return 1;
1371 static void alc_ssid_check(struct hda_codec *codec,
1372 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1374 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1375 struct alc_spec *spec = codec->spec;
1376 snd_printd("realtek: "
1377 "Enable default setup for auto mode as fallback\n");
1378 spec->init_amp = ALC_INIT_DEFAULT;
1379 alc_init_auto_hp(codec);
1380 alc_init_auto_mic(codec);
1385 * Fix-up pin default configurations and add default verbs
1388 struct alc_pincfg {
1389 hda_nid_t nid;
1390 u32 val;
1393 struct alc_fixup {
1394 const struct alc_pincfg *pins;
1395 const struct hda_verb *verbs;
1398 static void alc_pick_fixup(struct hda_codec *codec,
1399 const struct snd_pci_quirk *quirk,
1400 const struct alc_fixup *fix)
1402 const struct alc_pincfg *cfg;
1404 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1405 if (!quirk)
1406 return;
1408 fix += quirk->value;
1409 cfg = fix->pins;
1410 if (cfg) {
1411 for (; cfg->nid; cfg++)
1412 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1414 if (fix->verbs)
1415 add_verb(codec->spec, fix->verbs);
1418 static int alc_read_coef_idx(struct hda_codec *codec,
1419 unsigned int coef_idx)
1421 unsigned int val;
1422 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1423 coef_idx);
1424 val = snd_hda_codec_read(codec, 0x20, 0,
1425 AC_VERB_GET_PROC_COEF, 0);
1426 return val;
1430 * ALC888
1434 * 2ch mode
1436 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1437 /* Mic-in jack as mic in */
1438 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1439 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1440 /* Line-in jack as Line in */
1441 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1442 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1443 /* Line-Out as Front */
1444 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1445 { } /* end */
1449 * 4ch mode
1451 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1452 /* Mic-in jack as mic in */
1453 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1454 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1455 /* Line-in jack as Surround */
1456 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1457 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1458 /* Line-Out as Front */
1459 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1460 { } /* end */
1464 * 6ch mode
1466 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1467 /* Mic-in jack as CLFE */
1468 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1469 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1470 /* Line-in jack as Surround */
1471 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1472 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1473 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1474 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1475 { } /* end */
1479 * 8ch mode
1481 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1482 /* Mic-in jack as CLFE */
1483 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1484 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1485 /* Line-in jack as Surround */
1486 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1487 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1488 /* Line-Out as Side */
1489 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1490 { } /* end */
1493 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1494 { 2, alc888_4ST_ch2_intel_init },
1495 { 4, alc888_4ST_ch4_intel_init },
1496 { 6, alc888_4ST_ch6_intel_init },
1497 { 8, alc888_4ST_ch8_intel_init },
1501 * ALC888 Fujitsu Siemens Amillo xa3530
1504 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1505 /* Front Mic: set to PIN_IN (empty by default) */
1506 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1507 /* Connect Internal HP to Front */
1508 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1509 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1510 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1511 /* Connect Bass HP to Front */
1512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1514 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1515 /* Connect Line-Out side jack (SPDIF) to Side */
1516 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1517 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1518 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1519 /* Connect Mic jack to CLFE */
1520 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1521 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1522 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1523 /* Connect Line-in jack to Surround */
1524 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1525 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1526 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1527 /* Connect HP out jack to Front */
1528 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1529 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1530 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1531 /* Enable unsolicited event for HP jack and Line-out jack */
1532 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1533 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1537 static void alc_automute_amp(struct hda_codec *codec)
1539 struct alc_spec *spec = codec->spec;
1540 unsigned int mute;
1541 hda_nid_t nid;
1542 int i;
1544 spec->jack_present = 0;
1545 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1546 nid = spec->autocfg.hp_pins[i];
1547 if (!nid)
1548 break;
1549 if (snd_hda_jack_detect(codec, nid)) {
1550 spec->jack_present = 1;
1551 break;
1555 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1556 /* Toggle internal speakers muting */
1557 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1558 nid = spec->autocfg.speaker_pins[i];
1559 if (!nid)
1560 break;
1561 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1562 HDA_AMP_MUTE, mute);
1566 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1567 unsigned int res)
1569 if (codec->vendor_id == 0x10ec0880)
1570 res >>= 28;
1571 else
1572 res >>= 26;
1573 if (res == ALC880_HP_EVENT)
1574 alc_automute_amp(codec);
1577 static void alc889_automute_setup(struct hda_codec *codec)
1579 struct alc_spec *spec = codec->spec;
1581 spec->autocfg.hp_pins[0] = 0x15;
1582 spec->autocfg.speaker_pins[0] = 0x14;
1583 spec->autocfg.speaker_pins[1] = 0x16;
1584 spec->autocfg.speaker_pins[2] = 0x17;
1585 spec->autocfg.speaker_pins[3] = 0x19;
1586 spec->autocfg.speaker_pins[4] = 0x1a;
1589 static void alc889_intel_init_hook(struct hda_codec *codec)
1591 alc889_coef_init(codec);
1592 alc_automute_amp(codec);
1595 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1597 struct alc_spec *spec = codec->spec;
1599 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1600 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1601 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1602 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1606 * ALC888 Acer Aspire 4930G model
1609 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1610 /* Front Mic: set to PIN_IN (empty by default) */
1611 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1612 /* Unselect Front Mic by default in input mixer 3 */
1613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1614 /* Enable unsolicited event for HP jack */
1615 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1616 /* Connect Internal HP to front */
1617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1618 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1619 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1620 /* Connect HP out to front */
1621 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1622 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1623 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1628 * ALC888 Acer Aspire 6530G model
1631 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1632 /* Bias voltage on for external mic port */
1633 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1634 /* Front Mic: set to PIN_IN (empty by default) */
1635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1636 /* Unselect Front Mic by default in input mixer 3 */
1637 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1638 /* Enable unsolicited event for HP jack */
1639 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1640 /* Enable speaker output */
1641 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1642 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1643 /* Enable headphone output */
1644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1646 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1651 * ALC889 Acer Aspire 8930G model
1654 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1655 /* Front Mic: set to PIN_IN (empty by default) */
1656 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1657 /* Unselect Front Mic by default in input mixer 3 */
1658 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1659 /* Enable unsolicited event for HP jack */
1660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1661 /* Connect Internal Front to Front */
1662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1664 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1665 /* Connect Internal Rear to Rear */
1666 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1667 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1668 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1669 /* Connect Internal CLFE to CLFE */
1670 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1671 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1672 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1673 /* Connect HP out to Front */
1674 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1675 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1676 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1677 /* Enable all DACs */
1678 /* DAC DISABLE/MUTE 1? */
1679 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1680 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1681 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1682 /* DAC DISABLE/MUTE 2? */
1683 /* some bit here disables the other DACs. Init=0x4900 */
1684 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1685 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1686 /* DMIC fix
1687 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1688 * which makes the stereo useless. However, either the mic or the ALC889
1689 * makes the signal become a difference/sum signal instead of standard
1690 * stereo, which is annoying. So instead we flip this bit which makes the
1691 * codec replicate the sum signal to both channels, turning it into a
1692 * normal mono mic.
1694 /* DMIC_CONTROL? Init value = 0x0001 */
1695 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1696 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1700 static struct hda_input_mux alc888_2_capture_sources[2] = {
1701 /* Front mic only available on one ADC */
1703 .num_items = 4,
1704 .items = {
1705 { "Mic", 0x0 },
1706 { "Line", 0x2 },
1707 { "CD", 0x4 },
1708 { "Front Mic", 0xb },
1712 .num_items = 3,
1713 .items = {
1714 { "Mic", 0x0 },
1715 { "Line", 0x2 },
1716 { "CD", 0x4 },
1721 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1722 /* Interal mic only available on one ADC */
1724 .num_items = 5,
1725 .items = {
1726 { "Ext Mic", 0x0 },
1727 { "Line In", 0x2 },
1728 { "CD", 0x4 },
1729 { "Input Mix", 0xa },
1730 { "Int Mic", 0xb },
1734 .num_items = 4,
1735 .items = {
1736 { "Ext Mic", 0x0 },
1737 { "Line In", 0x2 },
1738 { "CD", 0x4 },
1739 { "Input Mix", 0xa },
1744 static struct hda_input_mux alc889_capture_sources[3] = {
1745 /* Digital mic only available on first "ADC" */
1747 .num_items = 5,
1748 .items = {
1749 { "Mic", 0x0 },
1750 { "Line", 0x2 },
1751 { "CD", 0x4 },
1752 { "Front Mic", 0xb },
1753 { "Input Mix", 0xa },
1757 .num_items = 4,
1758 .items = {
1759 { "Mic", 0x0 },
1760 { "Line", 0x2 },
1761 { "CD", 0x4 },
1762 { "Input Mix", 0xa },
1766 .num_items = 4,
1767 .items = {
1768 { "Mic", 0x0 },
1769 { "Line", 0x2 },
1770 { "CD", 0x4 },
1771 { "Input Mix", 0xa },
1776 static struct snd_kcontrol_new alc888_base_mixer[] = {
1777 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1778 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1779 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1780 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1781 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1782 HDA_OUTPUT),
1783 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1784 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1785 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1786 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1787 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1795 { } /* end */
1798 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1799 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1800 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1801 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1802 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1803 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1804 HDA_OUTPUT),
1805 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1806 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1807 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1808 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1809 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1811 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1813 { } /* end */
1817 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1819 struct alc_spec *spec = codec->spec;
1821 spec->autocfg.hp_pins[0] = 0x15;
1822 spec->autocfg.speaker_pins[0] = 0x14;
1823 spec->autocfg.speaker_pins[1] = 0x16;
1824 spec->autocfg.speaker_pins[2] = 0x17;
1827 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1829 struct alc_spec *spec = codec->spec;
1831 spec->autocfg.hp_pins[0] = 0x15;
1832 spec->autocfg.speaker_pins[0] = 0x14;
1833 spec->autocfg.speaker_pins[1] = 0x16;
1834 spec->autocfg.speaker_pins[2] = 0x17;
1837 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1839 struct alc_spec *spec = codec->spec;
1841 spec->autocfg.hp_pins[0] = 0x15;
1842 spec->autocfg.speaker_pins[0] = 0x14;
1843 spec->autocfg.speaker_pins[1] = 0x16;
1844 spec->autocfg.speaker_pins[2] = 0x1b;
1847 #ifdef CONFIG_SND_HDA_POWER_SAVE
1848 static void alc889_power_eapd(struct hda_codec *codec, int power)
1850 set_eapd(codec, 0x14, power);
1851 set_eapd(codec, 0x15, power);
1853 #endif
1856 * ALC880 3-stack model
1858 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1859 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1860 * F-Mic = 0x1b, HP = 0x19
1863 static hda_nid_t alc880_dac_nids[4] = {
1864 /* front, rear, clfe, rear_surr */
1865 0x02, 0x05, 0x04, 0x03
1868 static hda_nid_t alc880_adc_nids[3] = {
1869 /* ADC0-2 */
1870 0x07, 0x08, 0x09,
1873 /* The datasheet says the node 0x07 is connected from inputs,
1874 * but it shows zero connection in the real implementation on some devices.
1875 * Note: this is a 915GAV bug, fixed on 915GLV
1877 static hda_nid_t alc880_adc_nids_alt[2] = {
1878 /* ADC1-2 */
1879 0x08, 0x09,
1882 #define ALC880_DIGOUT_NID 0x06
1883 #define ALC880_DIGIN_NID 0x0a
1885 static struct hda_input_mux alc880_capture_source = {
1886 .num_items = 4,
1887 .items = {
1888 { "Mic", 0x0 },
1889 { "Front Mic", 0x3 },
1890 { "Line", 0x2 },
1891 { "CD", 0x4 },
1895 /* channel source setting (2/6 channel selection for 3-stack) */
1896 /* 2ch mode */
1897 static struct hda_verb alc880_threestack_ch2_init[] = {
1898 /* set line-in to input, mute it */
1899 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1900 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1901 /* set mic-in to input vref 80%, mute it */
1902 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1903 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1904 { } /* end */
1907 /* 6ch mode */
1908 static struct hda_verb alc880_threestack_ch6_init[] = {
1909 /* set line-in to output, unmute it */
1910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1912 /* set mic-in to output, unmute it */
1913 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1914 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1915 { } /* end */
1918 static struct hda_channel_mode alc880_threestack_modes[2] = {
1919 { 2, alc880_threestack_ch2_init },
1920 { 6, alc880_threestack_ch6_init },
1923 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1924 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1925 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1926 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1927 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1928 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1929 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1930 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1931 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1933 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1934 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1935 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1936 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1937 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1943 .name = "Channel Mode",
1944 .info = alc_ch_mode_info,
1945 .get = alc_ch_mode_get,
1946 .put = alc_ch_mode_put,
1948 { } /* end */
1951 /* capture mixer elements */
1952 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1953 struct snd_ctl_elem_info *uinfo)
1955 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1956 struct alc_spec *spec = codec->spec;
1957 int err;
1959 mutex_lock(&codec->control_mutex);
1960 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1961 HDA_INPUT);
1962 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1963 mutex_unlock(&codec->control_mutex);
1964 return err;
1967 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1968 unsigned int size, unsigned int __user *tlv)
1970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1971 struct alc_spec *spec = codec->spec;
1972 int err;
1974 mutex_lock(&codec->control_mutex);
1975 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1976 HDA_INPUT);
1977 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1978 mutex_unlock(&codec->control_mutex);
1979 return err;
1982 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1983 struct snd_ctl_elem_value *ucontrol);
1985 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1986 struct snd_ctl_elem_value *ucontrol,
1987 getput_call_t func)
1989 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1990 struct alc_spec *spec = codec->spec;
1991 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1992 int err;
1994 mutex_lock(&codec->control_mutex);
1995 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1996 3, 0, HDA_INPUT);
1997 err = func(kcontrol, ucontrol);
1998 mutex_unlock(&codec->control_mutex);
1999 return err;
2002 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2003 struct snd_ctl_elem_value *ucontrol)
2005 return alc_cap_getput_caller(kcontrol, ucontrol,
2006 snd_hda_mixer_amp_volume_get);
2009 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2010 struct snd_ctl_elem_value *ucontrol)
2012 return alc_cap_getput_caller(kcontrol, ucontrol,
2013 snd_hda_mixer_amp_volume_put);
2016 /* capture mixer elements */
2017 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2019 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2020 struct snd_ctl_elem_value *ucontrol)
2022 return alc_cap_getput_caller(kcontrol, ucontrol,
2023 snd_hda_mixer_amp_switch_get);
2026 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2027 struct snd_ctl_elem_value *ucontrol)
2029 return alc_cap_getput_caller(kcontrol, ucontrol,
2030 snd_hda_mixer_amp_switch_put);
2033 #define _DEFINE_CAPMIX(num) \
2035 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2036 .name = "Capture Switch", \
2037 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2038 .count = num, \
2039 .info = alc_cap_sw_info, \
2040 .get = alc_cap_sw_get, \
2041 .put = alc_cap_sw_put, \
2042 }, \
2044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2045 .name = "Capture Volume", \
2046 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2047 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2048 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2049 .count = num, \
2050 .info = alc_cap_vol_info, \
2051 .get = alc_cap_vol_get, \
2052 .put = alc_cap_vol_put, \
2053 .tlv = { .c = alc_cap_vol_tlv }, \
2056 #define _DEFINE_CAPSRC(num) \
2058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2059 /* .name = "Capture Source", */ \
2060 .name = "Input Source", \
2061 .count = num, \
2062 .info = alc_mux_enum_info, \
2063 .get = alc_mux_enum_get, \
2064 .put = alc_mux_enum_put, \
2067 #define DEFINE_CAPMIX(num) \
2068 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2069 _DEFINE_CAPMIX(num), \
2070 _DEFINE_CAPSRC(num), \
2071 { } /* end */ \
2074 #define DEFINE_CAPMIX_NOSRC(num) \
2075 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2076 _DEFINE_CAPMIX(num), \
2077 { } /* end */ \
2080 /* up to three ADCs */
2081 DEFINE_CAPMIX(1);
2082 DEFINE_CAPMIX(2);
2083 DEFINE_CAPMIX(3);
2084 DEFINE_CAPMIX_NOSRC(1);
2085 DEFINE_CAPMIX_NOSRC(2);
2086 DEFINE_CAPMIX_NOSRC(3);
2089 * ALC880 5-stack model
2091 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2092 * Side = 0x02 (0xd)
2093 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2094 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2097 /* additional mixers to alc880_three_stack_mixer */
2098 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2099 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2100 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2101 { } /* end */
2104 /* channel source setting (6/8 channel selection for 5-stack) */
2105 /* 6ch mode */
2106 static struct hda_verb alc880_fivestack_ch6_init[] = {
2107 /* set line-in to input, mute it */
2108 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2109 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2110 { } /* end */
2113 /* 8ch mode */
2114 static struct hda_verb alc880_fivestack_ch8_init[] = {
2115 /* set line-in to output, unmute it */
2116 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2117 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2118 { } /* end */
2121 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2122 { 6, alc880_fivestack_ch6_init },
2123 { 8, alc880_fivestack_ch8_init },
2128 * ALC880 6-stack model
2130 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2131 * Side = 0x05 (0x0f)
2132 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2133 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2136 static hda_nid_t alc880_6st_dac_nids[4] = {
2137 /* front, rear, clfe, rear_surr */
2138 0x02, 0x03, 0x04, 0x05
2141 static struct hda_input_mux alc880_6stack_capture_source = {
2142 .num_items = 4,
2143 .items = {
2144 { "Mic", 0x0 },
2145 { "Front Mic", 0x1 },
2146 { "Line", 0x2 },
2147 { "CD", 0x4 },
2151 /* fixed 8-channels */
2152 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2153 { 8, NULL },
2156 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2159 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2160 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2161 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2162 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2163 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2164 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2165 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2166 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2167 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2168 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2169 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2170 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2171 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2173 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2174 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2177 .name = "Channel Mode",
2178 .info = alc_ch_mode_info,
2179 .get = alc_ch_mode_get,
2180 .put = alc_ch_mode_put,
2182 { } /* end */
2187 * ALC880 W810 model
2189 * W810 has rear IO for:
2190 * Front (DAC 02)
2191 * Surround (DAC 03)
2192 * Center/LFE (DAC 04)
2193 * Digital out (06)
2195 * The system also has a pair of internal speakers, and a headphone jack.
2196 * These are both connected to Line2 on the codec, hence to DAC 02.
2198 * There is a variable resistor to control the speaker or headphone
2199 * volume. This is a hardware-only device without a software API.
2201 * Plugging headphones in will disable the internal speakers. This is
2202 * implemented in hardware, not via the driver using jack sense. In
2203 * a similar fashion, plugging into the rear socket marked "front" will
2204 * disable both the speakers and headphones.
2206 * For input, there's a microphone jack, and an "audio in" jack.
2207 * These may not do anything useful with this driver yet, because I
2208 * haven't setup any initialization verbs for these yet...
2211 static hda_nid_t alc880_w810_dac_nids[3] = {
2212 /* front, rear/surround, clfe */
2213 0x02, 0x03, 0x04
2216 /* fixed 6 channels */
2217 static struct hda_channel_mode alc880_w810_modes[1] = {
2218 { 6, NULL }
2221 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2222 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2223 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2224 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2225 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2226 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2227 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2228 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2229 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2230 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2232 { } /* end */
2237 * Z710V model
2239 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2240 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2241 * Line = 0x1a
2244 static hda_nid_t alc880_z71v_dac_nids[1] = {
2245 0x02
2247 #define ALC880_Z71V_HP_DAC 0x03
2249 /* fixed 2 channels */
2250 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2251 { 2, NULL }
2254 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2256 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2257 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2258 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2263 { } /* end */
2268 * ALC880 F1734 model
2270 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2271 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2274 static hda_nid_t alc880_f1734_dac_nids[1] = {
2275 0x03
2277 #define ALC880_F1734_HP_DAC 0x02
2279 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2280 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2281 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2282 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2283 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2284 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2285 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2286 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2288 { } /* end */
2291 static struct hda_input_mux alc880_f1734_capture_source = {
2292 .num_items = 2,
2293 .items = {
2294 { "Mic", 0x1 },
2295 { "CD", 0x4 },
2301 * ALC880 ASUS model
2303 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2304 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2305 * Mic = 0x18, Line = 0x1a
2308 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2309 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2311 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2312 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2313 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2314 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2315 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2316 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2317 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2318 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2319 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2320 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2321 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2322 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2323 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2325 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2328 .name = "Channel Mode",
2329 .info = alc_ch_mode_info,
2330 .get = alc_ch_mode_get,
2331 .put = alc_ch_mode_put,
2333 { } /* end */
2337 * ALC880 ASUS W1V model
2339 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2340 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2341 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2344 /* additional mixers to alc880_asus_mixer */
2345 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2346 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2347 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2348 { } /* end */
2351 /* TCL S700 */
2352 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2354 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2356 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2357 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2360 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2361 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2362 { } /* end */
2365 /* Uniwill */
2366 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2367 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2368 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2369 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2370 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2371 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2372 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2373 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2374 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2375 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2376 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2377 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2378 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2379 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2380 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2381 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2382 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2385 .name = "Channel Mode",
2386 .info = alc_ch_mode_info,
2387 .get = alc_ch_mode_get,
2388 .put = alc_ch_mode_put,
2390 { } /* end */
2393 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2394 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2395 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2396 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2397 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2398 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2399 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2400 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2401 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2402 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2403 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2404 { } /* end */
2407 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2408 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2409 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2410 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2411 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2412 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2413 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2414 { } /* end */
2418 * virtual master controls
2422 * slave controls for virtual master
2424 static const char *alc_slave_vols[] = {
2425 "Front Playback Volume",
2426 "Surround Playback Volume",
2427 "Center Playback Volume",
2428 "LFE Playback Volume",
2429 "Side Playback Volume",
2430 "Headphone Playback Volume",
2431 "Speaker Playback Volume",
2432 "Mono Playback Volume",
2433 "Line-Out Playback Volume",
2434 "PCM Playback Volume",
2435 NULL,
2438 static const char *alc_slave_sws[] = {
2439 "Front Playback Switch",
2440 "Surround Playback Switch",
2441 "Center Playback Switch",
2442 "LFE Playback Switch",
2443 "Side Playback Switch",
2444 "Headphone Playback Switch",
2445 "Speaker Playback Switch",
2446 "Mono Playback Switch",
2447 "IEC958 Playback Switch",
2448 "Line-Out Playback Switch",
2449 "PCM Playback Switch",
2450 NULL,
2454 * build control elements
2457 static void alc_free_kctls(struct hda_codec *codec);
2459 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2460 /* additional beep mixers; the actual parameters are overwritten at build */
2461 static struct snd_kcontrol_new alc_beep_mixer[] = {
2462 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2463 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2464 { } /* end */
2466 #endif
2468 static int alc_build_controls(struct hda_codec *codec)
2470 struct alc_spec *spec = codec->spec;
2471 int err;
2472 int i;
2474 for (i = 0; i < spec->num_mixers; i++) {
2475 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2476 if (err < 0)
2477 return err;
2479 if (spec->cap_mixer) {
2480 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2481 if (err < 0)
2482 return err;
2484 if (spec->multiout.dig_out_nid) {
2485 err = snd_hda_create_spdif_out_ctls(codec,
2486 spec->multiout.dig_out_nid);
2487 if (err < 0)
2488 return err;
2489 if (!spec->no_analog) {
2490 err = snd_hda_create_spdif_share_sw(codec,
2491 &spec->multiout);
2492 if (err < 0)
2493 return err;
2494 spec->multiout.share_spdif = 1;
2497 if (spec->dig_in_nid) {
2498 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2499 if (err < 0)
2500 return err;
2503 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2504 /* create beep controls if needed */
2505 if (spec->beep_amp) {
2506 struct snd_kcontrol_new *knew;
2507 for (knew = alc_beep_mixer; knew->name; knew++) {
2508 struct snd_kcontrol *kctl;
2509 kctl = snd_ctl_new1(knew, codec);
2510 if (!kctl)
2511 return -ENOMEM;
2512 kctl->private_value = spec->beep_amp;
2513 err = snd_hda_ctl_add(codec,
2514 get_amp_nid_(spec->beep_amp), kctl);
2515 if (err < 0)
2516 return err;
2519 #endif
2521 /* if we have no master control, let's create it */
2522 if (!spec->no_analog &&
2523 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2524 unsigned int vmaster_tlv[4];
2525 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2526 HDA_OUTPUT, vmaster_tlv);
2527 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2528 vmaster_tlv, alc_slave_vols);
2529 if (err < 0)
2530 return err;
2532 if (!spec->no_analog &&
2533 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2534 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2535 NULL, alc_slave_sws);
2536 if (err < 0)
2537 return err;
2540 alc_free_kctls(codec); /* no longer needed */
2541 return 0;
2546 * initialize the codec volumes, etc
2550 * generic initialization of ADC, input mixers and output mixers
2552 static struct hda_verb alc880_volume_init_verbs[] = {
2554 * Unmute ADC0-2 and set the default input to mic-in
2556 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2557 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2558 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2560 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2563 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2564 * mixer widget
2565 * Note: PASD motherboards uses the Line In 2 as the input for front
2566 * panel mic (mic 2)
2568 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2569 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2570 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2571 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2572 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2573 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2574 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2575 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2578 * Set up output mixers (0x0c - 0x0f)
2580 /* set vol=0 to output mixers */
2581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2584 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2585 /* set up input amps for analog loopback */
2586 /* Amp Indices: DAC = 0, mixer = 1 */
2587 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2588 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2589 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2590 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2591 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2592 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2593 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2594 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2600 * 3-stack pin configuration:
2601 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2603 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2605 * preset connection lists of input pins
2606 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2608 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2609 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2610 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2613 * Set pin mode and muting
2615 /* set front pin widgets 0x14 for output */
2616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2617 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2618 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2621 /* Mic2 (as headphone out) for HP output */
2622 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2623 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2624 /* Line In pin widget for input */
2625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2626 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2627 /* Line2 (as front mic) pin widget for input and vref at 80% */
2628 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2629 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2630 /* CD pin widget for input */
2631 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2637 * 5-stack pin configuration:
2638 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2639 * line-in/side = 0x1a, f-mic = 0x1b
2641 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2643 * preset connection lists of input pins
2644 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2646 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2647 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2650 * Set pin mode and muting
2652 /* set pin widgets 0x14-0x17 for output */
2653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2654 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2655 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2656 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2657 /* unmute pins for output (no gain on this amp) */
2658 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2659 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2660 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2663 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2666 /* Mic2 (as headphone out) for HP output */
2667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2669 /* Line In pin widget for input */
2670 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2671 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2672 /* Line2 (as front mic) pin widget for input and vref at 80% */
2673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2674 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2675 /* CD pin widget for input */
2676 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2682 * W810 pin configuration:
2683 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2685 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2686 /* hphone/speaker input selector: front DAC */
2687 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2691 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2692 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2693 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2694 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2697 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2703 * Z71V pin configuration:
2704 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2706 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2709 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2712 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2713 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2714 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2715 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2721 * 6-stack pin configuration:
2722 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2723 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2725 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2726 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2728 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2729 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2730 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2731 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2732 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2733 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2734 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2735 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2739 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2744 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2751 * Uniwill pin configuration:
2752 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2753 * line = 0x1a
2755 static struct hda_verb alc880_uniwill_init_verbs[] = {
2756 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2760 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2762 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2763 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2764 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2765 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2766 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2768 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2769 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2770 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2771 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2773 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2775 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2776 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2777 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2779 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2780 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2781 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2783 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2784 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2790 * Uniwill P53
2791 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2793 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2794 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2798 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2799 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2803 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2804 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2805 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2806 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2809 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2810 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2812 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2813 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2814 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2816 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2817 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2822 static struct hda_verb alc880_beep_init_verbs[] = {
2823 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2827 /* auto-toggle front mic */
2828 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2830 unsigned int present;
2831 unsigned char bits;
2833 present = snd_hda_jack_detect(codec, 0x18);
2834 bits = present ? HDA_AMP_MUTE : 0;
2835 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2838 static void alc880_uniwill_setup(struct hda_codec *codec)
2840 struct alc_spec *spec = codec->spec;
2842 spec->autocfg.hp_pins[0] = 0x14;
2843 spec->autocfg.speaker_pins[0] = 0x15;
2844 spec->autocfg.speaker_pins[0] = 0x16;
2847 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2849 alc_automute_amp(codec);
2850 alc880_uniwill_mic_automute(codec);
2853 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2854 unsigned int res)
2856 /* Looks like the unsol event is incompatible with the standard
2857 * definition. 4bit tag is placed at 28 bit!
2859 switch (res >> 28) {
2860 case ALC880_MIC_EVENT:
2861 alc880_uniwill_mic_automute(codec);
2862 break;
2863 default:
2864 alc_automute_amp_unsol_event(codec, res);
2865 break;
2869 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2871 struct alc_spec *spec = codec->spec;
2873 spec->autocfg.hp_pins[0] = 0x14;
2874 spec->autocfg.speaker_pins[0] = 0x15;
2877 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2879 unsigned int present;
2881 present = snd_hda_codec_read(codec, 0x21, 0,
2882 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2883 present &= HDA_AMP_VOLMASK;
2884 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2885 HDA_AMP_VOLMASK, present);
2886 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2887 HDA_AMP_VOLMASK, present);
2890 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2891 unsigned int res)
2893 /* Looks like the unsol event is incompatible with the standard
2894 * definition. 4bit tag is placed at 28 bit!
2896 if ((res >> 28) == ALC880_DCVOL_EVENT)
2897 alc880_uniwill_p53_dcvol_automute(codec);
2898 else
2899 alc_automute_amp_unsol_event(codec, res);
2903 * F1734 pin configuration:
2904 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2906 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2907 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2908 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2909 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2910 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2911 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2913 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2915 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2918 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2919 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2920 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2921 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2922 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2923 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2924 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2925 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2926 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2929 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2935 * ASUS pin configuration:
2936 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2938 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2939 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2940 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2941 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2942 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2945 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2947 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2949 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2950 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2951 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2953 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2954 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2959 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2961 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2966 /* Enable GPIO mask and set output */
2967 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2968 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2969 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2971 /* Clevo m520g init */
2972 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2973 /* headphone output */
2974 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2975 /* line-out */
2976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2977 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2978 /* Line-in */
2979 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2980 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2981 /* CD */
2982 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2983 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2984 /* Mic1 (rear panel) */
2985 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2986 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2987 /* Mic2 (front panel) */
2988 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2989 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2990 /* headphone */
2991 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2992 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2993 /* change to EAPD mode */
2994 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2995 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3000 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3001 /* change to EAPD mode */
3002 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3003 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3005 /* Headphone output */
3006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3007 /* Front output*/
3008 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3009 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3011 /* Line In pin widget for input */
3012 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3013 /* CD pin widget for input */
3014 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3015 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3016 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3018 /* change to EAPD mode */
3019 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3020 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3026 * LG m1 express dual
3028 * Pin assignment:
3029 * Rear Line-In/Out (blue): 0x14
3030 * Build-in Mic-In: 0x15
3031 * Speaker-out: 0x17
3032 * HP-Out (green): 0x1b
3033 * Mic-In/Out (red): 0x19
3034 * SPDIF-Out: 0x1e
3037 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3038 static hda_nid_t alc880_lg_dac_nids[3] = {
3039 0x05, 0x02, 0x03
3042 /* seems analog CD is not working */
3043 static struct hda_input_mux alc880_lg_capture_source = {
3044 .num_items = 3,
3045 .items = {
3046 { "Mic", 0x1 },
3047 { "Line", 0x5 },
3048 { "Internal Mic", 0x6 },
3052 /* 2,4,6 channel modes */
3053 static struct hda_verb alc880_lg_ch2_init[] = {
3054 /* set line-in and mic-in to input */
3055 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3056 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3060 static struct hda_verb alc880_lg_ch4_init[] = {
3061 /* set line-in to out and mic-in to input */
3062 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3063 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3067 static struct hda_verb alc880_lg_ch6_init[] = {
3068 /* set line-in and mic-in to output */
3069 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3070 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3074 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3075 { 2, alc880_lg_ch2_init },
3076 { 4, alc880_lg_ch4_init },
3077 { 6, alc880_lg_ch6_init },
3080 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3081 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3082 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3083 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3084 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3085 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3086 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3087 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3088 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3094 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3096 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3097 .name = "Channel Mode",
3098 .info = alc_ch_mode_info,
3099 .get = alc_ch_mode_get,
3100 .put = alc_ch_mode_put,
3102 { } /* end */
3105 static struct hda_verb alc880_lg_init_verbs[] = {
3106 /* set capture source to mic-in */
3107 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3108 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3110 /* mute all amp mixer inputs */
3111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3114 /* line-in to input */
3115 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3116 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3117 /* built-in mic */
3118 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3119 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3120 /* speaker-out */
3121 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3122 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3123 /* mic-in to input */
3124 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3125 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3126 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3127 /* HP-out */
3128 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3129 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3130 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3131 /* jack sense */
3132 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3136 /* toggle speaker-output according to the hp-jack state */
3137 static void alc880_lg_setup(struct hda_codec *codec)
3139 struct alc_spec *spec = codec->spec;
3141 spec->autocfg.hp_pins[0] = 0x1b;
3142 spec->autocfg.speaker_pins[0] = 0x17;
3146 * LG LW20
3148 * Pin assignment:
3149 * Speaker-out: 0x14
3150 * Mic-In: 0x18
3151 * Built-in Mic-In: 0x19
3152 * Line-In: 0x1b
3153 * HP-Out: 0x1a
3154 * SPDIF-Out: 0x1e
3157 static struct hda_input_mux alc880_lg_lw_capture_source = {
3158 .num_items = 3,
3159 .items = {
3160 { "Mic", 0x0 },
3161 { "Internal Mic", 0x1 },
3162 { "Line In", 0x2 },
3166 #define alc880_lg_lw_modes alc880_threestack_modes
3168 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3169 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3170 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3171 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3172 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3173 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3174 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3175 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3176 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3181 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3182 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3185 .name = "Channel Mode",
3186 .info = alc_ch_mode_info,
3187 .get = alc_ch_mode_get,
3188 .put = alc_ch_mode_put,
3190 { } /* end */
3193 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3194 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3195 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3196 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3198 /* set capture source to mic-in */
3199 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3201 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3202 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3203 /* speaker-out */
3204 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3205 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3206 /* HP-out */
3207 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3208 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3209 /* mic-in to input */
3210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3212 /* built-in mic */
3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3215 /* jack sense */
3216 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3220 /* toggle speaker-output according to the hp-jack state */
3221 static void alc880_lg_lw_setup(struct hda_codec *codec)
3223 struct alc_spec *spec = codec->spec;
3225 spec->autocfg.hp_pins[0] = 0x1b;
3226 spec->autocfg.speaker_pins[0] = 0x14;
3229 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3230 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3231 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3234 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3235 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3236 { } /* end */
3239 static struct hda_input_mux alc880_medion_rim_capture_source = {
3240 .num_items = 2,
3241 .items = {
3242 { "Mic", 0x0 },
3243 { "Internal Mic", 0x1 },
3247 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3248 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3253 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3254 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3255 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3256 /* Mic2 (as headphone out) for HP output */
3257 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3258 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3259 /* Internal Speaker */
3260 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3261 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3263 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3264 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3266 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3270 /* toggle speaker-output according to the hp-jack state */
3271 static void alc880_medion_rim_automute(struct hda_codec *codec)
3273 struct alc_spec *spec = codec->spec;
3274 alc_automute_amp(codec);
3275 /* toggle EAPD */
3276 if (spec->jack_present)
3277 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3278 else
3279 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3282 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3283 unsigned int res)
3285 /* Looks like the unsol event is incompatible with the standard
3286 * definition. 4bit tag is placed at 28 bit!
3288 if ((res >> 28) == ALC880_HP_EVENT)
3289 alc880_medion_rim_automute(codec);
3292 static void alc880_medion_rim_setup(struct hda_codec *codec)
3294 struct alc_spec *spec = codec->spec;
3296 spec->autocfg.hp_pins[0] = 0x14;
3297 spec->autocfg.speaker_pins[0] = 0x1b;
3300 #ifdef CONFIG_SND_HDA_POWER_SAVE
3301 static struct hda_amp_list alc880_loopbacks[] = {
3302 { 0x0b, HDA_INPUT, 0 },
3303 { 0x0b, HDA_INPUT, 1 },
3304 { 0x0b, HDA_INPUT, 2 },
3305 { 0x0b, HDA_INPUT, 3 },
3306 { 0x0b, HDA_INPUT, 4 },
3307 { } /* end */
3310 static struct hda_amp_list alc880_lg_loopbacks[] = {
3311 { 0x0b, HDA_INPUT, 1 },
3312 { 0x0b, HDA_INPUT, 6 },
3313 { 0x0b, HDA_INPUT, 7 },
3314 { } /* end */
3316 #endif
3319 * Common callbacks
3322 static int alc_init(struct hda_codec *codec)
3324 struct alc_spec *spec = codec->spec;
3325 unsigned int i;
3327 alc_fix_pll(codec);
3328 alc_auto_init_amp(codec, spec->init_amp);
3330 for (i = 0; i < spec->num_init_verbs; i++)
3331 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3333 if (spec->init_hook)
3334 spec->init_hook(codec);
3336 return 0;
3339 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3341 struct alc_spec *spec = codec->spec;
3343 if (spec->unsol_event)
3344 spec->unsol_event(codec, res);
3347 #ifdef CONFIG_SND_HDA_POWER_SAVE
3348 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3350 struct alc_spec *spec = codec->spec;
3351 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3353 #endif
3356 * Analog playback callbacks
3358 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3359 struct hda_codec *codec,
3360 struct snd_pcm_substream *substream)
3362 struct alc_spec *spec = codec->spec;
3363 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3364 hinfo);
3367 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3368 struct hda_codec *codec,
3369 unsigned int stream_tag,
3370 unsigned int format,
3371 struct snd_pcm_substream *substream)
3373 struct alc_spec *spec = codec->spec;
3374 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3375 stream_tag, format, substream);
3378 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3379 struct hda_codec *codec,
3380 struct snd_pcm_substream *substream)
3382 struct alc_spec *spec = codec->spec;
3383 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3387 * Digital out
3389 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3390 struct hda_codec *codec,
3391 struct snd_pcm_substream *substream)
3393 struct alc_spec *spec = codec->spec;
3394 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3397 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3398 struct hda_codec *codec,
3399 unsigned int stream_tag,
3400 unsigned int format,
3401 struct snd_pcm_substream *substream)
3403 struct alc_spec *spec = codec->spec;
3404 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3405 stream_tag, format, substream);
3408 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3409 struct hda_codec *codec,
3410 struct snd_pcm_substream *substream)
3412 struct alc_spec *spec = codec->spec;
3413 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3416 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3417 struct hda_codec *codec,
3418 struct snd_pcm_substream *substream)
3420 struct alc_spec *spec = codec->spec;
3421 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3425 * Analog capture
3427 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3428 struct hda_codec *codec,
3429 unsigned int stream_tag,
3430 unsigned int format,
3431 struct snd_pcm_substream *substream)
3433 struct alc_spec *spec = codec->spec;
3435 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3436 stream_tag, 0, format);
3437 return 0;
3440 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3441 struct hda_codec *codec,
3442 struct snd_pcm_substream *substream)
3444 struct alc_spec *spec = codec->spec;
3446 snd_hda_codec_cleanup_stream(codec,
3447 spec->adc_nids[substream->number + 1]);
3448 return 0;
3454 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3455 .substreams = 1,
3456 .channels_min = 2,
3457 .channels_max = 8,
3458 /* NID is set in alc_build_pcms */
3459 .ops = {
3460 .open = alc880_playback_pcm_open,
3461 .prepare = alc880_playback_pcm_prepare,
3462 .cleanup = alc880_playback_pcm_cleanup
3466 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3467 .substreams = 1,
3468 .channels_min = 2,
3469 .channels_max = 2,
3470 /* NID is set in alc_build_pcms */
3473 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3474 .substreams = 1,
3475 .channels_min = 2,
3476 .channels_max = 2,
3477 /* NID is set in alc_build_pcms */
3480 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3481 .substreams = 2, /* can be overridden */
3482 .channels_min = 2,
3483 .channels_max = 2,
3484 /* NID is set in alc_build_pcms */
3485 .ops = {
3486 .prepare = alc880_alt_capture_pcm_prepare,
3487 .cleanup = alc880_alt_capture_pcm_cleanup
3491 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3492 .substreams = 1,
3493 .channels_min = 2,
3494 .channels_max = 2,
3495 /* NID is set in alc_build_pcms */
3496 .ops = {
3497 .open = alc880_dig_playback_pcm_open,
3498 .close = alc880_dig_playback_pcm_close,
3499 .prepare = alc880_dig_playback_pcm_prepare,
3500 .cleanup = alc880_dig_playback_pcm_cleanup
3504 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3505 .substreams = 1,
3506 .channels_min = 2,
3507 .channels_max = 2,
3508 /* NID is set in alc_build_pcms */
3511 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3512 static struct hda_pcm_stream alc_pcm_null_stream = {
3513 .substreams = 0,
3514 .channels_min = 0,
3515 .channels_max = 0,
3518 static int alc_build_pcms(struct hda_codec *codec)
3520 struct alc_spec *spec = codec->spec;
3521 struct hda_pcm *info = spec->pcm_rec;
3522 int i;
3524 codec->num_pcms = 1;
3525 codec->pcm_info = info;
3527 if (spec->no_analog)
3528 goto skip_analog;
3530 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3531 "%s Analog", codec->chip_name);
3532 info->name = spec->stream_name_analog;
3534 if (spec->stream_analog_playback) {
3535 if (snd_BUG_ON(!spec->multiout.dac_nids))
3536 return -EINVAL;
3537 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3538 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3540 if (spec->stream_analog_capture) {
3541 if (snd_BUG_ON(!spec->adc_nids))
3542 return -EINVAL;
3543 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3544 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3547 if (spec->channel_mode) {
3548 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3549 for (i = 0; i < spec->num_channel_mode; i++) {
3550 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3551 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3556 skip_analog:
3557 /* SPDIF for stream index #1 */
3558 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3559 snprintf(spec->stream_name_digital,
3560 sizeof(spec->stream_name_digital),
3561 "%s Digital", codec->chip_name);
3562 codec->num_pcms = 2;
3563 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3564 info = spec->pcm_rec + 1;
3565 info->name = spec->stream_name_digital;
3566 if (spec->dig_out_type)
3567 info->pcm_type = spec->dig_out_type;
3568 else
3569 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3570 if (spec->multiout.dig_out_nid &&
3571 spec->stream_digital_playback) {
3572 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3573 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3575 if (spec->dig_in_nid &&
3576 spec->stream_digital_capture) {
3577 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3578 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3580 /* FIXME: do we need this for all Realtek codec models? */
3581 codec->spdif_status_reset = 1;
3584 if (spec->no_analog)
3585 return 0;
3587 /* If the use of more than one ADC is requested for the current
3588 * model, configure a second analog capture-only PCM.
3590 /* Additional Analaog capture for index #2 */
3591 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3592 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3593 codec->num_pcms = 3;
3594 info = spec->pcm_rec + 2;
3595 info->name = spec->stream_name_analog;
3596 if (spec->alt_dac_nid) {
3597 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3598 *spec->stream_analog_alt_playback;
3599 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3600 spec->alt_dac_nid;
3601 } else {
3602 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3603 alc_pcm_null_stream;
3604 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3606 if (spec->num_adc_nids > 1) {
3607 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3608 *spec->stream_analog_alt_capture;
3609 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3610 spec->adc_nids[1];
3611 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3612 spec->num_adc_nids - 1;
3613 } else {
3614 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3615 alc_pcm_null_stream;
3616 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3620 return 0;
3623 static void alc_free_kctls(struct hda_codec *codec)
3625 struct alc_spec *spec = codec->spec;
3627 if (spec->kctls.list) {
3628 struct snd_kcontrol_new *kctl = spec->kctls.list;
3629 int i;
3630 for (i = 0; i < spec->kctls.used; i++)
3631 kfree(kctl[i].name);
3633 snd_array_free(&spec->kctls);
3636 static void alc_free(struct hda_codec *codec)
3638 struct alc_spec *spec = codec->spec;
3640 if (!spec)
3641 return;
3643 alc_free_kctls(codec);
3644 kfree(spec);
3645 snd_hda_detach_beep_device(codec);
3648 #ifdef CONFIG_SND_HDA_POWER_SAVE
3649 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3651 struct alc_spec *spec = codec->spec;
3652 if (spec && spec->power_hook)
3653 spec->power_hook(codec, 0);
3654 return 0;
3656 #endif
3658 #ifdef SND_HDA_NEEDS_RESUME
3659 static int alc_resume(struct hda_codec *codec)
3661 #ifdef CONFIG_SND_HDA_POWER_SAVE
3662 struct alc_spec *spec = codec->spec;
3663 #endif
3664 codec->patch_ops.init(codec);
3665 snd_hda_codec_resume_amp(codec);
3666 snd_hda_codec_resume_cache(codec);
3667 #ifdef CONFIG_SND_HDA_POWER_SAVE
3668 if (spec && spec->power_hook)
3669 spec->power_hook(codec, 1);
3670 #endif
3671 return 0;
3673 #endif
3677 static struct hda_codec_ops alc_patch_ops = {
3678 .build_controls = alc_build_controls,
3679 .build_pcms = alc_build_pcms,
3680 .init = alc_init,
3681 .free = alc_free,
3682 .unsol_event = alc_unsol_event,
3683 #ifdef SND_HDA_NEEDS_RESUME
3684 .resume = alc_resume,
3685 #endif
3686 #ifdef CONFIG_SND_HDA_POWER_SAVE
3687 .suspend = alc_suspend,
3688 .check_power_status = alc_check_power_status,
3689 #endif
3694 * Test configuration for debugging
3696 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3697 * enum controls.
3699 #ifdef CONFIG_SND_DEBUG
3700 static hda_nid_t alc880_test_dac_nids[4] = {
3701 0x02, 0x03, 0x04, 0x05
3704 static struct hda_input_mux alc880_test_capture_source = {
3705 .num_items = 7,
3706 .items = {
3707 { "In-1", 0x0 },
3708 { "In-2", 0x1 },
3709 { "In-3", 0x2 },
3710 { "In-4", 0x3 },
3711 { "CD", 0x4 },
3712 { "Front", 0x5 },
3713 { "Surround", 0x6 },
3717 static struct hda_channel_mode alc880_test_modes[4] = {
3718 { 2, NULL },
3719 { 4, NULL },
3720 { 6, NULL },
3721 { 8, NULL },
3724 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3725 struct snd_ctl_elem_info *uinfo)
3727 static char *texts[] = {
3728 "N/A", "Line Out", "HP Out",
3729 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3731 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3732 uinfo->count = 1;
3733 uinfo->value.enumerated.items = 8;
3734 if (uinfo->value.enumerated.item >= 8)
3735 uinfo->value.enumerated.item = 7;
3736 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3737 return 0;
3740 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3741 struct snd_ctl_elem_value *ucontrol)
3743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3744 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3745 unsigned int pin_ctl, item = 0;
3747 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3748 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3749 if (pin_ctl & AC_PINCTL_OUT_EN) {
3750 if (pin_ctl & AC_PINCTL_HP_EN)
3751 item = 2;
3752 else
3753 item = 1;
3754 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3755 switch (pin_ctl & AC_PINCTL_VREFEN) {
3756 case AC_PINCTL_VREF_HIZ: item = 3; break;
3757 case AC_PINCTL_VREF_50: item = 4; break;
3758 case AC_PINCTL_VREF_GRD: item = 5; break;
3759 case AC_PINCTL_VREF_80: item = 6; break;
3760 case AC_PINCTL_VREF_100: item = 7; break;
3763 ucontrol->value.enumerated.item[0] = item;
3764 return 0;
3767 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3768 struct snd_ctl_elem_value *ucontrol)
3770 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3771 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3772 static unsigned int ctls[] = {
3773 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3774 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3775 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3776 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3777 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3778 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3780 unsigned int old_ctl, new_ctl;
3782 old_ctl = snd_hda_codec_read(codec, nid, 0,
3783 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3784 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3785 if (old_ctl != new_ctl) {
3786 int val;
3787 snd_hda_codec_write_cache(codec, nid, 0,
3788 AC_VERB_SET_PIN_WIDGET_CONTROL,
3789 new_ctl);
3790 val = ucontrol->value.enumerated.item[0] >= 3 ?
3791 HDA_AMP_MUTE : 0;
3792 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3793 HDA_AMP_MUTE, val);
3794 return 1;
3796 return 0;
3799 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3800 struct snd_ctl_elem_info *uinfo)
3802 static char *texts[] = {
3803 "Front", "Surround", "CLFE", "Side"
3805 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3806 uinfo->count = 1;
3807 uinfo->value.enumerated.items = 4;
3808 if (uinfo->value.enumerated.item >= 4)
3809 uinfo->value.enumerated.item = 3;
3810 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3811 return 0;
3814 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3815 struct snd_ctl_elem_value *ucontrol)
3817 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3818 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3819 unsigned int sel;
3821 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3822 ucontrol->value.enumerated.item[0] = sel & 3;
3823 return 0;
3826 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3827 struct snd_ctl_elem_value *ucontrol)
3829 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3830 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3831 unsigned int sel;
3833 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3834 if (ucontrol->value.enumerated.item[0] != sel) {
3835 sel = ucontrol->value.enumerated.item[0] & 3;
3836 snd_hda_codec_write_cache(codec, nid, 0,
3837 AC_VERB_SET_CONNECT_SEL, sel);
3838 return 1;
3840 return 0;
3843 #define PIN_CTL_TEST(xname,nid) { \
3844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3845 .name = xname, \
3846 .info = alc_test_pin_ctl_info, \
3847 .get = alc_test_pin_ctl_get, \
3848 .put = alc_test_pin_ctl_put, \
3849 .private_value = nid \
3852 #define PIN_SRC_TEST(xname,nid) { \
3853 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3854 .name = xname, \
3855 .info = alc_test_pin_src_info, \
3856 .get = alc_test_pin_src_get, \
3857 .put = alc_test_pin_src_put, \
3858 .private_value = nid \
3861 static struct snd_kcontrol_new alc880_test_mixer[] = {
3862 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3863 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3864 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3865 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3866 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3867 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3868 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3869 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3870 PIN_CTL_TEST("Front Pin Mode", 0x14),
3871 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3872 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3873 PIN_CTL_TEST("Side Pin Mode", 0x17),
3874 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3875 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3876 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3877 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3878 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3879 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3880 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3881 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3882 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3883 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3884 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3885 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3886 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3887 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3888 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3889 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3890 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3891 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3893 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3894 .name = "Channel Mode",
3895 .info = alc_ch_mode_info,
3896 .get = alc_ch_mode_get,
3897 .put = alc_ch_mode_put,
3899 { } /* end */
3902 static struct hda_verb alc880_test_init_verbs[] = {
3903 /* Unmute inputs of 0x0c - 0x0f */
3904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3908 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3909 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3910 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3912 /* Vol output for 0x0c-0x0f */
3913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3914 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3915 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3916 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3917 /* Set output pins 0x14-0x17 */
3918 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3919 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3920 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3921 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3922 /* Unmute output pins 0x14-0x17 */
3923 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3925 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3926 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3927 /* Set input pins 0x18-0x1c */
3928 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3929 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3930 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3931 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3932 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3933 /* Mute input pins 0x18-0x1b */
3934 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3938 /* ADC set up */
3939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3940 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3941 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3942 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3943 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3944 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3945 /* Analog input/passthru */
3946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3953 #endif
3958 static const char *alc880_models[ALC880_MODEL_LAST] = {
3959 [ALC880_3ST] = "3stack",
3960 [ALC880_TCL_S700] = "tcl",
3961 [ALC880_3ST_DIG] = "3stack-digout",
3962 [ALC880_CLEVO] = "clevo",
3963 [ALC880_5ST] = "5stack",
3964 [ALC880_5ST_DIG] = "5stack-digout",
3965 [ALC880_W810] = "w810",
3966 [ALC880_Z71V] = "z71v",
3967 [ALC880_6ST] = "6stack",
3968 [ALC880_6ST_DIG] = "6stack-digout",
3969 [ALC880_ASUS] = "asus",
3970 [ALC880_ASUS_W1V] = "asus-w1v",
3971 [ALC880_ASUS_DIG] = "asus-dig",
3972 [ALC880_ASUS_DIG2] = "asus-dig2",
3973 [ALC880_UNIWILL_DIG] = "uniwill",
3974 [ALC880_UNIWILL_P53] = "uniwill-p53",
3975 [ALC880_FUJITSU] = "fujitsu",
3976 [ALC880_F1734] = "F1734",
3977 [ALC880_LG] = "lg",
3978 [ALC880_LG_LW] = "lg-lw",
3979 [ALC880_MEDION_RIM] = "medion",
3980 #ifdef CONFIG_SND_DEBUG
3981 [ALC880_TEST] = "test",
3982 #endif
3983 [ALC880_AUTO] = "auto",
3986 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3987 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3988 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3989 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3990 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3991 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3992 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3993 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3994 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3995 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3996 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3997 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3998 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3999 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4000 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4001 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4002 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4003 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4004 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4005 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4006 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4007 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4008 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4009 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4010 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4011 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4012 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4013 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4014 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4015 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4016 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4017 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4018 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4019 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4020 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4021 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4022 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4023 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4024 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4025 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4026 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4027 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4028 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4029 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4030 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4031 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4032 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4033 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4034 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4035 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4036 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4037 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4038 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4039 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4040 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4041 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4042 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4043 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4044 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4045 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4046 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4047 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4048 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4049 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4050 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4051 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4052 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4053 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4054 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4055 /* default Intel */
4056 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4057 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4058 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4063 * ALC880 codec presets
4065 static struct alc_config_preset alc880_presets[] = {
4066 [ALC880_3ST] = {
4067 .mixers = { alc880_three_stack_mixer },
4068 .init_verbs = { alc880_volume_init_verbs,
4069 alc880_pin_3stack_init_verbs },
4070 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4071 .dac_nids = alc880_dac_nids,
4072 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4073 .channel_mode = alc880_threestack_modes,
4074 .need_dac_fix = 1,
4075 .input_mux = &alc880_capture_source,
4077 [ALC880_3ST_DIG] = {
4078 .mixers = { alc880_three_stack_mixer },
4079 .init_verbs = { alc880_volume_init_verbs,
4080 alc880_pin_3stack_init_verbs },
4081 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4082 .dac_nids = alc880_dac_nids,
4083 .dig_out_nid = ALC880_DIGOUT_NID,
4084 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4085 .channel_mode = alc880_threestack_modes,
4086 .need_dac_fix = 1,
4087 .input_mux = &alc880_capture_source,
4089 [ALC880_TCL_S700] = {
4090 .mixers = { alc880_tcl_s700_mixer },
4091 .init_verbs = { alc880_volume_init_verbs,
4092 alc880_pin_tcl_S700_init_verbs,
4093 alc880_gpio2_init_verbs },
4094 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4095 .dac_nids = alc880_dac_nids,
4096 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4097 .num_adc_nids = 1, /* single ADC */
4098 .hp_nid = 0x03,
4099 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4100 .channel_mode = alc880_2_jack_modes,
4101 .input_mux = &alc880_capture_source,
4103 [ALC880_5ST] = {
4104 .mixers = { alc880_three_stack_mixer,
4105 alc880_five_stack_mixer},
4106 .init_verbs = { alc880_volume_init_verbs,
4107 alc880_pin_5stack_init_verbs },
4108 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4109 .dac_nids = alc880_dac_nids,
4110 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4111 .channel_mode = alc880_fivestack_modes,
4112 .input_mux = &alc880_capture_source,
4114 [ALC880_5ST_DIG] = {
4115 .mixers = { alc880_three_stack_mixer,
4116 alc880_five_stack_mixer },
4117 .init_verbs = { alc880_volume_init_verbs,
4118 alc880_pin_5stack_init_verbs },
4119 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4120 .dac_nids = alc880_dac_nids,
4121 .dig_out_nid = ALC880_DIGOUT_NID,
4122 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4123 .channel_mode = alc880_fivestack_modes,
4124 .input_mux = &alc880_capture_source,
4126 [ALC880_6ST] = {
4127 .mixers = { alc880_six_stack_mixer },
4128 .init_verbs = { alc880_volume_init_verbs,
4129 alc880_pin_6stack_init_verbs },
4130 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4131 .dac_nids = alc880_6st_dac_nids,
4132 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4133 .channel_mode = alc880_sixstack_modes,
4134 .input_mux = &alc880_6stack_capture_source,
4136 [ALC880_6ST_DIG] = {
4137 .mixers = { alc880_six_stack_mixer },
4138 .init_verbs = { alc880_volume_init_verbs,
4139 alc880_pin_6stack_init_verbs },
4140 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4141 .dac_nids = alc880_6st_dac_nids,
4142 .dig_out_nid = ALC880_DIGOUT_NID,
4143 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4144 .channel_mode = alc880_sixstack_modes,
4145 .input_mux = &alc880_6stack_capture_source,
4147 [ALC880_W810] = {
4148 .mixers = { alc880_w810_base_mixer },
4149 .init_verbs = { alc880_volume_init_verbs,
4150 alc880_pin_w810_init_verbs,
4151 alc880_gpio2_init_verbs },
4152 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4153 .dac_nids = alc880_w810_dac_nids,
4154 .dig_out_nid = ALC880_DIGOUT_NID,
4155 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4156 .channel_mode = alc880_w810_modes,
4157 .input_mux = &alc880_capture_source,
4159 [ALC880_Z71V] = {
4160 .mixers = { alc880_z71v_mixer },
4161 .init_verbs = { alc880_volume_init_verbs,
4162 alc880_pin_z71v_init_verbs },
4163 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4164 .dac_nids = alc880_z71v_dac_nids,
4165 .dig_out_nid = ALC880_DIGOUT_NID,
4166 .hp_nid = 0x03,
4167 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4168 .channel_mode = alc880_2_jack_modes,
4169 .input_mux = &alc880_capture_source,
4171 [ALC880_F1734] = {
4172 .mixers = { alc880_f1734_mixer },
4173 .init_verbs = { alc880_volume_init_verbs,
4174 alc880_pin_f1734_init_verbs },
4175 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4176 .dac_nids = alc880_f1734_dac_nids,
4177 .hp_nid = 0x02,
4178 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4179 .channel_mode = alc880_2_jack_modes,
4180 .input_mux = &alc880_f1734_capture_source,
4181 .unsol_event = alc880_uniwill_p53_unsol_event,
4182 .setup = alc880_uniwill_p53_setup,
4183 .init_hook = alc_automute_amp,
4185 [ALC880_ASUS] = {
4186 .mixers = { alc880_asus_mixer },
4187 .init_verbs = { alc880_volume_init_verbs,
4188 alc880_pin_asus_init_verbs,
4189 alc880_gpio1_init_verbs },
4190 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4191 .dac_nids = alc880_asus_dac_nids,
4192 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4193 .channel_mode = alc880_asus_modes,
4194 .need_dac_fix = 1,
4195 .input_mux = &alc880_capture_source,
4197 [ALC880_ASUS_DIG] = {
4198 .mixers = { alc880_asus_mixer },
4199 .init_verbs = { alc880_volume_init_verbs,
4200 alc880_pin_asus_init_verbs,
4201 alc880_gpio1_init_verbs },
4202 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4203 .dac_nids = alc880_asus_dac_nids,
4204 .dig_out_nid = ALC880_DIGOUT_NID,
4205 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4206 .channel_mode = alc880_asus_modes,
4207 .need_dac_fix = 1,
4208 .input_mux = &alc880_capture_source,
4210 [ALC880_ASUS_DIG2] = {
4211 .mixers = { alc880_asus_mixer },
4212 .init_verbs = { alc880_volume_init_verbs,
4213 alc880_pin_asus_init_verbs,
4214 alc880_gpio2_init_verbs }, /* use GPIO2 */
4215 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4216 .dac_nids = alc880_asus_dac_nids,
4217 .dig_out_nid = ALC880_DIGOUT_NID,
4218 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4219 .channel_mode = alc880_asus_modes,
4220 .need_dac_fix = 1,
4221 .input_mux = &alc880_capture_source,
4223 [ALC880_ASUS_W1V] = {
4224 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4225 .init_verbs = { alc880_volume_init_verbs,
4226 alc880_pin_asus_init_verbs,
4227 alc880_gpio1_init_verbs },
4228 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4229 .dac_nids = alc880_asus_dac_nids,
4230 .dig_out_nid = ALC880_DIGOUT_NID,
4231 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4232 .channel_mode = alc880_asus_modes,
4233 .need_dac_fix = 1,
4234 .input_mux = &alc880_capture_source,
4236 [ALC880_UNIWILL_DIG] = {
4237 .mixers = { alc880_asus_mixer },
4238 .init_verbs = { alc880_volume_init_verbs,
4239 alc880_pin_asus_init_verbs },
4240 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4241 .dac_nids = alc880_asus_dac_nids,
4242 .dig_out_nid = ALC880_DIGOUT_NID,
4243 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4244 .channel_mode = alc880_asus_modes,
4245 .need_dac_fix = 1,
4246 .input_mux = &alc880_capture_source,
4248 [ALC880_UNIWILL] = {
4249 .mixers = { alc880_uniwill_mixer },
4250 .init_verbs = { alc880_volume_init_verbs,
4251 alc880_uniwill_init_verbs },
4252 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4253 .dac_nids = alc880_asus_dac_nids,
4254 .dig_out_nid = ALC880_DIGOUT_NID,
4255 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4256 .channel_mode = alc880_threestack_modes,
4257 .need_dac_fix = 1,
4258 .input_mux = &alc880_capture_source,
4259 .unsol_event = alc880_uniwill_unsol_event,
4260 .setup = alc880_uniwill_setup,
4261 .init_hook = alc880_uniwill_init_hook,
4263 [ALC880_UNIWILL_P53] = {
4264 .mixers = { alc880_uniwill_p53_mixer },
4265 .init_verbs = { alc880_volume_init_verbs,
4266 alc880_uniwill_p53_init_verbs },
4267 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4268 .dac_nids = alc880_asus_dac_nids,
4269 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4270 .channel_mode = alc880_threestack_modes,
4271 .input_mux = &alc880_capture_source,
4272 .unsol_event = alc880_uniwill_p53_unsol_event,
4273 .setup = alc880_uniwill_p53_setup,
4274 .init_hook = alc_automute_amp,
4276 [ALC880_FUJITSU] = {
4277 .mixers = { alc880_fujitsu_mixer },
4278 .init_verbs = { alc880_volume_init_verbs,
4279 alc880_uniwill_p53_init_verbs,
4280 alc880_beep_init_verbs },
4281 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4282 .dac_nids = alc880_dac_nids,
4283 .dig_out_nid = ALC880_DIGOUT_NID,
4284 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4285 .channel_mode = alc880_2_jack_modes,
4286 .input_mux = &alc880_capture_source,
4287 .unsol_event = alc880_uniwill_p53_unsol_event,
4288 .setup = alc880_uniwill_p53_setup,
4289 .init_hook = alc_automute_amp,
4291 [ALC880_CLEVO] = {
4292 .mixers = { alc880_three_stack_mixer },
4293 .init_verbs = { alc880_volume_init_verbs,
4294 alc880_pin_clevo_init_verbs },
4295 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4296 .dac_nids = alc880_dac_nids,
4297 .hp_nid = 0x03,
4298 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4299 .channel_mode = alc880_threestack_modes,
4300 .need_dac_fix = 1,
4301 .input_mux = &alc880_capture_source,
4303 [ALC880_LG] = {
4304 .mixers = { alc880_lg_mixer },
4305 .init_verbs = { alc880_volume_init_verbs,
4306 alc880_lg_init_verbs },
4307 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4308 .dac_nids = alc880_lg_dac_nids,
4309 .dig_out_nid = ALC880_DIGOUT_NID,
4310 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4311 .channel_mode = alc880_lg_ch_modes,
4312 .need_dac_fix = 1,
4313 .input_mux = &alc880_lg_capture_source,
4314 .unsol_event = alc_automute_amp_unsol_event,
4315 .setup = alc880_lg_setup,
4316 .init_hook = alc_automute_amp,
4317 #ifdef CONFIG_SND_HDA_POWER_SAVE
4318 .loopbacks = alc880_lg_loopbacks,
4319 #endif
4321 [ALC880_LG_LW] = {
4322 .mixers = { alc880_lg_lw_mixer },
4323 .init_verbs = { alc880_volume_init_verbs,
4324 alc880_lg_lw_init_verbs },
4325 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4326 .dac_nids = alc880_dac_nids,
4327 .dig_out_nid = ALC880_DIGOUT_NID,
4328 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4329 .channel_mode = alc880_lg_lw_modes,
4330 .input_mux = &alc880_lg_lw_capture_source,
4331 .unsol_event = alc_automute_amp_unsol_event,
4332 .setup = alc880_lg_lw_setup,
4333 .init_hook = alc_automute_amp,
4335 [ALC880_MEDION_RIM] = {
4336 .mixers = { alc880_medion_rim_mixer },
4337 .init_verbs = { alc880_volume_init_verbs,
4338 alc880_medion_rim_init_verbs,
4339 alc_gpio2_init_verbs },
4340 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4341 .dac_nids = alc880_dac_nids,
4342 .dig_out_nid = ALC880_DIGOUT_NID,
4343 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4344 .channel_mode = alc880_2_jack_modes,
4345 .input_mux = &alc880_medion_rim_capture_source,
4346 .unsol_event = alc880_medion_rim_unsol_event,
4347 .setup = alc880_medion_rim_setup,
4348 .init_hook = alc880_medion_rim_automute,
4350 #ifdef CONFIG_SND_DEBUG
4351 [ALC880_TEST] = {
4352 .mixers = { alc880_test_mixer },
4353 .init_verbs = { alc880_test_init_verbs },
4354 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4355 .dac_nids = alc880_test_dac_nids,
4356 .dig_out_nid = ALC880_DIGOUT_NID,
4357 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4358 .channel_mode = alc880_test_modes,
4359 .input_mux = &alc880_test_capture_source,
4361 #endif
4365 * Automatic parse of I/O pins from the BIOS configuration
4368 enum {
4369 ALC_CTL_WIDGET_VOL,
4370 ALC_CTL_WIDGET_MUTE,
4371 ALC_CTL_BIND_MUTE,
4373 static struct snd_kcontrol_new alc880_control_templates[] = {
4374 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4375 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4376 HDA_BIND_MUTE(NULL, 0, 0, 0),
4379 /* add dynamic controls */
4380 static int add_control(struct alc_spec *spec, int type, const char *name,
4381 unsigned long val)
4383 struct snd_kcontrol_new *knew;
4385 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4386 knew = snd_array_new(&spec->kctls);
4387 if (!knew)
4388 return -ENOMEM;
4389 *knew = alc880_control_templates[type];
4390 knew->name = kstrdup(name, GFP_KERNEL);
4391 if (!knew->name)
4392 return -ENOMEM;
4393 if (get_amp_nid_(val))
4394 knew->subdevice = HDA_SUBDEV_NID_FLAG | get_amp_nid_(val);
4395 knew->private_value = val;
4396 return 0;
4399 static int add_control_with_pfx(struct alc_spec *spec, int type,
4400 const char *pfx, const char *dir,
4401 const char *sfx, unsigned long val)
4403 char name[32];
4404 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4405 return add_control(spec, type, name, val);
4408 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4409 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4410 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4411 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4413 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4414 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4415 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4416 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4417 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4418 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4419 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4420 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4421 #define ALC880_PIN_CD_NID 0x1c
4423 /* fill in the dac_nids table from the parsed pin configuration */
4424 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4425 const struct auto_pin_cfg *cfg)
4427 hda_nid_t nid;
4428 int assigned[4];
4429 int i, j;
4431 memset(assigned, 0, sizeof(assigned));
4432 spec->multiout.dac_nids = spec->private_dac_nids;
4434 /* check the pins hardwired to audio widget */
4435 for (i = 0; i < cfg->line_outs; i++) {
4436 nid = cfg->line_out_pins[i];
4437 if (alc880_is_fixed_pin(nid)) {
4438 int idx = alc880_fixed_pin_idx(nid);
4439 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4440 assigned[idx] = 1;
4443 /* left pins can be connect to any audio widget */
4444 for (i = 0; i < cfg->line_outs; i++) {
4445 nid = cfg->line_out_pins[i];
4446 if (alc880_is_fixed_pin(nid))
4447 continue;
4448 /* search for an empty channel */
4449 for (j = 0; j < cfg->line_outs; j++) {
4450 if (!assigned[j]) {
4451 spec->multiout.dac_nids[i] =
4452 alc880_idx_to_dac(j);
4453 assigned[j] = 1;
4454 break;
4458 spec->multiout.num_dacs = cfg->line_outs;
4459 return 0;
4462 /* add playback controls from the parsed DAC table */
4463 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4464 const struct auto_pin_cfg *cfg)
4466 static const char *chname[4] = {
4467 "Front", "Surround", NULL /*CLFE*/, "Side"
4469 hda_nid_t nid;
4470 int i, err;
4472 for (i = 0; i < cfg->line_outs; i++) {
4473 if (!spec->multiout.dac_nids[i])
4474 continue;
4475 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4476 if (i == 2) {
4477 /* Center/LFE */
4478 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4479 "Center",
4480 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4481 HDA_OUTPUT));
4482 if (err < 0)
4483 return err;
4484 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4485 "LFE",
4486 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4487 HDA_OUTPUT));
4488 if (err < 0)
4489 return err;
4490 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4491 "Center",
4492 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4493 HDA_INPUT));
4494 if (err < 0)
4495 return err;
4496 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4497 "LFE",
4498 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4499 HDA_INPUT));
4500 if (err < 0)
4501 return err;
4502 } else {
4503 const char *pfx;
4504 if (cfg->line_outs == 1 &&
4505 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4506 pfx = "Speaker";
4507 else
4508 pfx = chname[i];
4509 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4510 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4511 HDA_OUTPUT));
4512 if (err < 0)
4513 return err;
4514 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4515 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4516 HDA_INPUT));
4517 if (err < 0)
4518 return err;
4521 return 0;
4524 /* add playback controls for speaker and HP outputs */
4525 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4526 const char *pfx)
4528 hda_nid_t nid;
4529 int err;
4531 if (!pin)
4532 return 0;
4534 if (alc880_is_fixed_pin(pin)) {
4535 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4536 /* specify the DAC as the extra output */
4537 if (!spec->multiout.hp_nid)
4538 spec->multiout.hp_nid = nid;
4539 else
4540 spec->multiout.extra_out_nid[0] = nid;
4541 /* control HP volume/switch on the output mixer amp */
4542 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4543 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4544 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4545 if (err < 0)
4546 return err;
4547 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4548 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4549 if (err < 0)
4550 return err;
4551 } else if (alc880_is_multi_pin(pin)) {
4552 /* set manual connection */
4553 /* we have only a switch on HP-out PIN */
4554 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4555 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4556 if (err < 0)
4557 return err;
4559 return 0;
4562 /* create input playback/capture controls for the given pin */
4563 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4564 const char *ctlname,
4565 int idx, hda_nid_t mix_nid)
4567 int err;
4569 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4570 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4571 if (err < 0)
4572 return err;
4573 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4574 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4575 if (err < 0)
4576 return err;
4577 return 0;
4580 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4582 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4583 return (pincap & AC_PINCAP_IN) != 0;
4586 /* create playback/capture controls for input pins */
4587 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4588 const struct auto_pin_cfg *cfg,
4589 hda_nid_t mixer,
4590 hda_nid_t cap1, hda_nid_t cap2)
4592 struct alc_spec *spec = codec->spec;
4593 struct hda_input_mux *imux = &spec->private_imux[0];
4594 int i, err, idx;
4596 for (i = 0; i < AUTO_PIN_LAST; i++) {
4597 hda_nid_t pin;
4599 pin = cfg->input_pins[i];
4600 if (!alc_is_input_pin(codec, pin))
4601 continue;
4603 if (mixer) {
4604 idx = get_connection_index(codec, mixer, pin);
4605 if (idx >= 0) {
4606 err = new_analog_input(spec, pin,
4607 auto_pin_cfg_labels[i],
4608 idx, mixer);
4609 if (err < 0)
4610 return err;
4614 if (!cap1)
4615 continue;
4616 idx = get_connection_index(codec, cap1, pin);
4617 if (idx < 0 && cap2)
4618 idx = get_connection_index(codec, cap2, pin);
4619 if (idx >= 0) {
4620 imux->items[imux->num_items].label =
4621 auto_pin_cfg_labels[i];
4622 imux->items[imux->num_items].index = idx;
4623 imux->num_items++;
4626 return 0;
4629 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4630 const struct auto_pin_cfg *cfg)
4632 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4635 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4636 unsigned int pin_type)
4638 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4639 pin_type);
4640 /* unmute pin */
4641 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4642 AMP_OUT_UNMUTE);
4645 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4646 hda_nid_t nid, int pin_type,
4647 int dac_idx)
4649 alc_set_pin_output(codec, nid, pin_type);
4650 /* need the manual connection? */
4651 if (alc880_is_multi_pin(nid)) {
4652 struct alc_spec *spec = codec->spec;
4653 int idx = alc880_multi_pin_idx(nid);
4654 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4655 AC_VERB_SET_CONNECT_SEL,
4656 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4660 static int get_pin_type(int line_out_type)
4662 if (line_out_type == AUTO_PIN_HP_OUT)
4663 return PIN_HP;
4664 else
4665 return PIN_OUT;
4668 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4670 struct alc_spec *spec = codec->spec;
4671 int i;
4673 for (i = 0; i < spec->autocfg.line_outs; i++) {
4674 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4675 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4676 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4680 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4682 struct alc_spec *spec = codec->spec;
4683 hda_nid_t pin;
4685 pin = spec->autocfg.speaker_pins[0];
4686 if (pin) /* connect to front */
4687 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4688 pin = spec->autocfg.hp_pins[0];
4689 if (pin) /* connect to front */
4690 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4693 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4695 struct alc_spec *spec = codec->spec;
4696 int i;
4698 for (i = 0; i < AUTO_PIN_LAST; i++) {
4699 hda_nid_t nid = spec->autocfg.input_pins[i];
4700 if (alc_is_input_pin(codec, nid)) {
4701 alc_set_input_pin(codec, nid, i);
4702 if (nid != ALC880_PIN_CD_NID &&
4703 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4704 snd_hda_codec_write(codec, nid, 0,
4705 AC_VERB_SET_AMP_GAIN_MUTE,
4706 AMP_OUT_MUTE);
4711 /* parse the BIOS configuration and set up the alc_spec */
4712 /* return 1 if successful, 0 if the proper config is not found,
4713 * or a negative error code
4715 static int alc880_parse_auto_config(struct hda_codec *codec)
4717 struct alc_spec *spec = codec->spec;
4718 int i, err;
4719 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4721 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4722 alc880_ignore);
4723 if (err < 0)
4724 return err;
4725 if (!spec->autocfg.line_outs)
4726 return 0; /* can't find valid BIOS pin config */
4728 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4729 if (err < 0)
4730 return err;
4731 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4732 if (err < 0)
4733 return err;
4734 err = alc880_auto_create_extra_out(spec,
4735 spec->autocfg.speaker_pins[0],
4736 "Speaker");
4737 if (err < 0)
4738 return err;
4739 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4740 "Headphone");
4741 if (err < 0)
4742 return err;
4743 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4744 if (err < 0)
4745 return err;
4747 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4749 /* check multiple SPDIF-out (for recent codecs) */
4750 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4751 hda_nid_t dig_nid;
4752 err = snd_hda_get_connections(codec,
4753 spec->autocfg.dig_out_pins[i],
4754 &dig_nid, 1);
4755 if (err < 0)
4756 continue;
4757 if (!i)
4758 spec->multiout.dig_out_nid = dig_nid;
4759 else {
4760 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4761 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4762 break;
4763 spec->slave_dig_outs[i - 1] = dig_nid;
4766 if (spec->autocfg.dig_in_pin)
4767 spec->dig_in_nid = ALC880_DIGIN_NID;
4769 if (spec->kctls.list)
4770 add_mixer(spec, spec->kctls.list);
4772 add_verb(spec, alc880_volume_init_verbs);
4774 spec->num_mux_defs = 1;
4775 spec->input_mux = &spec->private_imux[0];
4777 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4779 return 1;
4782 /* additional initialization for auto-configuration model */
4783 static void alc880_auto_init(struct hda_codec *codec)
4785 struct alc_spec *spec = codec->spec;
4786 alc880_auto_init_multi_out(codec);
4787 alc880_auto_init_extra_out(codec);
4788 alc880_auto_init_analog_input(codec);
4789 if (spec->unsol_event)
4790 alc_inithook(codec);
4793 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4794 * one of two digital mic pins, e.g. on ALC272
4796 static void fixup_automic_adc(struct hda_codec *codec)
4798 struct alc_spec *spec = codec->spec;
4799 int i;
4801 for (i = 0; i < spec->num_adc_nids; i++) {
4802 hda_nid_t cap = spec->capsrc_nids ?
4803 spec->capsrc_nids[i] : spec->adc_nids[i];
4804 int iidx, eidx;
4806 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4807 if (iidx < 0)
4808 continue;
4809 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4810 if (eidx < 0)
4811 continue;
4812 spec->int_mic.mux_idx = iidx;
4813 spec->ext_mic.mux_idx = eidx;
4814 if (spec->capsrc_nids)
4815 spec->capsrc_nids += i;
4816 spec->adc_nids += i;
4817 spec->num_adc_nids = 1;
4818 return;
4820 snd_printd(KERN_INFO "hda_codec: %s: "
4821 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4822 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4823 spec->auto_mic = 0; /* disable auto-mic to be sure */
4826 /* choose the ADC/MUX containing the input pin and initialize the setup */
4827 static void fixup_single_adc(struct hda_codec *codec)
4829 struct alc_spec *spec = codec->spec;
4830 hda_nid_t pin;
4831 int i;
4833 /* search for the input pin; there must be only one */
4834 for (i = 0; i < AUTO_PIN_LAST; i++) {
4835 if (spec->autocfg.input_pins[i]) {
4836 pin = spec->autocfg.input_pins[i];
4837 break;
4840 if (!pin)
4841 return;
4843 /* set the default connection to that pin */
4844 for (i = 0; i < spec->num_adc_nids; i++) {
4845 hda_nid_t cap = spec->capsrc_nids ?
4846 spec->capsrc_nids[i] : spec->adc_nids[i];
4847 int idx;
4849 idx = get_connection_index(codec, cap, pin);
4850 if (idx < 0)
4851 continue;
4852 /* use only this ADC */
4853 if (spec->capsrc_nids)
4854 spec->capsrc_nids += i;
4855 spec->adc_nids += i;
4856 spec->num_adc_nids = 1;
4857 /* select or unmute this route */
4858 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
4859 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
4860 HDA_AMP_MUTE, 0);
4861 } else {
4862 snd_hda_codec_write_cache(codec, cap, 0,
4863 AC_VERB_SET_CONNECT_SEL, idx);
4865 return;
4869 static void set_capture_mixer(struct hda_codec *codec)
4871 struct alc_spec *spec = codec->spec;
4872 static struct snd_kcontrol_new *caps[2][3] = {
4873 { alc_capture_mixer_nosrc1,
4874 alc_capture_mixer_nosrc2,
4875 alc_capture_mixer_nosrc3 },
4876 { alc_capture_mixer1,
4877 alc_capture_mixer2,
4878 alc_capture_mixer3 },
4880 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4881 int mux = 0;
4882 if (spec->auto_mic)
4883 fixup_automic_adc(codec);
4884 else if (spec->input_mux) {
4885 if (spec->input_mux->num_items > 1)
4886 mux = 1;
4887 else if (spec->input_mux->num_items == 1)
4888 fixup_single_adc(codec);
4890 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4894 #ifdef CONFIG_SND_HDA_INPUT_BEEP
4895 #define set_beep_amp(spec, nid, idx, dir) \
4896 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4897 #else
4898 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
4899 #endif
4902 * OK, here we have finally the patch for ALC880
4905 static int patch_alc880(struct hda_codec *codec)
4907 struct alc_spec *spec;
4908 int board_config;
4909 int err;
4911 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4912 if (spec == NULL)
4913 return -ENOMEM;
4915 codec->spec = spec;
4917 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4918 alc880_models,
4919 alc880_cfg_tbl);
4920 if (board_config < 0) {
4921 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4922 codec->chip_name);
4923 board_config = ALC880_AUTO;
4926 if (board_config == ALC880_AUTO) {
4927 /* automatic parse from the BIOS config */
4928 err = alc880_parse_auto_config(codec);
4929 if (err < 0) {
4930 alc_free(codec);
4931 return err;
4932 } else if (!err) {
4933 printk(KERN_INFO
4934 "hda_codec: Cannot set up configuration "
4935 "from BIOS. Using 3-stack mode...\n");
4936 board_config = ALC880_3ST;
4940 err = snd_hda_attach_beep_device(codec, 0x1);
4941 if (err < 0) {
4942 alc_free(codec);
4943 return err;
4946 if (board_config != ALC880_AUTO)
4947 setup_preset(codec, &alc880_presets[board_config]);
4949 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4950 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4951 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4953 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4954 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4956 if (!spec->adc_nids && spec->input_mux) {
4957 /* check whether NID 0x07 is valid */
4958 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4959 /* get type */
4960 wcap = get_wcaps_type(wcap);
4961 if (wcap != AC_WID_AUD_IN) {
4962 spec->adc_nids = alc880_adc_nids_alt;
4963 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4964 } else {
4965 spec->adc_nids = alc880_adc_nids;
4966 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4969 set_capture_mixer(codec);
4970 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4972 spec->vmaster_nid = 0x0c;
4974 codec->patch_ops = alc_patch_ops;
4975 if (board_config == ALC880_AUTO)
4976 spec->init_hook = alc880_auto_init;
4977 #ifdef CONFIG_SND_HDA_POWER_SAVE
4978 if (!spec->loopback.amplist)
4979 spec->loopback.amplist = alc880_loopbacks;
4980 #endif
4981 codec->proc_widget_hook = print_realtek_coef;
4983 return 0;
4988 * ALC260 support
4991 static hda_nid_t alc260_dac_nids[1] = {
4992 /* front */
4993 0x02,
4996 static hda_nid_t alc260_adc_nids[1] = {
4997 /* ADC0 */
4998 0x04,
5001 static hda_nid_t alc260_adc_nids_alt[1] = {
5002 /* ADC1 */
5003 0x05,
5006 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5007 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5009 static hda_nid_t alc260_dual_adc_nids[2] = {
5010 /* ADC0, ADC1 */
5011 0x04, 0x05
5014 #define ALC260_DIGOUT_NID 0x03
5015 #define ALC260_DIGIN_NID 0x06
5017 static struct hda_input_mux alc260_capture_source = {
5018 .num_items = 4,
5019 .items = {
5020 { "Mic", 0x0 },
5021 { "Front Mic", 0x1 },
5022 { "Line", 0x2 },
5023 { "CD", 0x4 },
5027 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5028 * headphone jack and the internal CD lines since these are the only pins at
5029 * which audio can appear. For flexibility, also allow the option of
5030 * recording the mixer output on the second ADC (ADC0 doesn't have a
5031 * connection to the mixer output).
5033 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5035 .num_items = 3,
5036 .items = {
5037 { "Mic/Line", 0x0 },
5038 { "CD", 0x4 },
5039 { "Headphone", 0x2 },
5043 .num_items = 4,
5044 .items = {
5045 { "Mic/Line", 0x0 },
5046 { "CD", 0x4 },
5047 { "Headphone", 0x2 },
5048 { "Mixer", 0x5 },
5054 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5055 * the Fujitsu S702x, but jacks are marked differently.
5057 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5059 .num_items = 4,
5060 .items = {
5061 { "Mic", 0x0 },
5062 { "Line", 0x2 },
5063 { "CD", 0x4 },
5064 { "Headphone", 0x5 },
5068 .num_items = 5,
5069 .items = {
5070 { "Mic", 0x0 },
5071 { "Line", 0x2 },
5072 { "CD", 0x4 },
5073 { "Headphone", 0x6 },
5074 { "Mixer", 0x5 },
5079 /* Maxdata Favorit 100XS */
5080 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5082 .num_items = 2,
5083 .items = {
5084 { "Line/Mic", 0x0 },
5085 { "CD", 0x4 },
5089 .num_items = 3,
5090 .items = {
5091 { "Line/Mic", 0x0 },
5092 { "CD", 0x4 },
5093 { "Mixer", 0x5 },
5099 * This is just place-holder, so there's something for alc_build_pcms to look
5100 * at when it calculates the maximum number of channels. ALC260 has no mixer
5101 * element which allows changing the channel mode, so the verb list is
5102 * never used.
5104 static struct hda_channel_mode alc260_modes[1] = {
5105 { 2, NULL },
5109 /* Mixer combinations
5111 * basic: base_output + input + pc_beep + capture
5112 * HP: base_output + input + capture_alt
5113 * HP_3013: hp_3013 + input + capture
5114 * fujitsu: fujitsu + capture
5115 * acer: acer + capture
5118 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5119 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5120 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5121 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5122 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5123 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5124 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5125 { } /* end */
5128 static struct snd_kcontrol_new alc260_input_mixer[] = {
5129 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5130 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5131 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5132 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5134 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5135 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5136 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5137 { } /* end */
5140 /* update HP, line and mono out pins according to the master switch */
5141 static void alc260_hp_master_update(struct hda_codec *codec,
5142 hda_nid_t hp, hda_nid_t line,
5143 hda_nid_t mono)
5145 struct alc_spec *spec = codec->spec;
5146 unsigned int val = spec->master_sw ? PIN_HP : 0;
5147 /* change HP and line-out pins */
5148 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5149 val);
5150 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5151 val);
5152 /* mono (speaker) depending on the HP jack sense */
5153 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5154 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5155 val);
5158 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5159 struct snd_ctl_elem_value *ucontrol)
5161 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5162 struct alc_spec *spec = codec->spec;
5163 *ucontrol->value.integer.value = spec->master_sw;
5164 return 0;
5167 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5168 struct snd_ctl_elem_value *ucontrol)
5170 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5171 struct alc_spec *spec = codec->spec;
5172 int val = !!*ucontrol->value.integer.value;
5173 hda_nid_t hp, line, mono;
5175 if (val == spec->master_sw)
5176 return 0;
5177 spec->master_sw = val;
5178 hp = (kcontrol->private_value >> 16) & 0xff;
5179 line = (kcontrol->private_value >> 8) & 0xff;
5180 mono = kcontrol->private_value & 0xff;
5181 alc260_hp_master_update(codec, hp, line, mono);
5182 return 1;
5185 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5188 .name = "Master Playback Switch",
5189 .info = snd_ctl_boolean_mono_info,
5190 .get = alc260_hp_master_sw_get,
5191 .put = alc260_hp_master_sw_put,
5192 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5194 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5195 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5196 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5197 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5198 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5199 HDA_OUTPUT),
5200 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5201 { } /* end */
5204 static struct hda_verb alc260_hp_unsol_verbs[] = {
5205 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5209 static void alc260_hp_automute(struct hda_codec *codec)
5211 struct alc_spec *spec = codec->spec;
5213 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5214 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5217 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5219 if ((res >> 26) == ALC880_HP_EVENT)
5220 alc260_hp_automute(codec);
5223 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5226 .name = "Master Playback Switch",
5227 .info = snd_ctl_boolean_mono_info,
5228 .get = alc260_hp_master_sw_get,
5229 .put = alc260_hp_master_sw_put,
5230 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5232 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5233 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5234 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5235 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5236 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5238 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5239 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5240 { } /* end */
5243 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5244 .ops = &snd_hda_bind_vol,
5245 .values = {
5246 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5247 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5248 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5253 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5254 .ops = &snd_hda_bind_sw,
5255 .values = {
5256 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5257 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5262 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5263 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5264 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5265 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5267 { } /* end */
5270 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5275 static void alc260_hp_3013_automute(struct hda_codec *codec)
5277 struct alc_spec *spec = codec->spec;
5279 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5280 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5283 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5284 unsigned int res)
5286 if ((res >> 26) == ALC880_HP_EVENT)
5287 alc260_hp_3013_automute(codec);
5290 static void alc260_hp_3012_automute(struct hda_codec *codec)
5292 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5294 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5295 bits);
5296 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5297 bits);
5298 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5299 bits);
5302 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5303 unsigned int res)
5305 if ((res >> 26) == ALC880_HP_EVENT)
5306 alc260_hp_3012_automute(codec);
5309 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5310 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5312 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5313 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5314 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5315 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5316 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5317 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5318 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5319 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5320 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5321 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5322 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5323 { } /* end */
5326 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5327 * versions of the ALC260 don't act on requests to enable mic bias from NID
5328 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5329 * datasheet doesn't mention this restriction. At this stage it's not clear
5330 * whether this behaviour is intentional or is a hardware bug in chip
5331 * revisions available in early 2006. Therefore for now allow the
5332 * "Headphone Jack Mode" control to span all choices, but if it turns out
5333 * that the lack of mic bias for this NID is intentional we could change the
5334 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5336 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5337 * don't appear to make the mic bias available from the "line" jack, even
5338 * though the NID used for this jack (0x14) can supply it. The theory is
5339 * that perhaps Acer have included blocking capacitors between the ALC260
5340 * and the output jack. If this turns out to be the case for all such
5341 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5342 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5344 * The C20x Tablet series have a mono internal speaker which is controlled
5345 * via the chip's Mono sum widget and pin complex, so include the necessary
5346 * controls for such models. On models without a "mono speaker" the control
5347 * won't do anything.
5349 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5350 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5351 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5352 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5353 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5354 HDA_OUTPUT),
5355 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5356 HDA_INPUT),
5357 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5358 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5360 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5361 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5362 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5363 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5364 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5365 { } /* end */
5368 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5370 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5371 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5372 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5373 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5374 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5375 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5376 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5377 { } /* end */
5380 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5381 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5383 static struct snd_kcontrol_new alc260_will_mixer[] = {
5384 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5385 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5386 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5387 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5388 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5389 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5390 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5391 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5392 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5393 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5394 { } /* end */
5397 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5398 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5400 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5401 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5402 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5403 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5404 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5405 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5406 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5407 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5408 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5409 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5410 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5411 { } /* end */
5415 * initialization verbs
5417 static struct hda_verb alc260_init_verbs[] = {
5418 /* Line In pin widget for input */
5419 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5420 /* CD pin widget for input */
5421 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5422 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5423 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5424 /* Mic2 (front panel) pin widget for input and vref at 80% */
5425 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5426 /* LINE-2 is used for line-out in rear */
5427 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5428 /* select line-out */
5429 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5430 /* LINE-OUT pin */
5431 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5432 /* enable HP */
5433 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5434 /* enable Mono */
5435 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5436 /* mute capture amp left and right */
5437 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5438 /* set connection select to line in (default select for this ADC) */
5439 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5440 /* mute capture amp left and right */
5441 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5442 /* set connection select to line in (default select for this ADC) */
5443 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5444 /* set vol=0 Line-Out mixer amp left and right */
5445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5446 /* unmute pin widget amp left and right (no gain on this amp) */
5447 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5448 /* set vol=0 HP mixer amp left and right */
5449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5450 /* unmute pin widget amp left and right (no gain on this amp) */
5451 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5452 /* set vol=0 Mono mixer amp left and right */
5453 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5454 /* unmute pin widget amp left and right (no gain on this amp) */
5455 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5456 /* unmute LINE-2 out pin */
5457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5458 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5459 * Line In 2 = 0x03
5461 /* mute analog inputs */
5462 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5463 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5464 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5467 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5468 /* mute Front out path */
5469 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5470 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5471 /* mute Headphone out path */
5472 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5473 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5474 /* mute Mono out path */
5475 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5476 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5480 #if 0 /* should be identical with alc260_init_verbs? */
5481 static struct hda_verb alc260_hp_init_verbs[] = {
5482 /* Headphone and output */
5483 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5484 /* mono output */
5485 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5486 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5487 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5488 /* Mic2 (front panel) pin widget for input and vref at 80% */
5489 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5490 /* Line In pin widget for input */
5491 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5492 /* Line-2 pin widget for output */
5493 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5494 /* CD pin widget for input */
5495 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5496 /* unmute amp left and right */
5497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5498 /* set connection select to line in (default select for this ADC) */
5499 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5500 /* unmute Line-Out mixer amp left and right (volume = 0) */
5501 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5502 /* mute pin widget amp left and right (no gain on this amp) */
5503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5504 /* unmute HP mixer amp left and right (volume = 0) */
5505 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5506 /* mute pin widget amp left and right (no gain on this amp) */
5507 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5508 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5509 * Line In 2 = 0x03
5511 /* mute analog inputs */
5512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5513 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5517 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5518 /* Unmute Front out path */
5519 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5520 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5521 /* Unmute Headphone out path */
5522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5524 /* Unmute Mono out path */
5525 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5526 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5529 #endif
5531 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5532 /* Line out and output */
5533 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5534 /* mono output */
5535 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5536 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5537 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5538 /* Mic2 (front panel) pin widget for input and vref at 80% */
5539 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5540 /* Line In pin widget for input */
5541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5542 /* Headphone pin widget for output */
5543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5544 /* CD pin widget for input */
5545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5546 /* unmute amp left and right */
5547 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5548 /* set connection select to line in (default select for this ADC) */
5549 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5550 /* unmute Line-Out mixer amp left and right (volume = 0) */
5551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5552 /* mute pin widget amp left and right (no gain on this amp) */
5553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5554 /* unmute HP mixer amp left and right (volume = 0) */
5555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5556 /* mute pin widget amp left and right (no gain on this amp) */
5557 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5558 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5559 * Line In 2 = 0x03
5561 /* mute analog inputs */
5562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5563 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5564 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5567 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5568 /* Unmute Front out path */
5569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5570 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5571 /* Unmute Headphone out path */
5572 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5574 /* Unmute Mono out path */
5575 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5576 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5580 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5581 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5582 * audio = 0x16, internal speaker = 0x10.
5584 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5585 /* Disable all GPIOs */
5586 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5587 /* Internal speaker is connected to headphone pin */
5588 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5589 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5591 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5592 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5593 /* Ensure all other unused pins are disabled and muted. */
5594 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5595 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5596 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5597 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5598 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5599 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5603 /* Disable digital (SPDIF) pins */
5604 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5605 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5607 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5608 * when acting as an output.
5610 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5612 /* Start with output sum widgets muted and their output gains at min */
5613 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5616 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5618 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5619 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5620 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5621 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5623 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5624 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5625 /* Unmute Line1 pin widget output buffer since it starts as an output.
5626 * If the pin mode is changed by the user the pin mode control will
5627 * take care of enabling the pin's input/output buffers as needed.
5628 * Therefore there's no need to enable the input buffer at this
5629 * stage.
5631 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5632 /* Unmute input buffer of pin widget used for Line-in (no equiv
5633 * mixer ctrl)
5635 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5637 /* Mute capture amp left and right */
5638 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5639 /* Set ADC connection select to match default mixer setting - line
5640 * in (on mic1 pin)
5642 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5644 /* Do the same for the second ADC: mute capture input amp and
5645 * set ADC connection to line in (on mic1 pin)
5647 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5648 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5650 /* Mute all inputs to mixer widget (even unconnected ones) */
5651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5653 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5663 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5664 * similar laptops (adapted from Fujitsu init verbs).
5666 static struct hda_verb alc260_acer_init_verbs[] = {
5667 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5668 * the headphone jack. Turn this on and rely on the standard mute
5669 * methods whenever the user wants to turn these outputs off.
5671 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5672 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5673 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5674 /* Internal speaker/Headphone jack is connected to Line-out pin */
5675 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5676 /* Internal microphone/Mic jack is connected to Mic1 pin */
5677 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5678 /* Line In jack is connected to Line1 pin */
5679 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5680 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5681 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5682 /* Ensure all other unused pins are disabled and muted. */
5683 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5685 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5686 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5689 /* Disable digital (SPDIF) pins */
5690 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5691 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5693 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5694 * bus when acting as outputs.
5696 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5697 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5699 /* Start with output sum widgets muted and their output gains at min */
5700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5702 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5703 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5707 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5708 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5710 /* Unmute Line-out pin widget amp left and right
5711 * (no equiv mixer ctrl)
5713 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5714 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5715 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5716 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5717 * inputs. If the pin mode is changed by the user the pin mode control
5718 * will take care of enabling the pin's input/output buffers as needed.
5719 * Therefore there's no need to enable the input buffer at this
5720 * stage.
5722 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5725 /* Mute capture amp left and right */
5726 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5727 /* Set ADC connection select to match default mixer setting - mic
5728 * (on mic1 pin)
5730 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5732 /* Do similar with the second ADC: mute capture input amp and
5733 * set ADC connection to mic to match ALSA's default state.
5735 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5736 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5738 /* Mute all inputs to mixer widget (even unconnected ones) */
5739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5751 /* Initialisation sequence for Maxdata Favorit 100XS
5752 * (adapted from Acer init verbs).
5754 static struct hda_verb alc260_favorit100_init_verbs[] = {
5755 /* GPIO 0 enables the output jack.
5756 * Turn this on and rely on the standard mute
5757 * methods whenever the user wants to turn these outputs off.
5759 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5760 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5761 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5762 /* Line/Mic input jack is connected to Mic1 pin */
5763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5764 /* Ensure all other unused pins are disabled and muted. */
5765 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5766 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5767 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5768 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5769 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5770 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5771 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5775 /* Disable digital (SPDIF) pins */
5776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5779 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5780 * bus when acting as outputs.
5782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5783 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5785 /* Start with output sum widgets muted and their output gains at min */
5786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5796 /* Unmute Line-out pin widget amp left and right
5797 * (no equiv mixer ctrl)
5799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5800 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5801 * inputs. If the pin mode is changed by the user the pin mode control
5802 * will take care of enabling the pin's input/output buffers as needed.
5803 * Therefore there's no need to enable the input buffer at this
5804 * stage.
5806 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5808 /* Mute capture amp left and right */
5809 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5810 /* Set ADC connection select to match default mixer setting - mic
5811 * (on mic1 pin)
5813 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5815 /* Do similar with the second ADC: mute capture input amp and
5816 * set ADC connection to mic to match ALSA's default state.
5818 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5819 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5821 /* Mute all inputs to mixer widget (even unconnected ones) */
5822 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5823 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5824 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5834 static struct hda_verb alc260_will_verbs[] = {
5835 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5836 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5837 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5838 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5839 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5840 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5844 static struct hda_verb alc260_replacer_672v_verbs[] = {
5845 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5846 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5847 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5849 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5850 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5851 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5853 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5857 /* toggle speaker-output according to the hp-jack state */
5858 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5860 unsigned int present;
5862 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5863 present = snd_hda_jack_detect(codec, 0x0f);
5864 if (present) {
5865 snd_hda_codec_write_cache(codec, 0x01, 0,
5866 AC_VERB_SET_GPIO_DATA, 1);
5867 snd_hda_codec_write_cache(codec, 0x0f, 0,
5868 AC_VERB_SET_PIN_WIDGET_CONTROL,
5869 PIN_HP);
5870 } else {
5871 snd_hda_codec_write_cache(codec, 0x01, 0,
5872 AC_VERB_SET_GPIO_DATA, 0);
5873 snd_hda_codec_write_cache(codec, 0x0f, 0,
5874 AC_VERB_SET_PIN_WIDGET_CONTROL,
5875 PIN_OUT);
5879 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5880 unsigned int res)
5882 if ((res >> 26) == ALC880_HP_EVENT)
5883 alc260_replacer_672v_automute(codec);
5886 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5887 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5888 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5889 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5890 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5891 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5893 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5894 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5895 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5896 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5900 /* Test configuration for debugging, modelled after the ALC880 test
5901 * configuration.
5903 #ifdef CONFIG_SND_DEBUG
5904 static hda_nid_t alc260_test_dac_nids[1] = {
5905 0x02,
5907 static hda_nid_t alc260_test_adc_nids[2] = {
5908 0x04, 0x05,
5910 /* For testing the ALC260, each input MUX needs its own definition since
5911 * the signal assignments are different. This assumes that the first ADC
5912 * is NID 0x04.
5914 static struct hda_input_mux alc260_test_capture_sources[2] = {
5916 .num_items = 7,
5917 .items = {
5918 { "MIC1 pin", 0x0 },
5919 { "MIC2 pin", 0x1 },
5920 { "LINE1 pin", 0x2 },
5921 { "LINE2 pin", 0x3 },
5922 { "CD pin", 0x4 },
5923 { "LINE-OUT pin", 0x5 },
5924 { "HP-OUT pin", 0x6 },
5928 .num_items = 8,
5929 .items = {
5930 { "MIC1 pin", 0x0 },
5931 { "MIC2 pin", 0x1 },
5932 { "LINE1 pin", 0x2 },
5933 { "LINE2 pin", 0x3 },
5934 { "CD pin", 0x4 },
5935 { "Mixer", 0x5 },
5936 { "LINE-OUT pin", 0x6 },
5937 { "HP-OUT pin", 0x7 },
5941 static struct snd_kcontrol_new alc260_test_mixer[] = {
5942 /* Output driver widgets */
5943 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5944 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5945 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5946 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5947 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5948 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5950 /* Modes for retasking pin widgets
5951 * Note: the ALC260 doesn't seem to act on requests to enable mic
5952 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5953 * mention this restriction. At this stage it's not clear whether
5954 * this behaviour is intentional or is a hardware bug in chip
5955 * revisions available at least up until early 2006. Therefore for
5956 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5957 * choices, but if it turns out that the lack of mic bias for these
5958 * NIDs is intentional we could change their modes from
5959 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5961 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5962 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5963 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5964 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5965 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5966 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5968 /* Loopback mixer controls */
5969 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5970 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5971 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5972 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5973 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5974 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5975 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5976 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5977 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5978 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5979 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5980 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5981 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5982 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5984 /* Controls for GPIO pins, assuming they are configured as outputs */
5985 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5986 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5987 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5988 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5990 /* Switches to allow the digital IO pins to be enabled. The datasheet
5991 * is ambigious as to which NID is which; testing on laptops which
5992 * make this output available should provide clarification.
5994 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5995 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5997 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5998 * this output to turn on an external amplifier.
6000 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6001 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6003 { } /* end */
6005 static struct hda_verb alc260_test_init_verbs[] = {
6006 /* Enable all GPIOs as outputs with an initial value of 0 */
6007 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6008 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6009 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6011 /* Enable retasking pins as output, initially without power amp */
6012 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6013 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6014 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6015 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6016 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6017 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6019 /* Disable digital (SPDIF) pins initially, but users can enable
6020 * them via a mixer switch. In the case of SPDIF-out, this initverb
6021 * payload also sets the generation to 0, output to be in "consumer"
6022 * PCM format, copyright asserted, no pre-emphasis and no validity
6023 * control.
6025 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6026 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6028 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6029 * OUT1 sum bus when acting as an output.
6031 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6032 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6033 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6034 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6036 /* Start with output sum widgets muted and their output gains at min */
6037 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6041 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6043 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6044 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6045 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6047 /* Unmute retasking pin widget output buffers since the default
6048 * state appears to be output. As the pin mode is changed by the
6049 * user the pin mode control will take care of enabling the pin's
6050 * input/output buffers as needed.
6052 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6053 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6056 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6057 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6058 /* Also unmute the mono-out pin widget */
6059 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6061 /* Mute capture amp left and right */
6062 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6063 /* Set ADC connection select to match default mixer setting (mic1
6064 * pin)
6066 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6068 /* Do the same for the second ADC: mute capture input amp and
6069 * set ADC connection to mic1 pin
6071 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6072 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6074 /* Mute all inputs to mixer widget (even unconnected ones) */
6075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6076 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6086 #endif
6088 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6089 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6091 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6092 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6095 * for BIOS auto-configuration
6098 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6099 const char *pfx, int *vol_bits)
6101 hda_nid_t nid_vol;
6102 unsigned long vol_val, sw_val;
6103 int err;
6105 if (nid >= 0x0f && nid < 0x11) {
6106 nid_vol = nid - 0x7;
6107 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6108 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6109 } else if (nid == 0x11) {
6110 nid_vol = nid - 0x7;
6111 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6112 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6113 } else if (nid >= 0x12 && nid <= 0x15) {
6114 nid_vol = 0x08;
6115 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6116 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6117 } else
6118 return 0; /* N/A */
6120 if (!(*vol_bits & (1 << nid_vol))) {
6121 /* first control for the volume widget */
6122 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6123 if (err < 0)
6124 return err;
6125 *vol_bits |= (1 << nid_vol);
6127 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6128 if (err < 0)
6129 return err;
6130 return 1;
6133 /* add playback controls from the parsed DAC table */
6134 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6135 const struct auto_pin_cfg *cfg)
6137 hda_nid_t nid;
6138 int err;
6139 int vols = 0;
6141 spec->multiout.num_dacs = 1;
6142 spec->multiout.dac_nids = spec->private_dac_nids;
6143 spec->multiout.dac_nids[0] = 0x02;
6145 nid = cfg->line_out_pins[0];
6146 if (nid) {
6147 const char *pfx;
6148 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6149 pfx = "Master";
6150 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6151 pfx = "Speaker";
6152 else
6153 pfx = "Front";
6154 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6155 if (err < 0)
6156 return err;
6159 nid = cfg->speaker_pins[0];
6160 if (nid) {
6161 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6162 if (err < 0)
6163 return err;
6166 nid = cfg->hp_pins[0];
6167 if (nid) {
6168 err = alc260_add_playback_controls(spec, nid, "Headphone",
6169 &vols);
6170 if (err < 0)
6171 return err;
6173 return 0;
6176 /* create playback/capture controls for input pins */
6177 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6178 const struct auto_pin_cfg *cfg)
6180 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6183 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6184 hda_nid_t nid, int pin_type,
6185 int sel_idx)
6187 alc_set_pin_output(codec, nid, pin_type);
6188 /* need the manual connection? */
6189 if (nid >= 0x12) {
6190 int idx = nid - 0x12;
6191 snd_hda_codec_write(codec, idx + 0x0b, 0,
6192 AC_VERB_SET_CONNECT_SEL, sel_idx);
6196 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6198 struct alc_spec *spec = codec->spec;
6199 hda_nid_t nid;
6201 nid = spec->autocfg.line_out_pins[0];
6202 if (nid) {
6203 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6204 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6207 nid = spec->autocfg.speaker_pins[0];
6208 if (nid)
6209 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6211 nid = spec->autocfg.hp_pins[0];
6212 if (nid)
6213 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6216 #define ALC260_PIN_CD_NID 0x16
6217 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6219 struct alc_spec *spec = codec->spec;
6220 int i;
6222 for (i = 0; i < AUTO_PIN_LAST; i++) {
6223 hda_nid_t nid = spec->autocfg.input_pins[i];
6224 if (nid >= 0x12) {
6225 alc_set_input_pin(codec, nid, i);
6226 if (nid != ALC260_PIN_CD_NID &&
6227 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6228 snd_hda_codec_write(codec, nid, 0,
6229 AC_VERB_SET_AMP_GAIN_MUTE,
6230 AMP_OUT_MUTE);
6236 * generic initialization of ADC, input mixers and output mixers
6238 static struct hda_verb alc260_volume_init_verbs[] = {
6240 * Unmute ADC0-1 and set the default input to mic-in
6242 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6243 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6244 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6245 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6247 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6248 * mixer widget
6249 * Note: PASD motherboards uses the Line In 2 as the input for
6250 * front panel mic (mic 2)
6252 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6253 /* mute analog inputs */
6254 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6255 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6256 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6258 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6261 * Set up output mixers (0x08 - 0x0a)
6263 /* set vol=0 to output mixers */
6264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6266 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6267 /* set up input amps for analog loopback */
6268 /* Amp Indices: DAC = 0, mixer = 1 */
6269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6270 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6271 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6273 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6279 static int alc260_parse_auto_config(struct hda_codec *codec)
6281 struct alc_spec *spec = codec->spec;
6282 int err;
6283 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6285 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6286 alc260_ignore);
6287 if (err < 0)
6288 return err;
6289 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6290 if (err < 0)
6291 return err;
6292 if (!spec->kctls.list)
6293 return 0; /* can't find valid BIOS pin config */
6294 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6295 if (err < 0)
6296 return err;
6298 spec->multiout.max_channels = 2;
6300 if (spec->autocfg.dig_outs)
6301 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6302 if (spec->kctls.list)
6303 add_mixer(spec, spec->kctls.list);
6305 add_verb(spec, alc260_volume_init_verbs);
6307 spec->num_mux_defs = 1;
6308 spec->input_mux = &spec->private_imux[0];
6310 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6312 return 1;
6315 /* additional initialization for auto-configuration model */
6316 static void alc260_auto_init(struct hda_codec *codec)
6318 struct alc_spec *spec = codec->spec;
6319 alc260_auto_init_multi_out(codec);
6320 alc260_auto_init_analog_input(codec);
6321 if (spec->unsol_event)
6322 alc_inithook(codec);
6325 #ifdef CONFIG_SND_HDA_POWER_SAVE
6326 static struct hda_amp_list alc260_loopbacks[] = {
6327 { 0x07, HDA_INPUT, 0 },
6328 { 0x07, HDA_INPUT, 1 },
6329 { 0x07, HDA_INPUT, 2 },
6330 { 0x07, HDA_INPUT, 3 },
6331 { 0x07, HDA_INPUT, 4 },
6332 { } /* end */
6334 #endif
6337 * ALC260 configurations
6339 static const char *alc260_models[ALC260_MODEL_LAST] = {
6340 [ALC260_BASIC] = "basic",
6341 [ALC260_HP] = "hp",
6342 [ALC260_HP_3013] = "hp-3013",
6343 [ALC260_HP_DC7600] = "hp-dc7600",
6344 [ALC260_FUJITSU_S702X] = "fujitsu",
6345 [ALC260_ACER] = "acer",
6346 [ALC260_WILL] = "will",
6347 [ALC260_REPLACER_672V] = "replacer",
6348 [ALC260_FAVORIT100] = "favorit100",
6349 #ifdef CONFIG_SND_DEBUG
6350 [ALC260_TEST] = "test",
6351 #endif
6352 [ALC260_AUTO] = "auto",
6355 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6356 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6357 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6358 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6359 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6360 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6361 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6362 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6363 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6364 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6365 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6366 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6367 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6368 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6369 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6370 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6371 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6372 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6373 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6374 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6375 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6379 static struct alc_config_preset alc260_presets[] = {
6380 [ALC260_BASIC] = {
6381 .mixers = { alc260_base_output_mixer,
6382 alc260_input_mixer },
6383 .init_verbs = { alc260_init_verbs },
6384 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6385 .dac_nids = alc260_dac_nids,
6386 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6387 .adc_nids = alc260_dual_adc_nids,
6388 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6389 .channel_mode = alc260_modes,
6390 .input_mux = &alc260_capture_source,
6392 [ALC260_HP] = {
6393 .mixers = { alc260_hp_output_mixer,
6394 alc260_input_mixer },
6395 .init_verbs = { alc260_init_verbs,
6396 alc260_hp_unsol_verbs },
6397 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6398 .dac_nids = alc260_dac_nids,
6399 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6400 .adc_nids = alc260_adc_nids_alt,
6401 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6402 .channel_mode = alc260_modes,
6403 .input_mux = &alc260_capture_source,
6404 .unsol_event = alc260_hp_unsol_event,
6405 .init_hook = alc260_hp_automute,
6407 [ALC260_HP_DC7600] = {
6408 .mixers = { alc260_hp_dc7600_mixer,
6409 alc260_input_mixer },
6410 .init_verbs = { alc260_init_verbs,
6411 alc260_hp_dc7600_verbs },
6412 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6413 .dac_nids = alc260_dac_nids,
6414 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6415 .adc_nids = alc260_adc_nids_alt,
6416 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6417 .channel_mode = alc260_modes,
6418 .input_mux = &alc260_capture_source,
6419 .unsol_event = alc260_hp_3012_unsol_event,
6420 .init_hook = alc260_hp_3012_automute,
6422 [ALC260_HP_3013] = {
6423 .mixers = { alc260_hp_3013_mixer,
6424 alc260_input_mixer },
6425 .init_verbs = { alc260_hp_3013_init_verbs,
6426 alc260_hp_3013_unsol_verbs },
6427 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6428 .dac_nids = alc260_dac_nids,
6429 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6430 .adc_nids = alc260_adc_nids_alt,
6431 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6432 .channel_mode = alc260_modes,
6433 .input_mux = &alc260_capture_source,
6434 .unsol_event = alc260_hp_3013_unsol_event,
6435 .init_hook = alc260_hp_3013_automute,
6437 [ALC260_FUJITSU_S702X] = {
6438 .mixers = { alc260_fujitsu_mixer },
6439 .init_verbs = { alc260_fujitsu_init_verbs },
6440 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6441 .dac_nids = alc260_dac_nids,
6442 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6443 .adc_nids = alc260_dual_adc_nids,
6444 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6445 .channel_mode = alc260_modes,
6446 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6447 .input_mux = alc260_fujitsu_capture_sources,
6449 [ALC260_ACER] = {
6450 .mixers = { alc260_acer_mixer },
6451 .init_verbs = { alc260_acer_init_verbs },
6452 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6453 .dac_nids = alc260_dac_nids,
6454 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6455 .adc_nids = alc260_dual_adc_nids,
6456 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6457 .channel_mode = alc260_modes,
6458 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6459 .input_mux = alc260_acer_capture_sources,
6461 [ALC260_FAVORIT100] = {
6462 .mixers = { alc260_favorit100_mixer },
6463 .init_verbs = { alc260_favorit100_init_verbs },
6464 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6465 .dac_nids = alc260_dac_nids,
6466 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6467 .adc_nids = alc260_dual_adc_nids,
6468 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6469 .channel_mode = alc260_modes,
6470 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6471 .input_mux = alc260_favorit100_capture_sources,
6473 [ALC260_WILL] = {
6474 .mixers = { alc260_will_mixer },
6475 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6476 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6477 .dac_nids = alc260_dac_nids,
6478 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6479 .adc_nids = alc260_adc_nids,
6480 .dig_out_nid = ALC260_DIGOUT_NID,
6481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6482 .channel_mode = alc260_modes,
6483 .input_mux = &alc260_capture_source,
6485 [ALC260_REPLACER_672V] = {
6486 .mixers = { alc260_replacer_672v_mixer },
6487 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6488 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6489 .dac_nids = alc260_dac_nids,
6490 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6491 .adc_nids = alc260_adc_nids,
6492 .dig_out_nid = ALC260_DIGOUT_NID,
6493 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6494 .channel_mode = alc260_modes,
6495 .input_mux = &alc260_capture_source,
6496 .unsol_event = alc260_replacer_672v_unsol_event,
6497 .init_hook = alc260_replacer_672v_automute,
6499 #ifdef CONFIG_SND_DEBUG
6500 [ALC260_TEST] = {
6501 .mixers = { alc260_test_mixer },
6502 .init_verbs = { alc260_test_init_verbs },
6503 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6504 .dac_nids = alc260_test_dac_nids,
6505 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6506 .adc_nids = alc260_test_adc_nids,
6507 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6508 .channel_mode = alc260_modes,
6509 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6510 .input_mux = alc260_test_capture_sources,
6512 #endif
6515 static int patch_alc260(struct hda_codec *codec)
6517 struct alc_spec *spec;
6518 int err, board_config;
6520 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6521 if (spec == NULL)
6522 return -ENOMEM;
6524 codec->spec = spec;
6526 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6527 alc260_models,
6528 alc260_cfg_tbl);
6529 if (board_config < 0) {
6530 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6531 codec->chip_name);
6532 board_config = ALC260_AUTO;
6535 if (board_config == ALC260_AUTO) {
6536 /* automatic parse from the BIOS config */
6537 err = alc260_parse_auto_config(codec);
6538 if (err < 0) {
6539 alc_free(codec);
6540 return err;
6541 } else if (!err) {
6542 printk(KERN_INFO
6543 "hda_codec: Cannot set up configuration "
6544 "from BIOS. Using base mode...\n");
6545 board_config = ALC260_BASIC;
6549 err = snd_hda_attach_beep_device(codec, 0x1);
6550 if (err < 0) {
6551 alc_free(codec);
6552 return err;
6555 if (board_config != ALC260_AUTO)
6556 setup_preset(codec, &alc260_presets[board_config]);
6558 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6559 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6561 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6562 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6564 if (!spec->adc_nids && spec->input_mux) {
6565 /* check whether NID 0x04 is valid */
6566 unsigned int wcap = get_wcaps(codec, 0x04);
6567 wcap = get_wcaps_type(wcap);
6568 /* get type */
6569 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6570 spec->adc_nids = alc260_adc_nids_alt;
6571 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6572 } else {
6573 spec->adc_nids = alc260_adc_nids;
6574 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6577 set_capture_mixer(codec);
6578 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6580 spec->vmaster_nid = 0x08;
6582 codec->patch_ops = alc_patch_ops;
6583 if (board_config == ALC260_AUTO)
6584 spec->init_hook = alc260_auto_init;
6585 #ifdef CONFIG_SND_HDA_POWER_SAVE
6586 if (!spec->loopback.amplist)
6587 spec->loopback.amplist = alc260_loopbacks;
6588 #endif
6589 codec->proc_widget_hook = print_realtek_coef;
6591 return 0;
6596 * ALC882/883/885/888/889 support
6598 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6599 * configuration. Each pin widget can choose any input DACs and a mixer.
6600 * Each ADC is connected from a mixer of all inputs. This makes possible
6601 * 6-channel independent captures.
6603 * In addition, an independent DAC for the multi-playback (not used in this
6604 * driver yet).
6606 #define ALC882_DIGOUT_NID 0x06
6607 #define ALC882_DIGIN_NID 0x0a
6608 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6609 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6610 #define ALC1200_DIGOUT_NID 0x10
6613 static struct hda_channel_mode alc882_ch_modes[1] = {
6614 { 8, NULL }
6617 /* DACs */
6618 static hda_nid_t alc882_dac_nids[4] = {
6619 /* front, rear, clfe, rear_surr */
6620 0x02, 0x03, 0x04, 0x05
6622 #define alc883_dac_nids alc882_dac_nids
6624 /* ADCs */
6625 #define alc882_adc_nids alc880_adc_nids
6626 #define alc882_adc_nids_alt alc880_adc_nids_alt
6627 #define alc883_adc_nids alc882_adc_nids_alt
6628 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6629 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6630 #define alc889_adc_nids alc880_adc_nids
6632 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6633 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6634 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6635 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6636 #define alc889_capsrc_nids alc882_capsrc_nids
6638 /* input MUX */
6639 /* FIXME: should be a matrix-type input source selection */
6641 static struct hda_input_mux alc882_capture_source = {
6642 .num_items = 4,
6643 .items = {
6644 { "Mic", 0x0 },
6645 { "Front Mic", 0x1 },
6646 { "Line", 0x2 },
6647 { "CD", 0x4 },
6651 #define alc883_capture_source alc882_capture_source
6653 static struct hda_input_mux alc889_capture_source = {
6654 .num_items = 3,
6655 .items = {
6656 { "Front Mic", 0x0 },
6657 { "Mic", 0x3 },
6658 { "Line", 0x2 },
6662 static struct hda_input_mux mb5_capture_source = {
6663 .num_items = 3,
6664 .items = {
6665 { "Mic", 0x1 },
6666 { "Line", 0x2 },
6667 { "CD", 0x4 },
6671 static struct hda_input_mux alc883_3stack_6ch_intel = {
6672 .num_items = 4,
6673 .items = {
6674 { "Mic", 0x1 },
6675 { "Front Mic", 0x0 },
6676 { "Line", 0x2 },
6677 { "CD", 0x4 },
6681 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6682 .num_items = 2,
6683 .items = {
6684 { "Mic", 0x1 },
6685 { "Line", 0x2 },
6689 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6690 .num_items = 4,
6691 .items = {
6692 { "Mic", 0x0 },
6693 { "iMic", 0x1 },
6694 { "Line", 0x2 },
6695 { "CD", 0x4 },
6699 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6700 .num_items = 2,
6701 .items = {
6702 { "Mic", 0x0 },
6703 { "Int Mic", 0x1 },
6707 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6708 .num_items = 3,
6709 .items = {
6710 { "Mic", 0x0 },
6711 { "Front Mic", 0x1 },
6712 { "Line", 0x4 },
6716 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6717 .num_items = 2,
6718 .items = {
6719 { "Mic", 0x0 },
6720 { "Line", 0x2 },
6724 static struct hda_input_mux alc889A_mb31_capture_source = {
6725 .num_items = 2,
6726 .items = {
6727 { "Mic", 0x0 },
6728 /* Front Mic (0x01) unused */
6729 { "Line", 0x2 },
6730 /* Line 2 (0x03) unused */
6731 /* CD (0x04) unused? */
6736 * 2ch mode
6738 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6739 { 2, NULL }
6743 * 2ch mode
6745 static struct hda_verb alc882_3ST_ch2_init[] = {
6746 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6747 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6748 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6749 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6750 { } /* end */
6754 * 4ch mode
6756 static struct hda_verb alc882_3ST_ch4_init[] = {
6757 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6758 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6759 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6760 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6761 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6762 { } /* end */
6766 * 6ch mode
6768 static struct hda_verb alc882_3ST_ch6_init[] = {
6769 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6770 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6771 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6772 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6773 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6774 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6775 { } /* end */
6778 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6779 { 2, alc882_3ST_ch2_init },
6780 { 4, alc882_3ST_ch4_init },
6781 { 6, alc882_3ST_ch6_init },
6784 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6787 * 2ch mode
6789 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6790 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6791 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6792 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6795 { } /* end */
6799 * 4ch mode
6801 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6802 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6805 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6806 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6807 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6808 { } /* end */
6812 * 6ch mode
6814 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6815 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6816 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6817 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6818 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6819 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6820 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6821 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6822 { } /* end */
6825 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6826 { 2, alc883_3ST_ch2_clevo_init },
6827 { 4, alc883_3ST_ch4_clevo_init },
6828 { 6, alc883_3ST_ch6_clevo_init },
6833 * 6ch mode
6835 static struct hda_verb alc882_sixstack_ch6_init[] = {
6836 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6837 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6838 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6839 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6840 { } /* end */
6844 * 8ch mode
6846 static struct hda_verb alc882_sixstack_ch8_init[] = {
6847 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6848 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6849 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6850 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6851 { } /* end */
6854 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6855 { 6, alc882_sixstack_ch6_init },
6856 { 8, alc882_sixstack_ch8_init },
6860 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6864 * 2ch mode
6866 static struct hda_verb alc885_mbp_ch2_init[] = {
6867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6868 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6869 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6870 { } /* end */
6874 * 4ch mode
6876 static struct hda_verb alc885_mbp_ch4_init[] = {
6877 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6878 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6879 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6880 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6881 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6882 { } /* end */
6885 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6886 { 2, alc885_mbp_ch2_init },
6887 { 4, alc885_mbp_ch4_init },
6891 * 2ch
6892 * Speakers/Woofer/HP = Front
6893 * LineIn = Input
6895 static struct hda_verb alc885_mb5_ch2_init[] = {
6896 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6898 { } /* end */
6902 * 6ch mode
6903 * Speakers/HP = Front
6904 * Woofer = LFE
6905 * LineIn = Surround
6907 static struct hda_verb alc885_mb5_ch6_init[] = {
6908 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6909 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6910 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6911 { } /* end */
6914 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6915 { 2, alc885_mb5_ch2_init },
6916 { 6, alc885_mb5_ch6_init },
6921 * 2ch mode
6923 static struct hda_verb alc883_4ST_ch2_init[] = {
6924 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6925 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6926 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6927 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6930 { } /* end */
6934 * 4ch mode
6936 static struct hda_verb alc883_4ST_ch4_init[] = {
6937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6938 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6939 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6940 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6941 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6942 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6943 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6944 { } /* end */
6948 * 6ch mode
6950 static struct hda_verb alc883_4ST_ch6_init[] = {
6951 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6952 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6953 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6954 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6955 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6956 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6957 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6958 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6959 { } /* end */
6963 * 8ch mode
6965 static struct hda_verb alc883_4ST_ch8_init[] = {
6966 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6967 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6968 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6969 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6970 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6971 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6972 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6973 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6974 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6975 { } /* end */
6978 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6979 { 2, alc883_4ST_ch2_init },
6980 { 4, alc883_4ST_ch4_init },
6981 { 6, alc883_4ST_ch6_init },
6982 { 8, alc883_4ST_ch8_init },
6987 * 2ch mode
6989 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6990 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6991 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6992 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6993 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6994 { } /* end */
6998 * 4ch mode
7000 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7001 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7002 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7003 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7004 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7005 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7006 { } /* end */
7010 * 6ch mode
7012 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7013 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7014 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7015 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7016 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7017 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7018 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7019 { } /* end */
7022 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7023 { 2, alc883_3ST_ch2_intel_init },
7024 { 4, alc883_3ST_ch4_intel_init },
7025 { 6, alc883_3ST_ch6_intel_init },
7029 * 2ch mode
7031 static struct hda_verb alc889_ch2_intel_init[] = {
7032 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7033 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7034 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7035 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7036 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7037 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7038 { } /* end */
7042 * 6ch mode
7044 static struct hda_verb alc889_ch6_intel_init[] = {
7045 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7046 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7047 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7048 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7049 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7050 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7051 { } /* end */
7055 * 8ch mode
7057 static struct hda_verb alc889_ch8_intel_init[] = {
7058 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7059 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7060 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7061 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7062 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7063 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7064 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7065 { } /* end */
7068 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7069 { 2, alc889_ch2_intel_init },
7070 { 6, alc889_ch6_intel_init },
7071 { 8, alc889_ch8_intel_init },
7075 * 6ch mode
7077 static struct hda_verb alc883_sixstack_ch6_init[] = {
7078 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7079 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7080 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7081 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7082 { } /* end */
7086 * 8ch mode
7088 static struct hda_verb alc883_sixstack_ch8_init[] = {
7089 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7090 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7091 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7092 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7093 { } /* end */
7096 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7097 { 6, alc883_sixstack_ch6_init },
7098 { 8, alc883_sixstack_ch8_init },
7102 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7103 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7105 static struct snd_kcontrol_new alc882_base_mixer[] = {
7106 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7107 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7108 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7109 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7110 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7111 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7112 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7113 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7115 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7116 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7117 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7118 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7121 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7122 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7124 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7125 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7126 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7127 { } /* end */
7130 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7132 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7133 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7134 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7135 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7137 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7139 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7140 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7141 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7142 { } /* end */
7145 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7146 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7147 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7148 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7149 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7150 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7151 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7153 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7154 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7155 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7157 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7158 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7159 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7160 { } /* end */
7163 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7164 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7165 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7166 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7168 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7169 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7171 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7172 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7173 { } /* end */
7177 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7178 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7179 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7180 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7181 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7185 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7187 { } /* end */
7190 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7191 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7192 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7194 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7195 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7202 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7203 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7204 { } /* end */
7207 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7208 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7210 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7211 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7212 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7214 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7215 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7216 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7219 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7220 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7223 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7224 { } /* end */
7227 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7228 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7229 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7230 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7236 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7238 { } /* end */
7241 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7244 .name = "Channel Mode",
7245 .info = alc_ch_mode_info,
7246 .get = alc_ch_mode_get,
7247 .put = alc_ch_mode_put,
7249 { } /* end */
7252 static struct hda_verb alc882_base_init_verbs[] = {
7253 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7254 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7255 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7256 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7257 /* Rear mixer */
7258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7259 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7260 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7261 /* CLFE mixer */
7262 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7265 /* Side mixer */
7266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7268 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7270 /* mute analog input loopbacks */
7271 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7272 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7273 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7274 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7275 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7277 /* Front Pin: output 0 (0x0c) */
7278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7281 /* Rear Pin: output 1 (0x0d) */
7282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7285 /* CLFE Pin: output 2 (0x0e) */
7286 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7287 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7288 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7289 /* Side Pin: output 3 (0x0f) */
7290 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7291 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7292 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7293 /* Mic (rear) pin: input vref at 80% */
7294 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7295 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7296 /* Front Mic pin: input vref at 80% */
7297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7299 /* Line In pin: input */
7300 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7301 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7302 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7303 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7304 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7305 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7306 /* CD pin widget for input */
7307 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7309 /* FIXME: use matrix-type input source selection */
7310 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7311 /* Input mixer2 */
7312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7316 /* Input mixer3 */
7317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7321 /* ADC2: mute amp left and right */
7322 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7323 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7324 /* ADC3: mute amp left and right */
7325 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7331 static struct hda_verb alc882_adc1_init_verbs[] = {
7332 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7333 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7334 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7335 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7336 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7337 /* ADC1: mute amp left and right */
7338 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7339 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7343 static struct hda_verb alc882_eapd_verbs[] = {
7344 /* change to EAPD mode */
7345 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7346 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7350 static struct hda_verb alc889_eapd_verbs[] = {
7351 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7352 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7356 static struct hda_verb alc_hp15_unsol_verbs[] = {
7357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7362 static struct hda_verb alc885_init_verbs[] = {
7363 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7364 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7367 /* Rear mixer */
7368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7371 /* CLFE mixer */
7372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7375 /* Side mixer */
7376 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7380 /* mute analog input loopbacks */
7381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7385 /* Front HP Pin: output 0 (0x0c) */
7386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7389 /* Front Pin: output 0 (0x0c) */
7390 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7391 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7392 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7393 /* Rear Pin: output 1 (0x0d) */
7394 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7395 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7396 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7397 /* CLFE Pin: output 2 (0x0e) */
7398 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7399 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7400 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7401 /* Side Pin: output 3 (0x0f) */
7402 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7403 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7404 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7405 /* Mic (rear) pin: input vref at 80% */
7406 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7407 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7408 /* Front Mic pin: input vref at 80% */
7409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7410 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7411 /* Line In pin: input */
7412 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7413 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7415 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7416 /* Input mixer1 */
7417 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7418 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7419 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7420 /* Input mixer2 */
7421 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7422 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7423 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7424 /* Input mixer3 */
7425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7427 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7428 /* ADC2: mute amp left and right */
7429 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7430 /* ADC3: mute amp left and right */
7431 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7436 static struct hda_verb alc885_init_input_verbs[] = {
7437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7438 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7439 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7444 /* Unmute Selector 24h and set the default input to front mic */
7445 static struct hda_verb alc889_init_input_verbs[] = {
7446 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7452 #define alc883_init_verbs alc882_base_init_verbs
7454 /* Mac Pro test */
7455 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7457 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7461 /* FIXME: this looks suspicious...
7462 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7463 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7465 { } /* end */
7468 static struct hda_verb alc882_macpro_init_verbs[] = {
7469 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7473 /* Front Pin: output 0 (0x0c) */
7474 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7475 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7476 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7477 /* Front Mic pin: input vref at 80% */
7478 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7479 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7480 /* Speaker: output */
7481 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7482 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7483 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7484 /* Headphone output (output 0 - 0x0c) */
7485 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7486 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7487 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7489 /* FIXME: use matrix-type input source selection */
7490 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7491 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7493 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7496 /* Input mixer2 */
7497 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7498 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7499 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7500 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7501 /* Input mixer3 */
7502 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7503 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7504 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7505 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7506 /* ADC1: mute amp left and right */
7507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7508 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7509 /* ADC2: mute amp left and right */
7510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7511 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7512 /* ADC3: mute amp left and right */
7513 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7514 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7519 /* Macbook 5,1 */
7520 static struct hda_verb alc885_mb5_init_verbs[] = {
7521 /* DACs */
7522 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7523 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7524 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7525 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7526 /* Front mixer */
7527 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7528 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7529 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7530 /* Surround mixer */
7531 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7534 /* LFE mixer */
7535 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7538 /* HP mixer */
7539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7540 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7541 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7542 /* Front Pin (0x0c) */
7543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7546 /* LFE Pin (0x0e) */
7547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7549 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7550 /* HP Pin (0x0f) */
7551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7552 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7554 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7555 /* Front Mic pin: input vref at 80% */
7556 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7557 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7558 /* Line In pin */
7559 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7560 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7562 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7563 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7564 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7569 /* Macbook Pro rev3 */
7570 static struct hda_verb alc885_mbp3_init_verbs[] = {
7571 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7575 /* Rear mixer */
7576 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7579 /* HP mixer */
7580 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7583 /* Front Pin: output 0 (0x0c) */
7584 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7585 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7586 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7587 /* HP Pin: output 0 (0x0e) */
7588 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7590 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7591 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7592 /* Mic (rear) pin: input vref at 80% */
7593 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7594 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7595 /* Front Mic pin: input vref at 80% */
7596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7598 /* Line In pin: use output 1 when in LineOut mode */
7599 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7601 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7603 /* FIXME: use matrix-type input source selection */
7604 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7610 /* Input mixer2 */
7611 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7615 /* Input mixer3 */
7616 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7620 /* ADC1: mute amp left and right */
7621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7622 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7623 /* ADC2: mute amp left and right */
7624 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7625 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7626 /* ADC3: mute amp left and right */
7627 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7628 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7633 /* iMac 9,1 */
7634 static struct hda_verb alc885_imac91_init_verbs[] = {
7635 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7636 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7637 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7639 /* Rear mixer */
7640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7641 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7643 /* HP Pin: output 0 (0x0c) */
7644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7646 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7647 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7648 /* Internal Speakers: output 0 (0x0d) */
7649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7651 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7652 /* Mic (rear) pin: input vref at 80% */
7653 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7655 /* Front Mic pin: input vref at 80% */
7656 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7658 /* Line In pin: use output 1 when in LineOut mode */
7659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7661 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7663 /* FIXME: use matrix-type input source selection */
7664 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7665 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7667 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7668 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7669 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7670 /* Input mixer2 */
7671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7672 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7673 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7674 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7675 /* Input mixer3 */
7676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7680 /* ADC1: mute amp left and right */
7681 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7682 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7683 /* ADC2: mute amp left and right */
7684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7685 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7686 /* ADC3: mute amp left and right */
7687 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7688 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7693 /* iMac 24 mixer. */
7694 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7695 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7696 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7697 { } /* end */
7700 /* iMac 24 init verbs. */
7701 static struct hda_verb alc885_imac24_init_verbs[] = {
7702 /* Internal speakers: output 0 (0x0c) */
7703 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7704 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7705 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7706 /* Internal speakers: output 0 (0x0c) */
7707 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7709 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7710 /* Headphone: output 0 (0x0c) */
7711 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7712 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7713 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7714 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7715 /* Front Mic: input vref at 80% */
7716 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7717 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7721 /* Toggle speaker-output according to the hp-jack state */
7722 static void alc885_imac24_setup(struct hda_codec *codec)
7724 struct alc_spec *spec = codec->spec;
7726 spec->autocfg.hp_pins[0] = 0x14;
7727 spec->autocfg.speaker_pins[0] = 0x18;
7728 spec->autocfg.speaker_pins[1] = 0x1a;
7731 static void alc885_mbp3_setup(struct hda_codec *codec)
7733 struct alc_spec *spec = codec->spec;
7735 spec->autocfg.hp_pins[0] = 0x15;
7736 spec->autocfg.speaker_pins[0] = 0x14;
7739 static void alc885_mb5_automute(struct hda_codec *codec)
7741 unsigned int present;
7743 present = snd_hda_codec_read(codec, 0x14, 0,
7744 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7745 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7746 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7747 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7748 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7752 static void alc885_mb5_unsol_event(struct hda_codec *codec,
7753 unsigned int res)
7755 /* Headphone insertion or removal. */
7756 if ((res >> 26) == ALC880_HP_EVENT)
7757 alc885_mb5_automute(codec);
7760 static void alc885_imac91_automute(struct hda_codec *codec)
7762 unsigned int present;
7764 present = snd_hda_codec_read(codec, 0x14, 0,
7765 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7766 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7767 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7768 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7769 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7773 static void alc885_imac91_unsol_event(struct hda_codec *codec,
7774 unsigned int res)
7776 /* Headphone insertion or removal. */
7777 if ((res >> 26) == ALC880_HP_EVENT)
7778 alc885_imac91_automute(codec);
7781 static struct hda_verb alc882_targa_verbs[] = {
7782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7783 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7788 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7789 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7790 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7792 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7793 { } /* end */
7796 /* toggle speaker-output according to the hp-jack state */
7797 static void alc882_targa_automute(struct hda_codec *codec)
7799 struct alc_spec *spec = codec->spec;
7800 alc_automute_amp(codec);
7801 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7802 spec->jack_present ? 1 : 3);
7805 static void alc882_targa_setup(struct hda_codec *codec)
7807 struct alc_spec *spec = codec->spec;
7809 spec->autocfg.hp_pins[0] = 0x14;
7810 spec->autocfg.speaker_pins[0] = 0x1b;
7813 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7815 if ((res >> 26) == ALC880_HP_EVENT)
7816 alc882_targa_automute(codec);
7819 static struct hda_verb alc882_asus_a7j_verbs[] = {
7820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7821 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7823 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7825 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7827 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7828 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7829 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7831 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7832 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7834 { } /* end */
7837 static struct hda_verb alc882_asus_a7m_verbs[] = {
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7841 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7843 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7845 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7847 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7849 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7850 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7851 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7852 { } /* end */
7855 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7857 unsigned int gpiostate, gpiomask, gpiodir;
7859 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7860 AC_VERB_GET_GPIO_DATA, 0);
7862 if (!muted)
7863 gpiostate |= (1 << pin);
7864 else
7865 gpiostate &= ~(1 << pin);
7867 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7868 AC_VERB_GET_GPIO_MASK, 0);
7869 gpiomask |= (1 << pin);
7871 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7872 AC_VERB_GET_GPIO_DIRECTION, 0);
7873 gpiodir |= (1 << pin);
7876 snd_hda_codec_write(codec, codec->afg, 0,
7877 AC_VERB_SET_GPIO_MASK, gpiomask);
7878 snd_hda_codec_write(codec, codec->afg, 0,
7879 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7881 msleep(1);
7883 snd_hda_codec_write(codec, codec->afg, 0,
7884 AC_VERB_SET_GPIO_DATA, gpiostate);
7887 /* set up GPIO at initialization */
7888 static void alc885_macpro_init_hook(struct hda_codec *codec)
7890 alc882_gpio_mute(codec, 0, 0);
7891 alc882_gpio_mute(codec, 1, 0);
7894 /* set up GPIO and update auto-muting at initialization */
7895 static void alc885_imac24_init_hook(struct hda_codec *codec)
7897 alc885_macpro_init_hook(codec);
7898 alc_automute_amp(codec);
7902 * generic initialization of ADC, input mixers and output mixers
7904 static struct hda_verb alc883_auto_init_verbs[] = {
7906 * Unmute ADC0-2 and set the default input to mic-in
7908 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7909 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7910 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7911 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7913 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7914 * mixer widget
7915 * Note: PASD motherboards uses the Line In 2 as the input for
7916 * front panel mic (mic 2)
7918 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7926 * Set up output mixers (0x0c - 0x0f)
7928 /* set vol=0 to output mixers */
7929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7930 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7933 /* set up input amps for analog loopback */
7934 /* Amp Indices: DAC = 0, mixer = 1 */
7935 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7936 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7937 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7938 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7939 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7940 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7941 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7942 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7943 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7944 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7946 /* FIXME: use matrix-type input source selection */
7947 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7948 /* Input mixer2 */
7949 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7950 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7951 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7952 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7953 /* Input mixer3 */
7954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7957 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7962 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7963 static struct hda_verb alc889A_mb31_ch2_init[] = {
7964 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7965 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7966 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7967 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7968 { } /* end */
7971 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7972 static struct hda_verb alc889A_mb31_ch4_init[] = {
7973 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7974 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7976 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7977 { } /* end */
7980 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7981 static struct hda_verb alc889A_mb31_ch5_init[] = {
7982 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7983 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7984 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7985 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7986 { } /* end */
7989 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7990 static struct hda_verb alc889A_mb31_ch6_init[] = {
7991 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7992 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7993 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7994 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7995 { } /* end */
7998 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7999 { 2, alc889A_mb31_ch2_init },
8000 { 4, alc889A_mb31_ch4_init },
8001 { 5, alc889A_mb31_ch5_init },
8002 { 6, alc889A_mb31_ch6_init },
8005 static struct hda_verb alc883_medion_eapd_verbs[] = {
8006 /* eanable EAPD on medion laptop */
8007 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8008 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8012 #define alc883_base_mixer alc882_base_mixer
8014 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8015 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8016 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8017 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8018 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8019 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8020 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8021 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8025 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8027 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8028 { } /* end */
8031 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8032 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8033 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8034 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8035 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8039 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8040 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8041 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8042 { } /* end */
8045 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8046 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8047 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8048 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8049 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8051 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8053 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8055 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8056 { } /* end */
8059 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8060 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8061 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8062 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8063 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8064 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8070 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8072 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8073 { } /* end */
8076 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8078 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8079 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8080 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8081 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8082 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8083 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8084 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8086 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8087 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8088 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8089 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8090 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8093 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8094 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8096 { } /* end */
8099 static struct snd_kcontrol_new alc883_3ST_6ch_intel_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_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8103 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8104 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8105 HDA_OUTPUT),
8106 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8107 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8108 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8110 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8111 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8112 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8113 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8117 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8118 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8119 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8120 { } /* end */
8123 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8124 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8127 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8128 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8129 HDA_OUTPUT),
8130 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8131 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8132 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8133 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8134 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8136 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8137 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8138 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8139 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8141 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8142 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8144 { } /* end */
8147 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8149 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8150 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8151 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8152 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8153 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8154 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8155 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8156 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8157 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8158 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8159 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8161 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8165 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8167 { } /* end */
8170 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8172 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8175 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8176 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8177 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8178 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8179 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8180 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8181 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8182 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8183 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8184 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8186 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8187 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8188 { } /* end */
8191 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8196 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8197 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8199 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8200 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8201 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8202 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8203 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8204 { } /* end */
8207 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8208 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8209 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8210 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8211 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8212 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8213 { } /* end */
8216 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8217 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8220 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8221 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8222 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8224 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8225 { } /* end */
8228 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8230 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8231 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8232 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8233 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8236 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8237 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8238 { } /* end */
8241 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8242 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8243 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8244 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8250 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8251 { } /* end */
8254 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8255 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8256 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8257 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8258 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8259 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8260 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8261 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8263 { } /* end */
8266 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8269 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8270 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8271 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8272 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8273 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8274 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8276 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8277 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8278 { } /* end */
8281 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8284 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8285 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8286 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8287 0x0d, 1, 0x0, HDA_OUTPUT),
8288 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8289 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8290 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8291 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8292 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8293 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8294 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8295 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8296 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8302 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8303 { } /* end */
8306 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8307 /* Output mixers */
8308 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8309 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8310 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8311 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8312 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8313 HDA_OUTPUT),
8314 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8315 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8316 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8317 /* Output switches */
8318 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8319 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8320 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8321 /* Boost mixers */
8322 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8323 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8324 /* Input mixers */
8325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8327 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8328 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8329 { } /* end */
8332 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8333 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8334 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8339 { } /* end */
8342 static struct hda_bind_ctls alc883_bind_cap_vol = {
8343 .ops = &snd_hda_bind_vol,
8344 .values = {
8345 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8346 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8351 static struct hda_bind_ctls alc883_bind_cap_switch = {
8352 .ops = &snd_hda_bind_sw,
8353 .values = {
8354 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8355 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8360 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8361 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8362 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8363 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8364 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8365 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8367 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8369 { } /* end */
8372 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8373 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8374 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8376 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8377 /* .name = "Capture Source", */
8378 .name = "Input Source",
8379 .count = 1,
8380 .info = alc_mux_enum_info,
8381 .get = alc_mux_enum_get,
8382 .put = alc_mux_enum_put,
8384 { } /* end */
8387 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8390 .name = "Channel Mode",
8391 .info = alc_ch_mode_info,
8392 .get = alc_ch_mode_get,
8393 .put = alc_ch_mode_put,
8395 { } /* end */
8398 /* toggle speaker-output according to the hp-jack state */
8399 static void alc883_mitac_setup(struct hda_codec *codec)
8401 struct alc_spec *spec = codec->spec;
8403 spec->autocfg.hp_pins[0] = 0x15;
8404 spec->autocfg.speaker_pins[0] = 0x14;
8405 spec->autocfg.speaker_pins[1] = 0x17;
8408 /* auto-toggle front mic */
8410 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8412 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8414 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8418 static struct hda_verb alc883_mitac_verbs[] = {
8419 /* HP */
8420 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8421 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8422 /* Subwoofer */
8423 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8426 /* enable unsolicited event */
8427 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8428 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8430 { } /* end */
8433 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8434 /* HP */
8435 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8437 /* Int speaker */
8438 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8440 /* enable unsolicited event */
8442 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8443 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8446 { } /* end */
8449 static struct hda_verb alc883_clevo_m720_verbs[] = {
8450 /* HP */
8451 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8452 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8453 /* Int speaker */
8454 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8457 /* enable unsolicited event */
8458 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8459 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8461 { } /* end */
8464 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8465 /* HP */
8466 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8468 /* Subwoofer */
8469 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8472 /* enable unsolicited event */
8473 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8475 { } /* end */
8478 static struct hda_verb alc883_targa_verbs[] = {
8479 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8483 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 /* Connect Line-Out side jack (SPDIF) to Side */
8486 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8487 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8488 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8489 /* Connect Mic jack to CLFE */
8490 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8491 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8492 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8493 /* Connect Line-in jack to Surround */
8494 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8495 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8496 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8497 /* Connect HP out jack to Front */
8498 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8499 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8500 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8504 { } /* end */
8507 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8508 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8509 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8510 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8511 { } /* end */
8514 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8515 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8517 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8519 { } /* end */
8522 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8523 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8524 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8525 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8526 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8527 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8528 { } /* end */
8531 static struct hda_verb alc883_haier_w66_verbs[] = {
8532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8538 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8539 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8540 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8541 { } /* end */
8544 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8547 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8548 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8549 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8550 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8551 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8552 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8553 { } /* end */
8556 static struct hda_verb alc888_6st_dell_verbs[] = {
8557 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8561 static struct hda_verb alc883_vaiott_verbs[] = {
8562 /* HP */
8563 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8566 /* enable unsolicited event */
8567 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8569 { } /* end */
8572 static void alc888_3st_hp_setup(struct hda_codec *codec)
8574 struct alc_spec *spec = codec->spec;
8576 spec->autocfg.hp_pins[0] = 0x1b;
8577 spec->autocfg.speaker_pins[0] = 0x14;
8578 spec->autocfg.speaker_pins[1] = 0x16;
8579 spec->autocfg.speaker_pins[2] = 0x18;
8582 static struct hda_verb alc888_3st_hp_verbs[] = {
8583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8584 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8585 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8586 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8587 { } /* end */
8591 * 2ch mode
8593 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8594 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8595 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8596 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8597 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8598 { } /* end */
8602 * 4ch mode
8604 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8605 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8606 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8607 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8608 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8609 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8610 { } /* end */
8614 * 6ch mode
8616 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8617 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8618 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8619 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8620 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8621 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8622 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8623 { } /* end */
8626 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8627 { 2, alc888_3st_hp_2ch_init },
8628 { 4, alc888_3st_hp_4ch_init },
8629 { 6, alc888_3st_hp_6ch_init },
8632 /* toggle front-jack and RCA according to the hp-jack state */
8633 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8635 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
8637 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8638 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8639 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8640 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8643 /* toggle RCA according to the front-jack state */
8644 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8646 unsigned int present = snd_hda_jack_detect(codec, 0x14);
8648 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8649 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8652 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8653 unsigned int res)
8655 if ((res >> 26) == ALC880_HP_EVENT)
8656 alc888_lenovo_ms7195_front_automute(codec);
8657 if ((res >> 26) == ALC880_FRONT_EVENT)
8658 alc888_lenovo_ms7195_rca_automute(codec);
8661 static struct hda_verb alc883_medion_md2_verbs[] = {
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8668 { } /* end */
8671 /* toggle speaker-output according to the hp-jack state */
8672 static void alc883_medion_md2_setup(struct hda_codec *codec)
8674 struct alc_spec *spec = codec->spec;
8676 spec->autocfg.hp_pins[0] = 0x14;
8677 spec->autocfg.speaker_pins[0] = 0x15;
8680 /* toggle speaker-output according to the hp-jack state */
8681 #define alc883_targa_init_hook alc882_targa_init_hook
8682 #define alc883_targa_unsol_event alc882_targa_unsol_event
8684 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8686 unsigned int present;
8688 present = snd_hda_jack_detect(codec, 0x18);
8689 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8690 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8693 static void alc883_clevo_m720_setup(struct hda_codec *codec)
8695 struct alc_spec *spec = codec->spec;
8697 spec->autocfg.hp_pins[0] = 0x15;
8698 spec->autocfg.speaker_pins[0] = 0x14;
8701 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8703 alc_automute_amp(codec);
8704 alc883_clevo_m720_mic_automute(codec);
8707 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8708 unsigned int res)
8710 switch (res >> 26) {
8711 case ALC880_MIC_EVENT:
8712 alc883_clevo_m720_mic_automute(codec);
8713 break;
8714 default:
8715 alc_automute_amp_unsol_event(codec, res);
8716 break;
8720 /* toggle speaker-output according to the hp-jack state */
8721 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8723 struct alc_spec *spec = codec->spec;
8725 spec->autocfg.hp_pins[0] = 0x14;
8726 spec->autocfg.speaker_pins[0] = 0x15;
8729 static void alc883_haier_w66_setup(struct hda_codec *codec)
8731 struct alc_spec *spec = codec->spec;
8733 spec->autocfg.hp_pins[0] = 0x1b;
8734 spec->autocfg.speaker_pins[0] = 0x14;
8737 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8739 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
8741 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8742 HDA_AMP_MUTE, bits);
8745 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8747 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
8749 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8750 HDA_AMP_MUTE, bits);
8751 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8752 HDA_AMP_MUTE, bits);
8755 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8756 unsigned int res)
8758 if ((res >> 26) == ALC880_HP_EVENT)
8759 alc883_lenovo_101e_all_automute(codec);
8760 if ((res >> 26) == ALC880_FRONT_EVENT)
8761 alc883_lenovo_101e_ispeaker_automute(codec);
8764 /* toggle speaker-output according to the hp-jack state */
8765 static void alc883_acer_aspire_setup(struct hda_codec *codec)
8767 struct alc_spec *spec = codec->spec;
8769 spec->autocfg.hp_pins[0] = 0x14;
8770 spec->autocfg.speaker_pins[0] = 0x15;
8771 spec->autocfg.speaker_pins[1] = 0x16;
8774 static struct hda_verb alc883_acer_eapd_verbs[] = {
8775 /* HP Pin: output 0 (0x0c) */
8776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8778 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* Front Pin: output 0 (0x0c) */
8780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8782 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8783 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8784 /* eanable EAPD on medion laptop */
8785 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8786 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8787 /* enable unsolicited event */
8788 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8792 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8793 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8796 { } /* end */
8799 static void alc888_6st_dell_setup(struct hda_codec *codec)
8801 struct alc_spec *spec = codec->spec;
8803 spec->autocfg.hp_pins[0] = 0x1b;
8804 spec->autocfg.speaker_pins[0] = 0x14;
8805 spec->autocfg.speaker_pins[1] = 0x15;
8806 spec->autocfg.speaker_pins[2] = 0x16;
8807 spec->autocfg.speaker_pins[3] = 0x17;
8810 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8812 struct alc_spec *spec = codec->spec;
8814 spec->autocfg.hp_pins[0] = 0x1b;
8815 spec->autocfg.speaker_pins[0] = 0x14;
8816 spec->autocfg.speaker_pins[1] = 0x15;
8817 spec->autocfg.speaker_pins[2] = 0x16;
8818 spec->autocfg.speaker_pins[3] = 0x17;
8819 spec->autocfg.speaker_pins[4] = 0x1a;
8822 static void alc883_vaiott_setup(struct hda_codec *codec)
8824 struct alc_spec *spec = codec->spec;
8826 spec->autocfg.hp_pins[0] = 0x15;
8827 spec->autocfg.speaker_pins[0] = 0x14;
8828 spec->autocfg.speaker_pins[1] = 0x17;
8831 static struct hda_verb alc888_asus_m90v_verbs[] = {
8832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8833 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8835 /* enable unsolicited event */
8836 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8837 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8838 { } /* end */
8841 static void alc883_mode2_setup(struct hda_codec *codec)
8843 struct alc_spec *spec = codec->spec;
8845 spec->autocfg.hp_pins[0] = 0x1b;
8846 spec->autocfg.speaker_pins[0] = 0x14;
8847 spec->autocfg.speaker_pins[1] = 0x15;
8848 spec->autocfg.speaker_pins[2] = 0x16;
8849 spec->ext_mic.pin = 0x18;
8850 spec->int_mic.pin = 0x19;
8851 spec->ext_mic.mux_idx = 0;
8852 spec->int_mic.mux_idx = 1;
8853 spec->auto_mic = 1;
8856 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8858 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8860 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8861 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8862 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8863 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8864 /* enable unsolicited event */
8865 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8866 { } /* end */
8869 static void alc883_eee1601_inithook(struct hda_codec *codec)
8871 struct alc_spec *spec = codec->spec;
8873 spec->autocfg.hp_pins[0] = 0x14;
8874 spec->autocfg.speaker_pins[0] = 0x1b;
8875 alc_automute_pin(codec);
8878 static struct hda_verb alc889A_mb31_verbs[] = {
8879 /* Init rear pin (used as headphone output) */
8880 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8881 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8882 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8883 /* Init line pin (used as output in 4ch and 6ch mode) */
8884 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8885 /* Init line 2 pin (used as headphone out by default) */
8886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8887 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8888 { } /* end */
8891 /* Mute speakers according to the headphone jack state */
8892 static void alc889A_mb31_automute(struct hda_codec *codec)
8894 unsigned int present;
8896 /* Mute only in 2ch or 4ch mode */
8897 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8898 == 0x00) {
8899 present = snd_hda_jack_detect(codec, 0x15);
8900 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8901 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8902 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8903 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8907 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8909 if ((res >> 26) == ALC880_HP_EVENT)
8910 alc889A_mb31_automute(codec);
8914 #ifdef CONFIG_SND_HDA_POWER_SAVE
8915 #define alc882_loopbacks alc880_loopbacks
8916 #endif
8918 /* pcm configuration: identical with ALC880 */
8919 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
8920 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
8921 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
8922 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
8924 static hda_nid_t alc883_slave_dig_outs[] = {
8925 ALC1200_DIGOUT_NID, 0,
8928 static hda_nid_t alc1200_slave_dig_outs[] = {
8929 ALC883_DIGOUT_NID, 0,
8933 * configuration and preset
8935 static const char *alc882_models[ALC882_MODEL_LAST] = {
8936 [ALC882_3ST_DIG] = "3stack-dig",
8937 [ALC882_6ST_DIG] = "6stack-dig",
8938 [ALC882_ARIMA] = "arima",
8939 [ALC882_W2JC] = "w2jc",
8940 [ALC882_TARGA] = "targa",
8941 [ALC882_ASUS_A7J] = "asus-a7j",
8942 [ALC882_ASUS_A7M] = "asus-a7m",
8943 [ALC885_MACPRO] = "macpro",
8944 [ALC885_MB5] = "mb5",
8945 [ALC885_MBP3] = "mbp3",
8946 [ALC885_IMAC24] = "imac24",
8947 [ALC885_IMAC91] = "imac91",
8948 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8949 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8950 [ALC883_3ST_6ch] = "3stack-6ch",
8951 [ALC883_6ST_DIG] = "alc883-6stack-dig",
8952 [ALC883_TARGA_DIG] = "targa-dig",
8953 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8954 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8955 [ALC883_ACER] = "acer",
8956 [ALC883_ACER_ASPIRE] = "acer-aspire",
8957 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8958 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
8959 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8960 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
8961 [ALC883_MEDION] = "medion",
8962 [ALC883_MEDION_MD2] = "medion-md2",
8963 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8964 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8965 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8966 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8967 [ALC888_LENOVO_SKY] = "lenovo-sky",
8968 [ALC883_HAIER_W66] = "haier-w66",
8969 [ALC888_3ST_HP] = "3stack-hp",
8970 [ALC888_6ST_DELL] = "6stack-dell",
8971 [ALC883_MITAC] = "mitac",
8972 [ALC883_CLEVO_M540R] = "clevo-m540r",
8973 [ALC883_CLEVO_M720] = "clevo-m720",
8974 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8975 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8976 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8977 [ALC889A_INTEL] = "intel-alc889a",
8978 [ALC889_INTEL] = "intel-x58",
8979 [ALC1200_ASUS_P5Q] = "asus-p5q",
8980 [ALC889A_MB31] = "mb31",
8981 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8982 [ALC882_AUTO] = "auto",
8985 static struct snd_pci_quirk alc882_cfg_tbl[] = {
8986 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8988 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8989 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8990 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8991 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8992 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8993 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8994 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8995 ALC888_ACER_ASPIRE_4930G),
8996 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8997 ALC888_ACER_ASPIRE_4930G),
8998 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8999 ALC888_ACER_ASPIRE_8930G),
9000 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9001 ALC888_ACER_ASPIRE_8930G),
9002 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9003 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9004 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9005 ALC888_ACER_ASPIRE_6530G),
9006 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9007 ALC888_ACER_ASPIRE_6530G),
9008 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9009 ALC888_ACER_ASPIRE_7730G),
9010 /* default Acer -- disabled as it causes more problems.
9011 * model=auto should work fine now
9013 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9015 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9017 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9018 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9019 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9020 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9021 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9022 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9024 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9025 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9026 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9027 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9028 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9029 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9030 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9031 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9032 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9033 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9034 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9036 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9037 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9038 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9039 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9040 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9041 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9042 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9043 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9044 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9046 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9047 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9048 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9049 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9050 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9051 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9052 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9053 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9054 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9055 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9056 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9057 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9058 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9059 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9060 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9061 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9062 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9063 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9064 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9065 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9066 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9067 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9068 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9069 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9070 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9071 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9072 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9073 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9074 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9076 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9077 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9078 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9079 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9080 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9081 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9082 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9083 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9084 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9085 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9086 ALC883_FUJITSU_PI2515),
9087 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9088 ALC888_FUJITSU_XA3530),
9089 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9090 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9091 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9092 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9093 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9094 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9095 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9096 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9097 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9099 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9100 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9101 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9102 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9103 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9104 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9105 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9110 /* codec SSID table for Intel Mac */
9111 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9112 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9113 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9114 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9115 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9116 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9117 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9118 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9119 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9120 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9121 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9122 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9123 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9124 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9125 * so apparently no perfect solution yet
9127 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9128 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9129 {} /* terminator */
9132 static struct alc_config_preset alc882_presets[] = {
9133 [ALC882_3ST_DIG] = {
9134 .mixers = { alc882_base_mixer },
9135 .init_verbs = { alc882_base_init_verbs,
9136 alc882_adc1_init_verbs },
9137 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9138 .dac_nids = alc882_dac_nids,
9139 .dig_out_nid = ALC882_DIGOUT_NID,
9140 .dig_in_nid = ALC882_DIGIN_NID,
9141 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9142 .channel_mode = alc882_ch_modes,
9143 .need_dac_fix = 1,
9144 .input_mux = &alc882_capture_source,
9146 [ALC882_6ST_DIG] = {
9147 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9148 .init_verbs = { alc882_base_init_verbs,
9149 alc882_adc1_init_verbs },
9150 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9151 .dac_nids = alc882_dac_nids,
9152 .dig_out_nid = ALC882_DIGOUT_NID,
9153 .dig_in_nid = ALC882_DIGIN_NID,
9154 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9155 .channel_mode = alc882_sixstack_modes,
9156 .input_mux = &alc882_capture_source,
9158 [ALC882_ARIMA] = {
9159 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9160 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9161 alc882_eapd_verbs },
9162 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9163 .dac_nids = alc882_dac_nids,
9164 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9165 .channel_mode = alc882_sixstack_modes,
9166 .input_mux = &alc882_capture_source,
9168 [ALC882_W2JC] = {
9169 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
9170 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9171 alc882_eapd_verbs, alc880_gpio1_init_verbs },
9172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9173 .dac_nids = alc882_dac_nids,
9174 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9175 .channel_mode = alc880_threestack_modes,
9176 .need_dac_fix = 1,
9177 .input_mux = &alc882_capture_source,
9178 .dig_out_nid = ALC882_DIGOUT_NID,
9180 [ALC885_MBP3] = {
9181 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9182 .init_verbs = { alc885_mbp3_init_verbs,
9183 alc880_gpio1_init_verbs },
9184 .num_dacs = 2,
9185 .dac_nids = alc882_dac_nids,
9186 .hp_nid = 0x04,
9187 .channel_mode = alc885_mbp_4ch_modes,
9188 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9189 .input_mux = &alc882_capture_source,
9190 .dig_out_nid = ALC882_DIGOUT_NID,
9191 .dig_in_nid = ALC882_DIGIN_NID,
9192 .unsol_event = alc_automute_amp_unsol_event,
9193 .setup = alc885_mbp3_setup,
9194 .init_hook = alc_automute_amp,
9196 [ALC885_MB5] = {
9197 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9198 .init_verbs = { alc885_mb5_init_verbs,
9199 alc880_gpio1_init_verbs },
9200 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9201 .dac_nids = alc882_dac_nids,
9202 .channel_mode = alc885_mb5_6ch_modes,
9203 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9204 .input_mux = &mb5_capture_source,
9205 .dig_out_nid = ALC882_DIGOUT_NID,
9206 .dig_in_nid = ALC882_DIGIN_NID,
9207 .unsol_event = alc885_mb5_unsol_event,
9208 .init_hook = alc885_mb5_automute,
9210 [ALC885_MACPRO] = {
9211 .mixers = { alc882_macpro_mixer },
9212 .init_verbs = { alc882_macpro_init_verbs },
9213 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9214 .dac_nids = alc882_dac_nids,
9215 .dig_out_nid = ALC882_DIGOUT_NID,
9216 .dig_in_nid = ALC882_DIGIN_NID,
9217 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9218 .channel_mode = alc882_ch_modes,
9219 .input_mux = &alc882_capture_source,
9220 .init_hook = alc885_macpro_init_hook,
9222 [ALC885_IMAC24] = {
9223 .mixers = { alc885_imac24_mixer },
9224 .init_verbs = { alc885_imac24_init_verbs },
9225 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9226 .dac_nids = alc882_dac_nids,
9227 .dig_out_nid = ALC882_DIGOUT_NID,
9228 .dig_in_nid = ALC882_DIGIN_NID,
9229 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9230 .channel_mode = alc882_ch_modes,
9231 .input_mux = &alc882_capture_source,
9232 .unsol_event = alc_automute_amp_unsol_event,
9233 .setup = alc885_imac24_setup,
9234 .init_hook = alc885_imac24_init_hook,
9236 [ALC885_IMAC91] = {
9237 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9238 .init_verbs = { alc885_imac91_init_verbs,
9239 alc880_gpio1_init_verbs },
9240 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9241 .dac_nids = alc882_dac_nids,
9242 .channel_mode = alc885_mbp_4ch_modes,
9243 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9244 .input_mux = &alc882_capture_source,
9245 .dig_out_nid = ALC882_DIGOUT_NID,
9246 .dig_in_nid = ALC882_DIGIN_NID,
9247 .unsol_event = alc885_imac91_unsol_event,
9248 .init_hook = alc885_imac91_automute,
9250 [ALC882_TARGA] = {
9251 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9252 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9253 alc880_gpio3_init_verbs, alc882_targa_verbs},
9254 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9255 .dac_nids = alc882_dac_nids,
9256 .dig_out_nid = ALC882_DIGOUT_NID,
9257 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9258 .adc_nids = alc882_adc_nids,
9259 .capsrc_nids = alc882_capsrc_nids,
9260 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9261 .channel_mode = alc882_3ST_6ch_modes,
9262 .need_dac_fix = 1,
9263 .input_mux = &alc882_capture_source,
9264 .unsol_event = alc882_targa_unsol_event,
9265 .setup = alc882_targa_setup,
9266 .init_hook = alc882_targa_automute,
9268 [ALC882_ASUS_A7J] = {
9269 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9270 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9271 alc882_asus_a7j_verbs},
9272 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9273 .dac_nids = alc882_dac_nids,
9274 .dig_out_nid = ALC882_DIGOUT_NID,
9275 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9276 .adc_nids = alc882_adc_nids,
9277 .capsrc_nids = alc882_capsrc_nids,
9278 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9279 .channel_mode = alc882_3ST_6ch_modes,
9280 .need_dac_fix = 1,
9281 .input_mux = &alc882_capture_source,
9283 [ALC882_ASUS_A7M] = {
9284 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9285 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9286 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9287 alc882_asus_a7m_verbs },
9288 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9289 .dac_nids = alc882_dac_nids,
9290 .dig_out_nid = ALC882_DIGOUT_NID,
9291 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9292 .channel_mode = alc880_threestack_modes,
9293 .need_dac_fix = 1,
9294 .input_mux = &alc882_capture_source,
9296 [ALC883_3ST_2ch_DIG] = {
9297 .mixers = { alc883_3ST_2ch_mixer },
9298 .init_verbs = { alc883_init_verbs },
9299 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9300 .dac_nids = alc883_dac_nids,
9301 .dig_out_nid = ALC883_DIGOUT_NID,
9302 .dig_in_nid = ALC883_DIGIN_NID,
9303 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9304 .channel_mode = alc883_3ST_2ch_modes,
9305 .input_mux = &alc883_capture_source,
9307 [ALC883_3ST_6ch_DIG] = {
9308 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9309 .init_verbs = { alc883_init_verbs },
9310 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9311 .dac_nids = alc883_dac_nids,
9312 .dig_out_nid = ALC883_DIGOUT_NID,
9313 .dig_in_nid = ALC883_DIGIN_NID,
9314 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9315 .channel_mode = alc883_3ST_6ch_modes,
9316 .need_dac_fix = 1,
9317 .input_mux = &alc883_capture_source,
9319 [ALC883_3ST_6ch] = {
9320 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9321 .init_verbs = { alc883_init_verbs },
9322 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9323 .dac_nids = alc883_dac_nids,
9324 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9325 .channel_mode = alc883_3ST_6ch_modes,
9326 .need_dac_fix = 1,
9327 .input_mux = &alc883_capture_source,
9329 [ALC883_3ST_6ch_INTEL] = {
9330 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9331 .init_verbs = { alc883_init_verbs },
9332 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9333 .dac_nids = alc883_dac_nids,
9334 .dig_out_nid = ALC883_DIGOUT_NID,
9335 .dig_in_nid = ALC883_DIGIN_NID,
9336 .slave_dig_outs = alc883_slave_dig_outs,
9337 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9338 .channel_mode = alc883_3ST_6ch_intel_modes,
9339 .need_dac_fix = 1,
9340 .input_mux = &alc883_3stack_6ch_intel,
9342 [ALC889A_INTEL] = {
9343 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9344 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9345 alc_hp15_unsol_verbs },
9346 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9347 .dac_nids = alc883_dac_nids,
9348 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9349 .adc_nids = alc889_adc_nids,
9350 .dig_out_nid = ALC883_DIGOUT_NID,
9351 .dig_in_nid = ALC883_DIGIN_NID,
9352 .slave_dig_outs = alc883_slave_dig_outs,
9353 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9354 .channel_mode = alc889_8ch_intel_modes,
9355 .capsrc_nids = alc889_capsrc_nids,
9356 .input_mux = &alc889_capture_source,
9357 .setup = alc889_automute_setup,
9358 .init_hook = alc_automute_amp,
9359 .unsol_event = alc_automute_amp_unsol_event,
9360 .need_dac_fix = 1,
9362 [ALC889_INTEL] = {
9363 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9364 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9365 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9366 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9367 .dac_nids = alc883_dac_nids,
9368 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9369 .adc_nids = alc889_adc_nids,
9370 .dig_out_nid = ALC883_DIGOUT_NID,
9371 .dig_in_nid = ALC883_DIGIN_NID,
9372 .slave_dig_outs = alc883_slave_dig_outs,
9373 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9374 .channel_mode = alc889_8ch_intel_modes,
9375 .capsrc_nids = alc889_capsrc_nids,
9376 .input_mux = &alc889_capture_source,
9377 .setup = alc889_automute_setup,
9378 .init_hook = alc889_intel_init_hook,
9379 .unsol_event = alc_automute_amp_unsol_event,
9380 .need_dac_fix = 1,
9382 [ALC883_6ST_DIG] = {
9383 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9384 .init_verbs = { alc883_init_verbs },
9385 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9386 .dac_nids = alc883_dac_nids,
9387 .dig_out_nid = ALC883_DIGOUT_NID,
9388 .dig_in_nid = ALC883_DIGIN_NID,
9389 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9390 .channel_mode = alc883_sixstack_modes,
9391 .input_mux = &alc883_capture_source,
9393 [ALC883_TARGA_DIG] = {
9394 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9395 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9396 alc883_targa_verbs},
9397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9398 .dac_nids = alc883_dac_nids,
9399 .dig_out_nid = ALC883_DIGOUT_NID,
9400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9401 .channel_mode = alc883_3ST_6ch_modes,
9402 .need_dac_fix = 1,
9403 .input_mux = &alc883_capture_source,
9404 .unsol_event = alc883_targa_unsol_event,
9405 .setup = alc882_targa_setup,
9406 .init_hook = alc882_targa_automute,
9408 [ALC883_TARGA_2ch_DIG] = {
9409 .mixers = { alc883_targa_2ch_mixer},
9410 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9411 alc883_targa_verbs},
9412 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9413 .dac_nids = alc883_dac_nids,
9414 .adc_nids = alc883_adc_nids_alt,
9415 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9416 .capsrc_nids = alc883_capsrc_nids,
9417 .dig_out_nid = ALC883_DIGOUT_NID,
9418 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9419 .channel_mode = alc883_3ST_2ch_modes,
9420 .input_mux = &alc883_capture_source,
9421 .unsol_event = alc883_targa_unsol_event,
9422 .setup = alc882_targa_setup,
9423 .init_hook = alc882_targa_automute,
9425 [ALC883_TARGA_8ch_DIG] = {
9426 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9427 alc883_chmode_mixer },
9428 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9429 alc883_targa_verbs },
9430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9431 .dac_nids = alc883_dac_nids,
9432 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9433 .adc_nids = alc883_adc_nids_rev,
9434 .capsrc_nids = alc883_capsrc_nids_rev,
9435 .dig_out_nid = ALC883_DIGOUT_NID,
9436 .dig_in_nid = ALC883_DIGIN_NID,
9437 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9438 .channel_mode = alc883_4ST_8ch_modes,
9439 .need_dac_fix = 1,
9440 .input_mux = &alc883_capture_source,
9441 .unsol_event = alc883_targa_unsol_event,
9442 .setup = alc882_targa_setup,
9443 .init_hook = alc882_targa_automute,
9445 [ALC883_ACER] = {
9446 .mixers = { alc883_base_mixer },
9447 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9448 * and the headphone jack. Turn this on and rely on the
9449 * standard mute methods whenever the user wants to turn
9450 * these outputs off.
9452 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9454 .dac_nids = alc883_dac_nids,
9455 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9456 .channel_mode = alc883_3ST_2ch_modes,
9457 .input_mux = &alc883_capture_source,
9459 [ALC883_ACER_ASPIRE] = {
9460 .mixers = { alc883_acer_aspire_mixer },
9461 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9462 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9463 .dac_nids = alc883_dac_nids,
9464 .dig_out_nid = ALC883_DIGOUT_NID,
9465 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9466 .channel_mode = alc883_3ST_2ch_modes,
9467 .input_mux = &alc883_capture_source,
9468 .unsol_event = alc_automute_amp_unsol_event,
9469 .setup = alc883_acer_aspire_setup,
9470 .init_hook = alc_automute_amp,
9472 [ALC888_ACER_ASPIRE_4930G] = {
9473 .mixers = { alc888_base_mixer,
9474 alc883_chmode_mixer },
9475 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9476 alc888_acer_aspire_4930g_verbs },
9477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9478 .dac_nids = alc883_dac_nids,
9479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9480 .adc_nids = alc883_adc_nids_rev,
9481 .capsrc_nids = alc883_capsrc_nids_rev,
9482 .dig_out_nid = ALC883_DIGOUT_NID,
9483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9484 .channel_mode = alc883_3ST_6ch_modes,
9485 .need_dac_fix = 1,
9486 .const_channel_count = 6,
9487 .num_mux_defs =
9488 ARRAY_SIZE(alc888_2_capture_sources),
9489 .input_mux = alc888_2_capture_sources,
9490 .unsol_event = alc_automute_amp_unsol_event,
9491 .setup = alc888_acer_aspire_4930g_setup,
9492 .init_hook = alc_automute_amp,
9494 [ALC888_ACER_ASPIRE_6530G] = {
9495 .mixers = { alc888_acer_aspire_6530_mixer },
9496 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9497 alc888_acer_aspire_6530g_verbs },
9498 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9499 .dac_nids = alc883_dac_nids,
9500 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9501 .adc_nids = alc883_adc_nids_rev,
9502 .capsrc_nids = alc883_capsrc_nids_rev,
9503 .dig_out_nid = ALC883_DIGOUT_NID,
9504 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9505 .channel_mode = alc883_3ST_2ch_modes,
9506 .num_mux_defs =
9507 ARRAY_SIZE(alc888_2_capture_sources),
9508 .input_mux = alc888_acer_aspire_6530_sources,
9509 .unsol_event = alc_automute_amp_unsol_event,
9510 .setup = alc888_acer_aspire_6530g_setup,
9511 .init_hook = alc_automute_amp,
9513 [ALC888_ACER_ASPIRE_8930G] = {
9514 .mixers = { alc889_acer_aspire_8930g_mixer,
9515 alc883_chmode_mixer },
9516 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9517 alc889_acer_aspire_8930g_verbs,
9518 alc889_eapd_verbs},
9519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9520 .dac_nids = alc883_dac_nids,
9521 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9522 .adc_nids = alc889_adc_nids,
9523 .capsrc_nids = alc889_capsrc_nids,
9524 .dig_out_nid = ALC883_DIGOUT_NID,
9525 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9526 .channel_mode = alc883_3ST_6ch_modes,
9527 .need_dac_fix = 1,
9528 .const_channel_count = 6,
9529 .num_mux_defs =
9530 ARRAY_SIZE(alc889_capture_sources),
9531 .input_mux = alc889_capture_sources,
9532 .unsol_event = alc_automute_amp_unsol_event,
9533 .setup = alc889_acer_aspire_8930g_setup,
9534 .init_hook = alc_automute_amp,
9535 #ifdef CONFIG_SND_HDA_POWER_SAVE
9536 .power_hook = alc889_power_eapd,
9537 #endif
9539 [ALC888_ACER_ASPIRE_7730G] = {
9540 .mixers = { alc883_3ST_6ch_mixer,
9541 alc883_chmode_mixer },
9542 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9543 alc888_acer_aspire_7730G_verbs },
9544 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9545 .dac_nids = alc883_dac_nids,
9546 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9547 .adc_nids = alc883_adc_nids_rev,
9548 .capsrc_nids = alc883_capsrc_nids_rev,
9549 .dig_out_nid = ALC883_DIGOUT_NID,
9550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9551 .channel_mode = alc883_3ST_6ch_modes,
9552 .need_dac_fix = 1,
9553 .const_channel_count = 6,
9554 .input_mux = &alc883_capture_source,
9555 .unsol_event = alc_automute_amp_unsol_event,
9556 .setup = alc888_acer_aspire_6530g_setup,
9557 .init_hook = alc_automute_amp,
9559 [ALC883_MEDION] = {
9560 .mixers = { alc883_fivestack_mixer,
9561 alc883_chmode_mixer },
9562 .init_verbs = { alc883_init_verbs,
9563 alc883_medion_eapd_verbs },
9564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9565 .dac_nids = alc883_dac_nids,
9566 .adc_nids = alc883_adc_nids_alt,
9567 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9568 .capsrc_nids = alc883_capsrc_nids,
9569 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9570 .channel_mode = alc883_sixstack_modes,
9571 .input_mux = &alc883_capture_source,
9573 [ALC883_MEDION_MD2] = {
9574 .mixers = { alc883_medion_md2_mixer},
9575 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9577 .dac_nids = alc883_dac_nids,
9578 .dig_out_nid = ALC883_DIGOUT_NID,
9579 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9580 .channel_mode = alc883_3ST_2ch_modes,
9581 .input_mux = &alc883_capture_source,
9582 .unsol_event = alc_automute_amp_unsol_event,
9583 .setup = alc883_medion_md2_setup,
9584 .init_hook = alc_automute_amp,
9586 [ALC883_LAPTOP_EAPD] = {
9587 .mixers = { alc883_base_mixer },
9588 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9590 .dac_nids = alc883_dac_nids,
9591 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9592 .channel_mode = alc883_3ST_2ch_modes,
9593 .input_mux = &alc883_capture_source,
9595 [ALC883_CLEVO_M540R] = {
9596 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9597 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9598 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9599 .dac_nids = alc883_dac_nids,
9600 .dig_out_nid = ALC883_DIGOUT_NID,
9601 .dig_in_nid = ALC883_DIGIN_NID,
9602 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9603 .channel_mode = alc883_3ST_6ch_clevo_modes,
9604 .need_dac_fix = 1,
9605 .input_mux = &alc883_capture_source,
9606 /* This machine has the hardware HP auto-muting, thus
9607 * we need no software mute via unsol event
9610 [ALC883_CLEVO_M720] = {
9611 .mixers = { alc883_clevo_m720_mixer },
9612 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9614 .dac_nids = alc883_dac_nids,
9615 .dig_out_nid = ALC883_DIGOUT_NID,
9616 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9617 .channel_mode = alc883_3ST_2ch_modes,
9618 .input_mux = &alc883_capture_source,
9619 .unsol_event = alc883_clevo_m720_unsol_event,
9620 .setup = alc883_clevo_m720_setup,
9621 .init_hook = alc883_clevo_m720_init_hook,
9623 [ALC883_LENOVO_101E_2ch] = {
9624 .mixers = { alc883_lenovo_101e_2ch_mixer},
9625 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9626 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9627 .dac_nids = alc883_dac_nids,
9628 .adc_nids = alc883_adc_nids_alt,
9629 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9630 .capsrc_nids = alc883_capsrc_nids,
9631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9632 .channel_mode = alc883_3ST_2ch_modes,
9633 .input_mux = &alc883_lenovo_101e_capture_source,
9634 .unsol_event = alc883_lenovo_101e_unsol_event,
9635 .init_hook = alc883_lenovo_101e_all_automute,
9637 [ALC883_LENOVO_NB0763] = {
9638 .mixers = { alc883_lenovo_nb0763_mixer },
9639 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9641 .dac_nids = alc883_dac_nids,
9642 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9643 .channel_mode = alc883_3ST_2ch_modes,
9644 .need_dac_fix = 1,
9645 .input_mux = &alc883_lenovo_nb0763_capture_source,
9646 .unsol_event = alc_automute_amp_unsol_event,
9647 .setup = alc883_medion_md2_setup,
9648 .init_hook = alc_automute_amp,
9650 [ALC888_LENOVO_MS7195_DIG] = {
9651 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9652 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9654 .dac_nids = alc883_dac_nids,
9655 .dig_out_nid = ALC883_DIGOUT_NID,
9656 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9657 .channel_mode = alc883_3ST_6ch_modes,
9658 .need_dac_fix = 1,
9659 .input_mux = &alc883_capture_source,
9660 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9661 .init_hook = alc888_lenovo_ms7195_front_automute,
9663 [ALC883_HAIER_W66] = {
9664 .mixers = { alc883_targa_2ch_mixer},
9665 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9666 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9667 .dac_nids = alc883_dac_nids,
9668 .dig_out_nid = ALC883_DIGOUT_NID,
9669 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9670 .channel_mode = alc883_3ST_2ch_modes,
9671 .input_mux = &alc883_capture_source,
9672 .unsol_event = alc_automute_amp_unsol_event,
9673 .setup = alc883_haier_w66_setup,
9674 .init_hook = alc_automute_amp,
9676 [ALC888_3ST_HP] = {
9677 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9678 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9679 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9680 .dac_nids = alc883_dac_nids,
9681 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9682 .channel_mode = alc888_3st_hp_modes,
9683 .need_dac_fix = 1,
9684 .input_mux = &alc883_capture_source,
9685 .unsol_event = alc_automute_amp_unsol_event,
9686 .setup = alc888_3st_hp_setup,
9687 .init_hook = alc_automute_amp,
9689 [ALC888_6ST_DELL] = {
9690 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9691 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9693 .dac_nids = alc883_dac_nids,
9694 .dig_out_nid = ALC883_DIGOUT_NID,
9695 .dig_in_nid = ALC883_DIGIN_NID,
9696 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9697 .channel_mode = alc883_sixstack_modes,
9698 .input_mux = &alc883_capture_source,
9699 .unsol_event = alc_automute_amp_unsol_event,
9700 .setup = alc888_6st_dell_setup,
9701 .init_hook = alc_automute_amp,
9703 [ALC883_MITAC] = {
9704 .mixers = { alc883_mitac_mixer },
9705 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9707 .dac_nids = alc883_dac_nids,
9708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9709 .channel_mode = alc883_3ST_2ch_modes,
9710 .input_mux = &alc883_capture_source,
9711 .unsol_event = alc_automute_amp_unsol_event,
9712 .setup = alc883_mitac_setup,
9713 .init_hook = alc_automute_amp,
9715 [ALC883_FUJITSU_PI2515] = {
9716 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9717 .init_verbs = { alc883_init_verbs,
9718 alc883_2ch_fujitsu_pi2515_verbs},
9719 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9720 .dac_nids = alc883_dac_nids,
9721 .dig_out_nid = ALC883_DIGOUT_NID,
9722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9723 .channel_mode = alc883_3ST_2ch_modes,
9724 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9725 .unsol_event = alc_automute_amp_unsol_event,
9726 .setup = alc883_2ch_fujitsu_pi2515_setup,
9727 .init_hook = alc_automute_amp,
9729 [ALC888_FUJITSU_XA3530] = {
9730 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9731 .init_verbs = { alc883_init_verbs,
9732 alc888_fujitsu_xa3530_verbs },
9733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9734 .dac_nids = alc883_dac_nids,
9735 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9736 .adc_nids = alc883_adc_nids_rev,
9737 .capsrc_nids = alc883_capsrc_nids_rev,
9738 .dig_out_nid = ALC883_DIGOUT_NID,
9739 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9740 .channel_mode = alc888_4ST_8ch_intel_modes,
9741 .num_mux_defs =
9742 ARRAY_SIZE(alc888_2_capture_sources),
9743 .input_mux = alc888_2_capture_sources,
9744 .unsol_event = alc_automute_amp_unsol_event,
9745 .setup = alc888_fujitsu_xa3530_setup,
9746 .init_hook = alc_automute_amp,
9748 [ALC888_LENOVO_SKY] = {
9749 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9750 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9751 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9752 .dac_nids = alc883_dac_nids,
9753 .dig_out_nid = ALC883_DIGOUT_NID,
9754 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9755 .channel_mode = alc883_sixstack_modes,
9756 .need_dac_fix = 1,
9757 .input_mux = &alc883_lenovo_sky_capture_source,
9758 .unsol_event = alc_automute_amp_unsol_event,
9759 .setup = alc888_lenovo_sky_setup,
9760 .init_hook = alc_automute_amp,
9762 [ALC888_ASUS_M90V] = {
9763 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9764 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9765 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9766 .dac_nids = alc883_dac_nids,
9767 .dig_out_nid = ALC883_DIGOUT_NID,
9768 .dig_in_nid = ALC883_DIGIN_NID,
9769 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9770 .channel_mode = alc883_3ST_6ch_modes,
9771 .need_dac_fix = 1,
9772 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9773 .unsol_event = alc_sku_unsol_event,
9774 .setup = alc883_mode2_setup,
9775 .init_hook = alc_inithook,
9777 [ALC888_ASUS_EEE1601] = {
9778 .mixers = { alc883_asus_eee1601_mixer },
9779 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9780 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9781 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9782 .dac_nids = alc883_dac_nids,
9783 .dig_out_nid = ALC883_DIGOUT_NID,
9784 .dig_in_nid = ALC883_DIGIN_NID,
9785 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9786 .channel_mode = alc883_3ST_2ch_modes,
9787 .need_dac_fix = 1,
9788 .input_mux = &alc883_asus_eee1601_capture_source,
9789 .unsol_event = alc_sku_unsol_event,
9790 .init_hook = alc883_eee1601_inithook,
9792 [ALC1200_ASUS_P5Q] = {
9793 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9794 .init_verbs = { alc883_init_verbs },
9795 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9796 .dac_nids = alc883_dac_nids,
9797 .dig_out_nid = ALC1200_DIGOUT_NID,
9798 .dig_in_nid = ALC883_DIGIN_NID,
9799 .slave_dig_outs = alc1200_slave_dig_outs,
9800 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9801 .channel_mode = alc883_sixstack_modes,
9802 .input_mux = &alc883_capture_source,
9804 [ALC889A_MB31] = {
9805 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9806 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9807 alc880_gpio1_init_verbs },
9808 .adc_nids = alc883_adc_nids,
9809 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9810 .capsrc_nids = alc883_capsrc_nids,
9811 .dac_nids = alc883_dac_nids,
9812 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9813 .channel_mode = alc889A_mb31_6ch_modes,
9814 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9815 .input_mux = &alc889A_mb31_capture_source,
9816 .dig_out_nid = ALC883_DIGOUT_NID,
9817 .unsol_event = alc889A_mb31_unsol_event,
9818 .init_hook = alc889A_mb31_automute,
9820 [ALC883_SONY_VAIO_TT] = {
9821 .mixers = { alc883_vaiott_mixer },
9822 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9823 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9824 .dac_nids = alc883_dac_nids,
9825 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9826 .channel_mode = alc883_3ST_2ch_modes,
9827 .input_mux = &alc883_capture_source,
9828 .unsol_event = alc_automute_amp_unsol_event,
9829 .setup = alc883_vaiott_setup,
9830 .init_hook = alc_automute_amp,
9836 * Pin config fixes
9838 enum {
9839 PINFIX_ABIT_AW9D_MAX
9842 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9843 { 0x15, 0x01080104 }, /* side */
9844 { 0x16, 0x01011012 }, /* rear */
9845 { 0x17, 0x01016011 }, /* clfe */
9849 static const struct alc_fixup alc882_fixups[] = {
9850 [PINFIX_ABIT_AW9D_MAX] = {
9851 .pins = alc882_abit_aw9d_pinfix
9855 static struct snd_pci_quirk alc882_fixup_tbl[] = {
9856 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9861 * BIOS auto configuration
9863 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9864 const struct auto_pin_cfg *cfg)
9866 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9869 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9870 hda_nid_t nid, int pin_type,
9871 int dac_idx)
9873 /* set as output */
9874 struct alc_spec *spec = codec->spec;
9875 int idx;
9877 alc_set_pin_output(codec, nid, pin_type);
9878 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9879 idx = 4;
9880 else
9881 idx = spec->multiout.dac_nids[dac_idx] - 2;
9882 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9886 static void alc882_auto_init_multi_out(struct hda_codec *codec)
9888 struct alc_spec *spec = codec->spec;
9889 int i;
9891 for (i = 0; i <= HDA_SIDE; i++) {
9892 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9893 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9894 if (nid)
9895 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9900 static void alc882_auto_init_hp_out(struct hda_codec *codec)
9902 struct alc_spec *spec = codec->spec;
9903 hda_nid_t pin;
9905 pin = spec->autocfg.hp_pins[0];
9906 if (pin) /* connect to front */
9907 /* use dac 0 */
9908 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9909 pin = spec->autocfg.speaker_pins[0];
9910 if (pin)
9911 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9914 static void alc882_auto_init_analog_input(struct hda_codec *codec)
9916 struct alc_spec *spec = codec->spec;
9917 int i;
9919 for (i = 0; i < AUTO_PIN_LAST; i++) {
9920 hda_nid_t nid = spec->autocfg.input_pins[i];
9921 if (!nid)
9922 continue;
9923 alc_set_input_pin(codec, nid, i);
9924 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9925 snd_hda_codec_write(codec, nid, 0,
9926 AC_VERB_SET_AMP_GAIN_MUTE,
9927 AMP_OUT_MUTE);
9931 static void alc882_auto_init_input_src(struct hda_codec *codec)
9933 struct alc_spec *spec = codec->spec;
9934 int c;
9936 for (c = 0; c < spec->num_adc_nids; c++) {
9937 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9938 hda_nid_t nid = spec->capsrc_nids[c];
9939 unsigned int mux_idx;
9940 const struct hda_input_mux *imux;
9941 int conns, mute, idx, item;
9943 conns = snd_hda_get_connections(codec, nid, conn_list,
9944 ARRAY_SIZE(conn_list));
9945 if (conns < 0)
9946 continue;
9947 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9948 imux = &spec->input_mux[mux_idx];
9949 if (!imux->num_items && mux_idx > 0)
9950 imux = &spec->input_mux[0];
9951 for (idx = 0; idx < conns; idx++) {
9952 /* if the current connection is the selected one,
9953 * unmute it as default - otherwise mute it
9955 mute = AMP_IN_MUTE(idx);
9956 for (item = 0; item < imux->num_items; item++) {
9957 if (imux->items[item].index == idx) {
9958 if (spec->cur_mux[c] == item)
9959 mute = AMP_IN_UNMUTE(idx);
9960 break;
9963 /* check if we have a selector or mixer
9964 * we could check for the widget type instead, but
9965 * just check for Amp-In presence (in case of mixer
9966 * without amp-in there is something wrong, this
9967 * function shouldn't be used or capsrc nid is wrong)
9969 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9970 snd_hda_codec_write(codec, nid, 0,
9971 AC_VERB_SET_AMP_GAIN_MUTE,
9972 mute);
9973 else if (mute != AMP_IN_MUTE(idx))
9974 snd_hda_codec_write(codec, nid, 0,
9975 AC_VERB_SET_CONNECT_SEL,
9976 idx);
9981 /* add mic boosts if needed */
9982 static int alc_auto_add_mic_boost(struct hda_codec *codec)
9984 struct alc_spec *spec = codec->spec;
9985 int err;
9986 hda_nid_t nid;
9988 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9989 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9990 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9991 "Mic Boost",
9992 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9993 if (err < 0)
9994 return err;
9996 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9997 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9998 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9999 "Front Mic Boost",
10000 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10001 if (err < 0)
10002 return err;
10004 return 0;
10007 /* almost identical with ALC880 parser... */
10008 static int alc882_parse_auto_config(struct hda_codec *codec)
10010 struct alc_spec *spec = codec->spec;
10011 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10012 int i, err;
10014 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10015 alc882_ignore);
10016 if (err < 0)
10017 return err;
10018 if (!spec->autocfg.line_outs)
10019 return 0; /* can't find valid BIOS pin config */
10021 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10022 if (err < 0)
10023 return err;
10024 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10025 if (err < 0)
10026 return err;
10027 err = alc880_auto_create_extra_out(spec,
10028 spec->autocfg.speaker_pins[0],
10029 "Speaker");
10030 if (err < 0)
10031 return err;
10032 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10033 "Headphone");
10034 if (err < 0)
10035 return err;
10036 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10037 if (err < 0)
10038 return err;
10040 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10042 /* check multiple SPDIF-out (for recent codecs) */
10043 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10044 hda_nid_t dig_nid;
10045 err = snd_hda_get_connections(codec,
10046 spec->autocfg.dig_out_pins[i],
10047 &dig_nid, 1);
10048 if (err < 0)
10049 continue;
10050 if (!i)
10051 spec->multiout.dig_out_nid = dig_nid;
10052 else {
10053 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
10054 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
10055 break;
10056 spec->slave_dig_outs[i - 1] = dig_nid;
10059 if (spec->autocfg.dig_in_pin)
10060 spec->dig_in_nid = ALC880_DIGIN_NID;
10062 if (spec->kctls.list)
10063 add_mixer(spec, spec->kctls.list);
10065 add_verb(spec, alc883_auto_init_verbs);
10066 /* if ADC 0x07 is available, initialize it, too */
10067 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10068 add_verb(spec, alc882_adc1_init_verbs);
10070 spec->num_mux_defs = 1;
10071 spec->input_mux = &spec->private_imux[0];
10073 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
10075 err = alc_auto_add_mic_boost(codec);
10076 if (err < 0)
10077 return err;
10079 return 1; /* config found */
10082 /* additional initialization for auto-configuration model */
10083 static void alc882_auto_init(struct hda_codec *codec)
10085 struct alc_spec *spec = codec->spec;
10086 alc882_auto_init_multi_out(codec);
10087 alc882_auto_init_hp_out(codec);
10088 alc882_auto_init_analog_input(codec);
10089 alc882_auto_init_input_src(codec);
10090 if (spec->unsol_event)
10091 alc_inithook(codec);
10094 static int patch_alc882(struct hda_codec *codec)
10096 struct alc_spec *spec;
10097 int err, board_config;
10099 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10100 if (spec == NULL)
10101 return -ENOMEM;
10103 codec->spec = spec;
10105 switch (codec->vendor_id) {
10106 case 0x10ec0882:
10107 case 0x10ec0885:
10108 break;
10109 default:
10110 /* ALC883 and variants */
10111 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10112 break;
10115 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10116 alc882_models,
10117 alc882_cfg_tbl);
10119 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10120 board_config = snd_hda_check_board_codec_sid_config(codec,
10121 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10123 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10124 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10125 codec->chip_name);
10126 board_config = ALC882_AUTO;
10129 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
10131 if (board_config == ALC882_AUTO) {
10132 /* automatic parse from the BIOS config */
10133 err = alc882_parse_auto_config(codec);
10134 if (err < 0) {
10135 alc_free(codec);
10136 return err;
10137 } else if (!err) {
10138 printk(KERN_INFO
10139 "hda_codec: Cannot set up configuration "
10140 "from BIOS. Using base mode...\n");
10141 board_config = ALC882_3ST_DIG;
10145 err = snd_hda_attach_beep_device(codec, 0x1);
10146 if (err < 0) {
10147 alc_free(codec);
10148 return err;
10151 if (board_config != ALC882_AUTO)
10152 setup_preset(codec, &alc882_presets[board_config]);
10154 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10155 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10156 /* FIXME: setup DAC5 */
10157 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10158 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10160 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10161 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10163 if (codec->vendor_id == 0x10ec0888)
10164 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
10166 if (!spec->adc_nids && spec->input_mux) {
10167 int i, j;
10168 spec->num_adc_nids = 0;
10169 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10170 const struct hda_input_mux *imux = spec->input_mux;
10171 hda_nid_t cap;
10172 hda_nid_t items[16];
10173 hda_nid_t nid = alc882_adc_nids[i];
10174 unsigned int wcap = get_wcaps(codec, nid);
10175 /* get type */
10176 wcap = get_wcaps_type(wcap);
10177 if (wcap != AC_WID_AUD_IN)
10178 continue;
10179 spec->private_adc_nids[spec->num_adc_nids] = nid;
10180 err = snd_hda_get_connections(codec, nid, &cap, 1);
10181 if (err < 0)
10182 continue;
10183 err = snd_hda_get_connections(codec, cap, items,
10184 ARRAY_SIZE(items));
10185 if (err < 0)
10186 continue;
10187 for (j = 0; j < imux->num_items; j++)
10188 if (imux->items[j].index >= err)
10189 break;
10190 if (j < imux->num_items)
10191 continue;
10192 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10193 spec->num_adc_nids++;
10195 spec->adc_nids = spec->private_adc_nids;
10196 spec->capsrc_nids = spec->private_capsrc_nids;
10199 set_capture_mixer(codec);
10200 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10202 spec->vmaster_nid = 0x0c;
10204 codec->patch_ops = alc_patch_ops;
10205 if (board_config == ALC882_AUTO)
10206 spec->init_hook = alc882_auto_init;
10207 #ifdef CONFIG_SND_HDA_POWER_SAVE
10208 if (!spec->loopback.amplist)
10209 spec->loopback.amplist = alc882_loopbacks;
10210 #endif
10211 codec->proc_widget_hook = print_realtek_coef;
10213 return 0;
10218 * ALC262 support
10221 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10222 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10224 #define alc262_dac_nids alc260_dac_nids
10225 #define alc262_adc_nids alc882_adc_nids
10226 #define alc262_adc_nids_alt alc882_adc_nids_alt
10227 #define alc262_capsrc_nids alc882_capsrc_nids
10228 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10230 #define alc262_modes alc260_modes
10231 #define alc262_capture_source alc882_capture_source
10233 static hda_nid_t alc262_dmic_adc_nids[1] = {
10234 /* ADC0 */
10235 0x09
10238 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10240 static struct snd_kcontrol_new alc262_base_mixer[] = {
10241 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10242 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10243 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10244 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10249 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10250 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10251 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10252 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10253 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10255 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10256 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10257 { } /* end */
10260 /* update HP, line and mono-out pins according to the master switch */
10261 static void alc262_hp_master_update(struct hda_codec *codec)
10263 struct alc_spec *spec = codec->spec;
10264 int val = spec->master_sw;
10266 /* HP & line-out */
10267 snd_hda_codec_write_cache(codec, 0x1b, 0,
10268 AC_VERB_SET_PIN_WIDGET_CONTROL,
10269 val ? PIN_HP : 0);
10270 snd_hda_codec_write_cache(codec, 0x15, 0,
10271 AC_VERB_SET_PIN_WIDGET_CONTROL,
10272 val ? PIN_HP : 0);
10273 /* mono (speaker) depending on the HP jack sense */
10274 val = val && !spec->jack_present;
10275 snd_hda_codec_write_cache(codec, 0x16, 0,
10276 AC_VERB_SET_PIN_WIDGET_CONTROL,
10277 val ? PIN_OUT : 0);
10280 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10282 struct alc_spec *spec = codec->spec;
10284 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10285 alc262_hp_master_update(codec);
10288 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10290 if ((res >> 26) != ALC880_HP_EVENT)
10291 return;
10292 alc262_hp_bpc_automute(codec);
10295 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10297 struct alc_spec *spec = codec->spec;
10299 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10300 alc262_hp_master_update(codec);
10303 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10304 unsigned int res)
10306 if ((res >> 26) != ALC880_HP_EVENT)
10307 return;
10308 alc262_hp_wildwest_automute(codec);
10311 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10313 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10314 struct snd_ctl_elem_value *ucontrol)
10316 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10317 struct alc_spec *spec = codec->spec;
10318 int val = !!*ucontrol->value.integer.value;
10320 if (val == spec->master_sw)
10321 return 0;
10322 spec->master_sw = val;
10323 alc262_hp_master_update(codec);
10324 return 1;
10327 #define ALC262_HP_MASTER_SWITCH \
10329 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10330 .name = "Master Playback Switch", \
10331 .info = snd_ctl_boolean_mono_info, \
10332 .get = alc262_hp_master_sw_get, \
10333 .put = alc262_hp_master_sw_put, \
10336 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10337 ALC262_HP_MASTER_SWITCH,
10338 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10339 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10340 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10341 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10342 HDA_OUTPUT),
10343 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10344 HDA_OUTPUT),
10345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10347 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10348 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10349 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10350 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10351 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10352 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10353 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10354 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10355 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10356 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10357 { } /* end */
10360 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10361 ALC262_HP_MASTER_SWITCH,
10362 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10363 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10364 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10366 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10367 HDA_OUTPUT),
10368 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10369 HDA_OUTPUT),
10370 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10372 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10373 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10374 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10375 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10376 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10377 { } /* end */
10380 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10381 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10382 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10383 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10384 { } /* end */
10387 /* mute/unmute internal speaker according to the hp jack and mute state */
10388 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10390 struct alc_spec *spec = codec->spec;
10392 spec->autocfg.hp_pins[0] = 0x15;
10393 spec->autocfg.speaker_pins[0] = 0x14;
10396 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10397 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10398 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10400 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10401 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10402 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10404 { } /* end */
10407 static struct hda_verb alc262_hp_t5735_verbs[] = {
10408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10411 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10415 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10416 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10417 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10418 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10419 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10422 { } /* end */
10425 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10426 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10428 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10429 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10430 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10431 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10434 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10439 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10440 .num_items = 1,
10441 .items = {
10442 { "Line", 0x1 },
10446 /* bind hp and internal speaker mute (with plug check) as master switch */
10447 static void alc262_hippo_master_update(struct hda_codec *codec)
10449 struct alc_spec *spec = codec->spec;
10450 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10451 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10452 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10453 unsigned int mute;
10455 /* HP */
10456 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10457 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10458 HDA_AMP_MUTE, mute);
10459 /* mute internal speaker per jack sense */
10460 if (spec->jack_present)
10461 mute = HDA_AMP_MUTE;
10462 if (line_nid)
10463 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10464 HDA_AMP_MUTE, mute);
10465 if (speaker_nid && speaker_nid != line_nid)
10466 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10467 HDA_AMP_MUTE, mute);
10470 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10472 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10473 struct snd_ctl_elem_value *ucontrol)
10475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10476 struct alc_spec *spec = codec->spec;
10477 int val = !!*ucontrol->value.integer.value;
10479 if (val == spec->master_sw)
10480 return 0;
10481 spec->master_sw = val;
10482 alc262_hippo_master_update(codec);
10483 return 1;
10486 #define ALC262_HIPPO_MASTER_SWITCH \
10488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10489 .name = "Master Playback Switch", \
10490 .info = snd_ctl_boolean_mono_info, \
10491 .get = alc262_hippo_master_sw_get, \
10492 .put = alc262_hippo_master_sw_put, \
10495 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10496 ALC262_HIPPO_MASTER_SWITCH,
10497 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10498 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10499 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10500 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10501 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10502 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10503 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10504 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10505 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10506 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10507 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10508 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10509 { } /* end */
10512 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10513 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10514 ALC262_HIPPO_MASTER_SWITCH,
10515 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10516 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10517 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10518 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10519 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10520 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10521 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10522 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10523 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10524 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10525 { } /* end */
10528 /* mute/unmute internal speaker according to the hp jack and mute state */
10529 static void alc262_hippo_automute(struct hda_codec *codec)
10531 struct alc_spec *spec = codec->spec;
10532 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10534 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10535 alc262_hippo_master_update(codec);
10538 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10540 if ((res >> 26) != ALC880_HP_EVENT)
10541 return;
10542 alc262_hippo_automute(codec);
10545 static void alc262_hippo_setup(struct hda_codec *codec)
10547 struct alc_spec *spec = codec->spec;
10549 spec->autocfg.hp_pins[0] = 0x15;
10550 spec->autocfg.speaker_pins[0] = 0x14;
10553 static void alc262_hippo1_setup(struct hda_codec *codec)
10555 struct alc_spec *spec = codec->spec;
10557 spec->autocfg.hp_pins[0] = 0x1b;
10558 spec->autocfg.speaker_pins[0] = 0x14;
10562 static struct snd_kcontrol_new alc262_sony_mixer[] = {
10563 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10564 ALC262_HIPPO_MASTER_SWITCH,
10565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10566 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10567 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10568 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10569 { } /* end */
10572 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10573 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10574 ALC262_HIPPO_MASTER_SWITCH,
10575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10578 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10579 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10580 { } /* end */
10583 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10584 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10585 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10586 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10587 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10588 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10589 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10590 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10591 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10593 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10595 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10596 { } /* end */
10599 static struct hda_verb alc262_tyan_verbs[] = {
10600 /* Headphone automute */
10601 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10602 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10603 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10605 /* P11 AUX_IN, white 4-pin connector */
10606 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10607 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10608 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10609 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10614 /* unsolicited event for HP jack sensing */
10615 static void alc262_tyan_setup(struct hda_codec *codec)
10617 struct alc_spec *spec = codec->spec;
10619 spec->autocfg.hp_pins[0] = 0x1b;
10620 spec->autocfg.speaker_pins[0] = 0x15;
10624 #define alc262_capture_mixer alc882_capture_mixer
10625 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
10628 * generic initialization of ADC, input mixers and output mixers
10630 static struct hda_verb alc262_init_verbs[] = {
10632 * Unmute ADC0-2 and set the default input to mic-in
10634 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10636 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10638 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10639 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10641 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10642 * mixer widget
10643 * Note: PASD motherboards uses the Line In 2 as the input for
10644 * front panel mic (mic 2)
10646 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10651 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10654 * Set up output mixers (0x0c - 0x0e)
10656 /* set vol=0 to output mixers */
10657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10658 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10659 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10660 /* set up input amps for analog loopback */
10661 /* Amp Indices: DAC = 0, mixer = 1 */
10662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10670 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10671 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10672 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10673 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10674 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10676 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10678 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10679 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10682 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10685 /* FIXME: use matrix-type input source selection */
10686 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10687 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10688 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10689 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10690 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10692 /* Input mixer2 */
10693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10694 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10695 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10696 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10697 /* Input mixer3 */
10698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10699 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10700 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10701 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10706 static struct hda_verb alc262_eapd_verbs[] = {
10707 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10708 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10712 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10714 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10715 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10722 static struct hda_verb alc262_sony_unsol_verbs[] = {
10723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10724 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10725 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10727 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10728 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10732 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10733 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10734 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10735 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10736 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10737 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10738 { } /* end */
10741 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10742 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10743 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10745 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10746 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10748 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10753 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10755 struct alc_spec *spec = codec->spec;
10757 spec->autocfg.hp_pins[0] = 0x15;
10758 spec->autocfg.speaker_pins[0] = 0x14;
10759 spec->ext_mic.pin = 0x18;
10760 spec->ext_mic.mux_idx = 0;
10761 spec->int_mic.pin = 0x12;
10762 spec->int_mic.mux_idx = 9;
10763 spec->auto_mic = 1;
10767 * nec model
10768 * 0x15 = headphone
10769 * 0x16 = internal speaker
10770 * 0x18 = external mic
10773 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10774 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10775 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10777 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10778 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10779 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10781 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10783 { } /* end */
10786 static struct hda_verb alc262_nec_verbs[] = {
10787 /* Unmute Speaker */
10788 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10790 /* Headphone */
10791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10792 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10794 /* External mic to headphone */
10795 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10796 /* External mic to speaker */
10797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10802 * fujitsu model
10803 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10804 * 0x1b = port replicator headphone out
10807 #define ALC_HP_EVENT 0x37
10809 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10810 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10812 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10817 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10818 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10819 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10823 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
10824 /* Front Mic pin: input vref at 50% */
10825 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
10826 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10830 static struct hda_input_mux alc262_fujitsu_capture_source = {
10831 .num_items = 3,
10832 .items = {
10833 { "Mic", 0x0 },
10834 { "Int Mic", 0x1 },
10835 { "CD", 0x4 },
10839 static struct hda_input_mux alc262_HP_capture_source = {
10840 .num_items = 5,
10841 .items = {
10842 { "Mic", 0x0 },
10843 { "Front Mic", 0x1 },
10844 { "Line", 0x2 },
10845 { "CD", 0x4 },
10846 { "AUX IN", 0x6 },
10850 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10851 .num_items = 4,
10852 .items = {
10853 { "Mic", 0x0 },
10854 { "Front Mic", 0x2 },
10855 { "Line", 0x1 },
10856 { "CD", 0x4 },
10860 /* mute/unmute internal speaker according to the hp jacks and mute state */
10861 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10863 struct alc_spec *spec = codec->spec;
10864 unsigned int mute;
10866 if (force || !spec->sense_updated) {
10867 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
10868 snd_hda_jack_detect(codec, 0x1b);
10869 spec->sense_updated = 1;
10871 /* unmute internal speaker only if both HPs are unplugged and
10872 * master switch is on
10874 if (spec->jack_present)
10875 mute = HDA_AMP_MUTE;
10876 else
10877 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10878 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10879 HDA_AMP_MUTE, mute);
10882 /* unsolicited event for HP jack sensing */
10883 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10884 unsigned int res)
10886 if ((res >> 26) != ALC_HP_EVENT)
10887 return;
10888 alc262_fujitsu_automute(codec, 1);
10891 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10893 alc262_fujitsu_automute(codec, 1);
10896 /* bind volumes of both NID 0x0c and 0x0d */
10897 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10898 .ops = &snd_hda_bind_vol,
10899 .values = {
10900 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10901 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10906 /* mute/unmute internal speaker according to the hp jack and mute state */
10907 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10909 struct alc_spec *spec = codec->spec;
10910 unsigned int mute;
10912 if (force || !spec->sense_updated) {
10913 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10914 spec->sense_updated = 1;
10916 if (spec->jack_present) {
10917 /* mute internal speaker */
10918 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10919 HDA_AMP_MUTE, HDA_AMP_MUTE);
10920 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10921 HDA_AMP_MUTE, HDA_AMP_MUTE);
10922 } else {
10923 /* unmute internal speaker if necessary */
10924 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10925 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10926 HDA_AMP_MUTE, mute);
10927 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10928 HDA_AMP_MUTE, mute);
10932 /* unsolicited event for HP jack sensing */
10933 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10934 unsigned int res)
10936 if ((res >> 26) != ALC_HP_EVENT)
10937 return;
10938 alc262_lenovo_3000_automute(codec, 1);
10941 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10942 int dir, int idx, long *valp)
10944 int i, change = 0;
10946 for (i = 0; i < 2; i++, valp++)
10947 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10948 HDA_AMP_MUTE,
10949 *valp ? 0 : HDA_AMP_MUTE);
10950 return change;
10953 /* bind hp and internal speaker mute (with plug check) */
10954 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10955 struct snd_ctl_elem_value *ucontrol)
10957 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10958 long *valp = ucontrol->value.integer.value;
10959 int change;
10961 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10962 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10963 if (change)
10964 alc262_fujitsu_automute(codec, 0);
10965 return change;
10968 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10969 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10972 .name = "Master Playback Switch",
10973 .info = snd_hda_mixer_amp_switch_info,
10974 .get = snd_hda_mixer_amp_switch_get,
10975 .put = alc262_fujitsu_master_sw_put,
10976 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10980 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10983 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10984 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10985 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10986 { } /* end */
10989 /* bind hp and internal speaker mute (with plug check) */
10990 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10991 struct snd_ctl_elem_value *ucontrol)
10993 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10994 long *valp = ucontrol->value.integer.value;
10995 int change;
10997 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10998 if (change)
10999 alc262_lenovo_3000_automute(codec, 0);
11000 return change;
11003 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11004 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11007 .name = "Master Playback Switch",
11008 .info = snd_hda_mixer_amp_switch_info,
11009 .get = snd_hda_mixer_amp_switch_get,
11010 .put = alc262_lenovo_3000_master_sw_put,
11011 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11015 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11017 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11018 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11019 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11020 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11021 { } /* end */
11024 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11025 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11026 ALC262_HIPPO_MASTER_SWITCH,
11027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11028 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11029 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11031 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11032 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11033 { } /* end */
11036 /* additional init verbs for Benq laptops */
11037 static struct hda_verb alc262_EAPD_verbs[] = {
11038 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11039 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11043 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11044 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11047 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11048 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11052 /* Samsung Q1 Ultra Vista model setup */
11053 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11054 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11055 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11058 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
11059 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
11060 { } /* end */
11063 static struct hda_verb alc262_ultra_verbs[] = {
11064 /* output mixer */
11065 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11066 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11067 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11068 /* speaker */
11069 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11071 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11072 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11073 /* HP */
11074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11075 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11077 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11078 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11079 /* internal mic */
11080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11081 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11082 /* ADC, choose mic */
11083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11084 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11085 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11086 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11088 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11091 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11092 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11096 /* mute/unmute internal speaker according to the hp jack and mute state */
11097 static void alc262_ultra_automute(struct hda_codec *codec)
11099 struct alc_spec *spec = codec->spec;
11100 unsigned int mute;
11102 mute = 0;
11103 /* auto-mute only when HP is used as HP */
11104 if (!spec->cur_mux[0]) {
11105 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11106 if (spec->jack_present)
11107 mute = HDA_AMP_MUTE;
11109 /* mute/unmute internal speaker */
11110 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11111 HDA_AMP_MUTE, mute);
11112 /* mute/unmute HP */
11113 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11114 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11117 /* unsolicited event for HP jack sensing */
11118 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11119 unsigned int res)
11121 if ((res >> 26) != ALC880_HP_EVENT)
11122 return;
11123 alc262_ultra_automute(codec);
11126 static struct hda_input_mux alc262_ultra_capture_source = {
11127 .num_items = 2,
11128 .items = {
11129 { "Mic", 0x1 },
11130 { "Headphone", 0x7 },
11134 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11135 struct snd_ctl_elem_value *ucontrol)
11137 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11138 struct alc_spec *spec = codec->spec;
11139 int ret;
11141 ret = alc_mux_enum_put(kcontrol, ucontrol);
11142 if (!ret)
11143 return 0;
11144 /* reprogram the HP pin as mic or HP according to the input source */
11145 snd_hda_codec_write_cache(codec, 0x15, 0,
11146 AC_VERB_SET_PIN_WIDGET_CONTROL,
11147 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11148 alc262_ultra_automute(codec); /* mute/unmute HP */
11149 return ret;
11152 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11153 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11154 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11156 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11157 .name = "Capture Source",
11158 .info = alc_mux_enum_info,
11159 .get = alc_mux_enum_get,
11160 .put = alc262_ultra_mux_enum_put,
11162 { } /* end */
11165 /* We use two mixers depending on the output pin; 0x16 is a mono output
11166 * and thus it's bound with a different mixer.
11167 * This function returns which mixer amp should be used.
11169 static int alc262_check_volbit(hda_nid_t nid)
11171 if (!nid)
11172 return 0;
11173 else if (nid == 0x16)
11174 return 2;
11175 else
11176 return 1;
11179 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11180 const char *pfx, int *vbits)
11182 unsigned long val;
11183 int vbit;
11185 vbit = alc262_check_volbit(nid);
11186 if (!vbit)
11187 return 0;
11188 if (*vbits & vbit) /* a volume control for this mixer already there */
11189 return 0;
11190 *vbits |= vbit;
11191 if (vbit == 2)
11192 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11193 else
11194 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11195 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
11198 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11199 const char *pfx)
11201 unsigned long val;
11203 if (!nid)
11204 return 0;
11205 if (nid == 0x16)
11206 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11207 else
11208 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11209 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
11212 /* add playback controls from the parsed DAC table */
11213 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11214 const struct auto_pin_cfg *cfg)
11216 const char *pfx;
11217 int vbits;
11218 int err;
11220 spec->multiout.num_dacs = 1; /* only use one dac */
11221 spec->multiout.dac_nids = spec->private_dac_nids;
11222 spec->multiout.dac_nids[0] = 2;
11224 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11225 pfx = "Master";
11226 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11227 pfx = "Speaker";
11228 else
11229 pfx = "Front";
11230 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11231 if (err < 0)
11232 return err;
11233 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11234 if (err < 0)
11235 return err;
11236 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11237 if (err < 0)
11238 return err;
11240 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11241 alc262_check_volbit(cfg->speaker_pins[0]) |
11242 alc262_check_volbit(cfg->hp_pins[0]);
11243 if (vbits == 1 || vbits == 2)
11244 pfx = "Master"; /* only one mixer is used */
11245 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11246 pfx = "Speaker";
11247 else
11248 pfx = "Front";
11249 vbits = 0;
11250 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11251 if (err < 0)
11252 return err;
11253 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11254 &vbits);
11255 if (err < 0)
11256 return err;
11257 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11258 &vbits);
11259 if (err < 0)
11260 return err;
11261 return 0;
11264 #define alc262_auto_create_input_ctls \
11265 alc882_auto_create_input_ctls
11268 * generic initialization of ADC, input mixers and output mixers
11270 static struct hda_verb alc262_volume_init_verbs[] = {
11272 * Unmute ADC0-2 and set the default input to mic-in
11274 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11276 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11278 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11281 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11282 * mixer widget
11283 * Note: PASD motherboards uses the Line In 2 as the input for
11284 * front panel mic (mic 2)
11286 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11294 * Set up output mixers (0x0c - 0x0f)
11296 /* set vol=0 to output mixers */
11297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11298 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11299 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11301 /* set up input amps for analog loopback */
11302 /* Amp Indices: DAC = 0, mixer = 1 */
11303 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11305 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11306 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11310 /* FIXME: use matrix-type input source selection */
11311 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11312 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11313 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11317 /* Input mixer2 */
11318 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11322 /* Input mixer3 */
11323 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11331 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11333 * Unmute ADC0-2 and set the default input to mic-in
11335 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11336 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11337 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11338 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11339 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11340 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11342 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11343 * mixer widget
11344 * Note: PASD motherboards uses the Line In 2 as the input for
11345 * front panel mic (mic 2)
11347 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11348 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11352 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11353 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11354 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11357 * Set up output mixers (0x0c - 0x0e)
11359 /* set vol=0 to output mixers */
11360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11362 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11364 /* set up input amps for analog loopback */
11365 /* Amp Indices: DAC = 0, mixer = 1 */
11366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11373 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11374 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11375 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11377 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11378 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11380 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11384 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11385 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11386 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11387 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11390 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11391 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11392 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11393 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11394 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11397 /* FIXME: use matrix-type input source selection */
11398 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11399 /* Input mixer1: only unmute Mic */
11400 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11409 /* Input mixer2 */
11410 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11411 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11412 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11419 /* Input mixer3 */
11420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11427 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11428 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11430 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11435 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11437 * Unmute ADC0-2 and set the default input to mic-in
11439 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11440 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11441 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11443 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11444 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11446 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11447 * mixer widget
11448 * Note: PASD motherboards uses the Line In 2 as the input for front
11449 * panel mic (mic 2)
11451 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11461 * Set up output mixers (0x0c - 0x0e)
11463 /* set vol=0 to output mixers */
11464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11468 /* set up input amps for analog loopback */
11469 /* Amp Indices: DAC = 0, mixer = 1 */
11470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11478 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11479 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11480 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11481 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11483 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11484 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11486 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11487 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11489 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11490 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11492 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11493 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11494 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11495 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11496 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11497 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11499 /* FIXME: use matrix-type input source selection */
11500 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11501 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11502 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11503 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11504 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11505 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11507 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11509 /* Input mixer2 */
11510 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11515 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11517 /* Input mixer3 */
11518 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11522 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11523 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11526 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11531 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11535 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11538 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11539 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11543 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11544 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11549 #ifdef CONFIG_SND_HDA_POWER_SAVE
11550 #define alc262_loopbacks alc880_loopbacks
11551 #endif
11553 /* pcm configuration: identical with ALC880 */
11554 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
11555 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
11556 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
11557 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
11560 * BIOS auto configuration
11562 static int alc262_parse_auto_config(struct hda_codec *codec)
11564 struct alc_spec *spec = codec->spec;
11565 int err;
11566 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11568 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11569 alc262_ignore);
11570 if (err < 0)
11571 return err;
11572 if (!spec->autocfg.line_outs) {
11573 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11574 spec->multiout.max_channels = 2;
11575 spec->no_analog = 1;
11576 goto dig_only;
11578 return 0; /* can't find valid BIOS pin config */
11580 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11581 if (err < 0)
11582 return err;
11583 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11584 if (err < 0)
11585 return err;
11587 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11589 dig_only:
11590 if (spec->autocfg.dig_outs) {
11591 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11592 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11594 if (spec->autocfg.dig_in_pin)
11595 spec->dig_in_nid = ALC262_DIGIN_NID;
11597 if (spec->kctls.list)
11598 add_mixer(spec, spec->kctls.list);
11600 add_verb(spec, alc262_volume_init_verbs);
11601 spec->num_mux_defs = 1;
11602 spec->input_mux = &spec->private_imux[0];
11604 err = alc_auto_add_mic_boost(codec);
11605 if (err < 0)
11606 return err;
11608 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11610 return 1;
11613 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11614 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11615 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11616 #define alc262_auto_init_input_src alc882_auto_init_input_src
11619 /* init callback for auto-configuration model -- overriding the default init */
11620 static void alc262_auto_init(struct hda_codec *codec)
11622 struct alc_spec *spec = codec->spec;
11623 alc262_auto_init_multi_out(codec);
11624 alc262_auto_init_hp_out(codec);
11625 alc262_auto_init_analog_input(codec);
11626 alc262_auto_init_input_src(codec);
11627 if (spec->unsol_event)
11628 alc_inithook(codec);
11632 * configuration and preset
11634 static const char *alc262_models[ALC262_MODEL_LAST] = {
11635 [ALC262_BASIC] = "basic",
11636 [ALC262_HIPPO] = "hippo",
11637 [ALC262_HIPPO_1] = "hippo_1",
11638 [ALC262_FUJITSU] = "fujitsu",
11639 [ALC262_HP_BPC] = "hp-bpc",
11640 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11641 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11642 [ALC262_HP_RP5700] = "hp-rp5700",
11643 [ALC262_BENQ_ED8] = "benq",
11644 [ALC262_BENQ_T31] = "benq-t31",
11645 [ALC262_SONY_ASSAMD] = "sony-assamd",
11646 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11647 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11648 [ALC262_ULTRA] = "ultra",
11649 [ALC262_LENOVO_3000] = "lenovo-3000",
11650 [ALC262_NEC] = "nec",
11651 [ALC262_TYAN] = "tyan",
11652 [ALC262_AUTO] = "auto",
11655 static struct snd_pci_quirk alc262_cfg_tbl[] = {
11656 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11657 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11658 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11659 ALC262_HP_BPC),
11660 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11661 ALC262_HP_BPC),
11662 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11663 ALC262_HP_BPC),
11664 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11665 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11666 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11667 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11668 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11669 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11670 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11671 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11672 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11673 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11674 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11675 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11676 ALC262_HP_TC_T5735),
11677 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11678 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11679 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11680 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11681 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11682 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11683 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11684 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
11685 #if 0 /* disable the quirk since model=auto works better in recent versions */
11686 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11687 ALC262_SONY_ASSAMD),
11688 #endif
11689 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11690 ALC262_TOSHIBA_RX1),
11691 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11692 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11693 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11694 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11695 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11696 ALC262_ULTRA),
11697 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11698 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11699 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11700 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11701 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11705 static struct alc_config_preset alc262_presets[] = {
11706 [ALC262_BASIC] = {
11707 .mixers = { alc262_base_mixer },
11708 .init_verbs = { alc262_init_verbs },
11709 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11710 .dac_nids = alc262_dac_nids,
11711 .hp_nid = 0x03,
11712 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11713 .channel_mode = alc262_modes,
11714 .input_mux = &alc262_capture_source,
11716 [ALC262_HIPPO] = {
11717 .mixers = { alc262_hippo_mixer },
11718 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11719 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11720 .dac_nids = alc262_dac_nids,
11721 .hp_nid = 0x03,
11722 .dig_out_nid = ALC262_DIGOUT_NID,
11723 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11724 .channel_mode = alc262_modes,
11725 .input_mux = &alc262_capture_source,
11726 .unsol_event = alc262_hippo_unsol_event,
11727 .setup = alc262_hippo_setup,
11728 .init_hook = alc262_hippo_automute,
11730 [ALC262_HIPPO_1] = {
11731 .mixers = { alc262_hippo1_mixer },
11732 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11733 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11734 .dac_nids = alc262_dac_nids,
11735 .hp_nid = 0x02,
11736 .dig_out_nid = ALC262_DIGOUT_NID,
11737 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11738 .channel_mode = alc262_modes,
11739 .input_mux = &alc262_capture_source,
11740 .unsol_event = alc262_hippo_unsol_event,
11741 .setup = alc262_hippo1_setup,
11742 .init_hook = alc262_hippo_automute,
11744 [ALC262_FUJITSU] = {
11745 .mixers = { alc262_fujitsu_mixer },
11746 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11747 alc262_fujitsu_unsol_verbs },
11748 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11749 .dac_nids = alc262_dac_nids,
11750 .hp_nid = 0x03,
11751 .dig_out_nid = ALC262_DIGOUT_NID,
11752 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11753 .channel_mode = alc262_modes,
11754 .input_mux = &alc262_fujitsu_capture_source,
11755 .unsol_event = alc262_fujitsu_unsol_event,
11756 .init_hook = alc262_fujitsu_init_hook,
11758 [ALC262_HP_BPC] = {
11759 .mixers = { alc262_HP_BPC_mixer },
11760 .init_verbs = { alc262_HP_BPC_init_verbs },
11761 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11762 .dac_nids = alc262_dac_nids,
11763 .hp_nid = 0x03,
11764 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11765 .channel_mode = alc262_modes,
11766 .input_mux = &alc262_HP_capture_source,
11767 .unsol_event = alc262_hp_bpc_unsol_event,
11768 .init_hook = alc262_hp_bpc_automute,
11770 [ALC262_HP_BPC_D7000_WF] = {
11771 .mixers = { alc262_HP_BPC_WildWest_mixer },
11772 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11773 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11774 .dac_nids = alc262_dac_nids,
11775 .hp_nid = 0x03,
11776 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11777 .channel_mode = alc262_modes,
11778 .input_mux = &alc262_HP_D7000_capture_source,
11779 .unsol_event = alc262_hp_wildwest_unsol_event,
11780 .init_hook = alc262_hp_wildwest_automute,
11782 [ALC262_HP_BPC_D7000_WL] = {
11783 .mixers = { alc262_HP_BPC_WildWest_mixer,
11784 alc262_HP_BPC_WildWest_option_mixer },
11785 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11786 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11787 .dac_nids = alc262_dac_nids,
11788 .hp_nid = 0x03,
11789 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11790 .channel_mode = alc262_modes,
11791 .input_mux = &alc262_HP_D7000_capture_source,
11792 .unsol_event = alc262_hp_wildwest_unsol_event,
11793 .init_hook = alc262_hp_wildwest_automute,
11795 [ALC262_HP_TC_T5735] = {
11796 .mixers = { alc262_hp_t5735_mixer },
11797 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11798 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11799 .dac_nids = alc262_dac_nids,
11800 .hp_nid = 0x03,
11801 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11802 .channel_mode = alc262_modes,
11803 .input_mux = &alc262_capture_source,
11804 .unsol_event = alc_sku_unsol_event,
11805 .setup = alc262_hp_t5735_setup,
11806 .init_hook = alc_inithook,
11808 [ALC262_HP_RP5700] = {
11809 .mixers = { alc262_hp_rp5700_mixer },
11810 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11811 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11812 .dac_nids = alc262_dac_nids,
11813 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11814 .channel_mode = alc262_modes,
11815 .input_mux = &alc262_hp_rp5700_capture_source,
11817 [ALC262_BENQ_ED8] = {
11818 .mixers = { alc262_base_mixer },
11819 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11820 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11821 .dac_nids = alc262_dac_nids,
11822 .hp_nid = 0x03,
11823 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11824 .channel_mode = alc262_modes,
11825 .input_mux = &alc262_capture_source,
11827 [ALC262_SONY_ASSAMD] = {
11828 .mixers = { alc262_sony_mixer },
11829 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11830 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11831 .dac_nids = alc262_dac_nids,
11832 .hp_nid = 0x02,
11833 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11834 .channel_mode = alc262_modes,
11835 .input_mux = &alc262_capture_source,
11836 .unsol_event = alc262_hippo_unsol_event,
11837 .setup = alc262_hippo_setup,
11838 .init_hook = alc262_hippo_automute,
11840 [ALC262_BENQ_T31] = {
11841 .mixers = { alc262_benq_t31_mixer },
11842 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11843 alc_hp15_unsol_verbs },
11844 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11845 .dac_nids = alc262_dac_nids,
11846 .hp_nid = 0x03,
11847 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11848 .channel_mode = alc262_modes,
11849 .input_mux = &alc262_capture_source,
11850 .unsol_event = alc262_hippo_unsol_event,
11851 .setup = alc262_hippo_setup,
11852 .init_hook = alc262_hippo_automute,
11854 [ALC262_ULTRA] = {
11855 .mixers = { alc262_ultra_mixer },
11856 .cap_mixer = alc262_ultra_capture_mixer,
11857 .init_verbs = { alc262_ultra_verbs },
11858 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11859 .dac_nids = alc262_dac_nids,
11860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11861 .channel_mode = alc262_modes,
11862 .input_mux = &alc262_ultra_capture_source,
11863 .adc_nids = alc262_adc_nids, /* ADC0 */
11864 .capsrc_nids = alc262_capsrc_nids,
11865 .num_adc_nids = 1, /* single ADC */
11866 .unsol_event = alc262_ultra_unsol_event,
11867 .init_hook = alc262_ultra_automute,
11869 [ALC262_LENOVO_3000] = {
11870 .mixers = { alc262_lenovo_3000_mixer },
11871 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11872 alc262_lenovo_3000_unsol_verbs,
11873 alc262_lenovo_3000_init_verbs },
11874 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11875 .dac_nids = alc262_dac_nids,
11876 .hp_nid = 0x03,
11877 .dig_out_nid = ALC262_DIGOUT_NID,
11878 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11879 .channel_mode = alc262_modes,
11880 .input_mux = &alc262_fujitsu_capture_source,
11881 .unsol_event = alc262_lenovo_3000_unsol_event,
11883 [ALC262_NEC] = {
11884 .mixers = { alc262_nec_mixer },
11885 .init_verbs = { alc262_nec_verbs },
11886 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11887 .dac_nids = alc262_dac_nids,
11888 .hp_nid = 0x03,
11889 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11890 .channel_mode = alc262_modes,
11891 .input_mux = &alc262_capture_source,
11893 [ALC262_TOSHIBA_S06] = {
11894 .mixers = { alc262_toshiba_s06_mixer },
11895 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11896 alc262_eapd_verbs },
11897 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11898 .capsrc_nids = alc262_dmic_capsrc_nids,
11899 .dac_nids = alc262_dac_nids,
11900 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11901 .num_adc_nids = 1, /* single ADC */
11902 .dig_out_nid = ALC262_DIGOUT_NID,
11903 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11904 .channel_mode = alc262_modes,
11905 .unsol_event = alc_sku_unsol_event,
11906 .setup = alc262_toshiba_s06_setup,
11907 .init_hook = alc_inithook,
11909 [ALC262_TOSHIBA_RX1] = {
11910 .mixers = { alc262_toshiba_rx1_mixer },
11911 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11912 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11913 .dac_nids = alc262_dac_nids,
11914 .hp_nid = 0x03,
11915 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11916 .channel_mode = alc262_modes,
11917 .input_mux = &alc262_capture_source,
11918 .unsol_event = alc262_hippo_unsol_event,
11919 .setup = alc262_hippo_setup,
11920 .init_hook = alc262_hippo_automute,
11922 [ALC262_TYAN] = {
11923 .mixers = { alc262_tyan_mixer },
11924 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11925 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11926 .dac_nids = alc262_dac_nids,
11927 .hp_nid = 0x02,
11928 .dig_out_nid = ALC262_DIGOUT_NID,
11929 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11930 .channel_mode = alc262_modes,
11931 .input_mux = &alc262_capture_source,
11932 .unsol_event = alc_automute_amp_unsol_event,
11933 .setup = alc262_tyan_setup,
11934 .init_hook = alc_automute_amp,
11938 static int patch_alc262(struct hda_codec *codec)
11940 struct alc_spec *spec;
11941 int board_config;
11942 int err;
11944 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11945 if (spec == NULL)
11946 return -ENOMEM;
11948 codec->spec = spec;
11949 #if 0
11950 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11951 * under-run
11954 int tmp;
11955 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11956 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11957 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11958 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11960 #endif
11962 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11964 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11965 alc262_models,
11966 alc262_cfg_tbl);
11968 if (board_config < 0) {
11969 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11970 codec->chip_name);
11971 board_config = ALC262_AUTO;
11974 if (board_config == ALC262_AUTO) {
11975 /* automatic parse from the BIOS config */
11976 err = alc262_parse_auto_config(codec);
11977 if (err < 0) {
11978 alc_free(codec);
11979 return err;
11980 } else if (!err) {
11981 printk(KERN_INFO
11982 "hda_codec: Cannot set up configuration "
11983 "from BIOS. Using base mode...\n");
11984 board_config = ALC262_BASIC;
11988 if (!spec->no_analog) {
11989 err = snd_hda_attach_beep_device(codec, 0x1);
11990 if (err < 0) {
11991 alc_free(codec);
11992 return err;
11996 if (board_config != ALC262_AUTO)
11997 setup_preset(codec, &alc262_presets[board_config]);
11999 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12000 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12002 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12003 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12005 if (!spec->adc_nids && spec->input_mux) {
12006 int i;
12007 /* check whether the digital-mic has to be supported */
12008 for (i = 0; i < spec->input_mux->num_items; i++) {
12009 if (spec->input_mux->items[i].index >= 9)
12010 break;
12012 if (i < spec->input_mux->num_items) {
12013 /* use only ADC0 */
12014 spec->adc_nids = alc262_dmic_adc_nids;
12015 spec->num_adc_nids = 1;
12016 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12017 } else {
12018 /* all analog inputs */
12019 /* check whether NID 0x07 is valid */
12020 unsigned int wcap = get_wcaps(codec, 0x07);
12022 /* get type */
12023 wcap = get_wcaps_type(wcap);
12024 if (wcap != AC_WID_AUD_IN) {
12025 spec->adc_nids = alc262_adc_nids_alt;
12026 spec->num_adc_nids =
12027 ARRAY_SIZE(alc262_adc_nids_alt);
12028 spec->capsrc_nids = alc262_capsrc_nids_alt;
12029 } else {
12030 spec->adc_nids = alc262_adc_nids;
12031 spec->num_adc_nids =
12032 ARRAY_SIZE(alc262_adc_nids);
12033 spec->capsrc_nids = alc262_capsrc_nids;
12037 if (!spec->cap_mixer && !spec->no_analog)
12038 set_capture_mixer(codec);
12039 if (!spec->no_analog)
12040 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12042 spec->vmaster_nid = 0x0c;
12044 codec->patch_ops = alc_patch_ops;
12045 if (board_config == ALC262_AUTO)
12046 spec->init_hook = alc262_auto_init;
12047 #ifdef CONFIG_SND_HDA_POWER_SAVE
12048 if (!spec->loopback.amplist)
12049 spec->loopback.amplist = alc262_loopbacks;
12050 #endif
12051 codec->proc_widget_hook = print_realtek_coef;
12053 return 0;
12057 * ALC268 channel source setting (2 channel)
12059 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12060 #define alc268_modes alc260_modes
12062 static hda_nid_t alc268_dac_nids[2] = {
12063 /* front, hp */
12064 0x02, 0x03
12067 static hda_nid_t alc268_adc_nids[2] = {
12068 /* ADC0-1 */
12069 0x08, 0x07
12072 static hda_nid_t alc268_adc_nids_alt[1] = {
12073 /* ADC0 */
12074 0x08
12077 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12079 static struct snd_kcontrol_new alc268_base_mixer[] = {
12080 /* output mixer control */
12081 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12082 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12083 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12084 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12085 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12086 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12087 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12091 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12092 /* output mixer control */
12093 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12094 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12095 ALC262_HIPPO_MASTER_SWITCH,
12096 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12097 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12098 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12102 /* bind Beep switches of both NID 0x0f and 0x10 */
12103 static struct hda_bind_ctls alc268_bind_beep_sw = {
12104 .ops = &snd_hda_bind_sw,
12105 .values = {
12106 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12107 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12112 static struct snd_kcontrol_new alc268_beep_mixer[] = {
12113 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12114 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12118 static struct hda_verb alc268_eapd_verbs[] = {
12119 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12120 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12124 /* Toshiba specific */
12125 static struct hda_verb alc268_toshiba_verbs[] = {
12126 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12127 { } /* end */
12130 /* Acer specific */
12131 /* bind volumes of both NID 0x02 and 0x03 */
12132 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12133 .ops = &snd_hda_bind_vol,
12134 .values = {
12135 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12136 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12141 /* mute/unmute internal speaker according to the hp jack and mute state */
12142 static void alc268_acer_automute(struct hda_codec *codec, int force)
12144 struct alc_spec *spec = codec->spec;
12145 unsigned int mute;
12147 if (force || !spec->sense_updated) {
12148 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
12149 spec->sense_updated = 1;
12151 if (spec->jack_present)
12152 mute = HDA_AMP_MUTE; /* mute internal speaker */
12153 else /* unmute internal speaker if necessary */
12154 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12155 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12156 HDA_AMP_MUTE, mute);
12160 /* bind hp and internal speaker mute (with plug check) */
12161 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12162 struct snd_ctl_elem_value *ucontrol)
12164 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12165 long *valp = ucontrol->value.integer.value;
12166 int change;
12168 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
12169 if (change)
12170 alc268_acer_automute(codec, 0);
12171 return change;
12174 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12175 /* output mixer control */
12176 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12179 .name = "Master Playback Switch",
12180 .info = snd_hda_mixer_amp_switch_info,
12181 .get = snd_hda_mixer_amp_switch_get,
12182 .put = alc268_acer_master_sw_put,
12183 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12185 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12189 static struct snd_kcontrol_new alc268_acer_mixer[] = {
12190 /* output mixer control */
12191 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12193 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12194 .name = "Master Playback Switch",
12195 .info = snd_hda_mixer_amp_switch_info,
12196 .get = snd_hda_mixer_amp_switch_get,
12197 .put = alc268_acer_master_sw_put,
12198 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12200 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12201 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12202 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12206 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12207 /* output mixer control */
12208 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12210 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12211 .name = "Master Playback Switch",
12212 .info = snd_hda_mixer_amp_switch_info,
12213 .get = snd_hda_mixer_amp_switch_get,
12214 .put = alc268_acer_master_sw_put,
12215 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12217 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12218 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12222 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12223 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12225 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12226 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12227 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12232 static struct hda_verb alc268_acer_verbs[] = {
12233 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12234 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12235 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12237 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12238 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12239 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12243 /* unsolicited event for HP jack sensing */
12244 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12245 #define alc268_toshiba_setup alc262_hippo_setup
12246 #define alc268_toshiba_automute alc262_hippo_automute
12248 static void alc268_acer_unsol_event(struct hda_codec *codec,
12249 unsigned int res)
12251 if ((res >> 26) != ALC880_HP_EVENT)
12252 return;
12253 alc268_acer_automute(codec, 1);
12256 static void alc268_acer_init_hook(struct hda_codec *codec)
12258 alc268_acer_automute(codec, 1);
12261 /* toggle speaker-output according to the hp-jack state */
12262 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12264 unsigned int present;
12265 unsigned char bits;
12267 present = snd_hda_jack_detect(codec, 0x15);
12268 bits = present ? AMP_IN_MUTE(0) : 0;
12269 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12270 AMP_IN_MUTE(0), bits);
12271 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12272 AMP_IN_MUTE(0), bits);
12275 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12276 unsigned int res)
12278 switch (res >> 26) {
12279 case ALC880_HP_EVENT:
12280 alc268_aspire_one_speaker_automute(codec);
12281 break;
12282 case ALC880_MIC_EVENT:
12283 alc_mic_automute(codec);
12284 break;
12288 static void alc268_acer_lc_setup(struct hda_codec *codec)
12290 struct alc_spec *spec = codec->spec;
12291 spec->ext_mic.pin = 0x18;
12292 spec->ext_mic.mux_idx = 0;
12293 spec->int_mic.pin = 0x12;
12294 spec->int_mic.mux_idx = 6;
12295 spec->auto_mic = 1;
12298 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12300 alc268_aspire_one_speaker_automute(codec);
12301 alc_mic_automute(codec);
12304 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12305 /* output mixer control */
12306 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12307 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12308 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12310 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12311 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12315 static struct hda_verb alc268_dell_verbs[] = {
12316 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12319 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12323 /* mute/unmute internal speaker according to the hp jack and mute state */
12324 static void alc268_dell_setup(struct hda_codec *codec)
12326 struct alc_spec *spec = codec->spec;
12328 spec->autocfg.hp_pins[0] = 0x15;
12329 spec->autocfg.speaker_pins[0] = 0x14;
12330 spec->ext_mic.pin = 0x18;
12331 spec->ext_mic.mux_idx = 0;
12332 spec->int_mic.pin = 0x19;
12333 spec->int_mic.mux_idx = 1;
12334 spec->auto_mic = 1;
12337 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12339 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12342 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12343 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12344 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12345 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12349 static struct hda_verb alc267_quanta_il1_verbs[] = {
12350 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12351 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12355 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12357 struct alc_spec *spec = codec->spec;
12358 spec->autocfg.hp_pins[0] = 0x15;
12359 spec->autocfg.speaker_pins[0] = 0x14;
12360 spec->ext_mic.pin = 0x18;
12361 spec->ext_mic.mux_idx = 0;
12362 spec->int_mic.pin = 0x19;
12363 spec->int_mic.mux_idx = 1;
12364 spec->auto_mic = 1;
12368 * generic initialization of ADC, input mixers and output mixers
12370 static struct hda_verb alc268_base_init_verbs[] = {
12371 /* Unmute DAC0-1 and set vol = 0 */
12372 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12373 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12376 * Set up output mixers (0x0c - 0x0e)
12378 /* set vol=0 to output mixers */
12379 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12380 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12387 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12388 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12389 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12390 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12391 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12392 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12394 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12396 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12397 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12398 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12400 /* set PCBEEP vol = 0, mute connections */
12401 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12402 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12403 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12405 /* Unmute Selector 23h,24h and set the default input to mic-in */
12407 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12408 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12409 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12416 * generic initialization of ADC, input mixers and output mixers
12418 static struct hda_verb alc268_volume_init_verbs[] = {
12419 /* set output DAC */
12420 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12421 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12423 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12424 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12425 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12426 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12427 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12429 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12430 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12431 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12433 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12434 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12436 /* set PCBEEP vol = 0, mute connections */
12437 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12439 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12444 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12445 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12446 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12447 { } /* end */
12450 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12451 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12452 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12453 _DEFINE_CAPSRC(1),
12454 { } /* end */
12457 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12458 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12459 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12460 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12461 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12462 _DEFINE_CAPSRC(2),
12463 { } /* end */
12466 static struct hda_input_mux alc268_capture_source = {
12467 .num_items = 4,
12468 .items = {
12469 { "Mic", 0x0 },
12470 { "Front Mic", 0x1 },
12471 { "Line", 0x2 },
12472 { "CD", 0x3 },
12476 static struct hda_input_mux alc268_acer_capture_source = {
12477 .num_items = 3,
12478 .items = {
12479 { "Mic", 0x0 },
12480 { "Internal Mic", 0x1 },
12481 { "Line", 0x2 },
12485 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12486 .num_items = 3,
12487 .items = {
12488 { "Mic", 0x0 },
12489 { "Internal Mic", 0x6 },
12490 { "Line", 0x2 },
12494 #ifdef CONFIG_SND_DEBUG
12495 static struct snd_kcontrol_new alc268_test_mixer[] = {
12496 /* Volume widgets */
12497 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12498 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12499 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12500 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12501 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12502 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12503 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12504 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12505 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12506 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12507 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12508 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12509 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12510 /* The below appears problematic on some hardwares */
12511 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12512 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12513 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12514 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12515 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12517 /* Modes for retasking pin widgets */
12518 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12519 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12520 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12521 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12523 /* Controls for GPIO pins, assuming they are configured as outputs */
12524 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12525 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12526 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12527 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12529 /* Switches to allow the digital SPDIF output pin to be enabled.
12530 * The ALC268 does not have an SPDIF input.
12532 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12534 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12535 * this output to turn on an external amplifier.
12537 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12538 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12540 { } /* end */
12542 #endif
12544 /* create input playback/capture controls for the given pin */
12545 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12546 const char *ctlname, int idx)
12548 hda_nid_t dac;
12549 int err;
12551 switch (nid) {
12552 case 0x14:
12553 case 0x16:
12554 dac = 0x02;
12555 break;
12556 case 0x15:
12557 case 0x21:
12558 dac = 0x03;
12559 break;
12560 default:
12561 return 0;
12563 if (spec->multiout.dac_nids[0] != dac &&
12564 spec->multiout.dac_nids[1] != dac) {
12565 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
12566 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12567 HDA_OUTPUT));
12568 if (err < 0)
12569 return err;
12570 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12573 if (nid != 0x16)
12574 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12575 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12576 else /* mono */
12577 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12578 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12579 if (err < 0)
12580 return err;
12581 return 0;
12584 /* add playback controls from the parsed DAC table */
12585 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12586 const struct auto_pin_cfg *cfg)
12588 hda_nid_t nid;
12589 int err;
12591 spec->multiout.dac_nids = spec->private_dac_nids;
12593 nid = cfg->line_out_pins[0];
12594 if (nid) {
12595 const char *name;
12596 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12597 name = "Speaker";
12598 else
12599 name = "Front";
12600 err = alc268_new_analog_output(spec, nid, name, 0);
12601 if (err < 0)
12602 return err;
12605 nid = cfg->speaker_pins[0];
12606 if (nid == 0x1d) {
12607 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
12608 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12609 if (err < 0)
12610 return err;
12611 } else {
12612 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12613 if (err < 0)
12614 return err;
12616 nid = cfg->hp_pins[0];
12617 if (nid) {
12618 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12619 if (err < 0)
12620 return err;
12623 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12624 if (nid == 0x16) {
12625 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
12626 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12627 if (err < 0)
12628 return err;
12630 return 0;
12633 /* create playback/capture controls for input pins */
12634 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12635 const struct auto_pin_cfg *cfg)
12637 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12640 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12641 hda_nid_t nid, int pin_type)
12643 int idx;
12645 alc_set_pin_output(codec, nid, pin_type);
12646 if (nid == 0x14 || nid == 0x16)
12647 idx = 0;
12648 else
12649 idx = 1;
12650 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12653 static void alc268_auto_init_multi_out(struct hda_codec *codec)
12655 struct alc_spec *spec = codec->spec;
12656 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12657 if (nid) {
12658 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12659 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12663 static void alc268_auto_init_hp_out(struct hda_codec *codec)
12665 struct alc_spec *spec = codec->spec;
12666 hda_nid_t pin;
12668 pin = spec->autocfg.hp_pins[0];
12669 if (pin)
12670 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12671 pin = spec->autocfg.speaker_pins[0];
12672 if (pin)
12673 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12676 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12678 struct alc_spec *spec = codec->spec;
12679 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12680 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12681 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12682 unsigned int dac_vol1, dac_vol2;
12684 if (line_nid == 0x1d || speaker_nid == 0x1d) {
12685 snd_hda_codec_write(codec, speaker_nid, 0,
12686 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12687 /* mute mixer inputs from 0x1d */
12688 snd_hda_codec_write(codec, 0x0f, 0,
12689 AC_VERB_SET_AMP_GAIN_MUTE,
12690 AMP_IN_UNMUTE(1));
12691 snd_hda_codec_write(codec, 0x10, 0,
12692 AC_VERB_SET_AMP_GAIN_MUTE,
12693 AMP_IN_UNMUTE(1));
12694 } else {
12695 /* unmute mixer inputs from 0x1d */
12696 snd_hda_codec_write(codec, 0x0f, 0,
12697 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12698 snd_hda_codec_write(codec, 0x10, 0,
12699 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12702 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12703 if (line_nid == 0x14)
12704 dac_vol2 = AMP_OUT_ZERO;
12705 else if (line_nid == 0x15)
12706 dac_vol1 = AMP_OUT_ZERO;
12707 if (hp_nid == 0x14)
12708 dac_vol2 = AMP_OUT_ZERO;
12709 else if (hp_nid == 0x15)
12710 dac_vol1 = AMP_OUT_ZERO;
12711 if (line_nid != 0x16 || hp_nid != 0x16 ||
12712 spec->autocfg.line_out_pins[1] != 0x16 ||
12713 spec->autocfg.line_out_pins[2] != 0x16)
12714 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12716 snd_hda_codec_write(codec, 0x02, 0,
12717 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12718 snd_hda_codec_write(codec, 0x03, 0,
12719 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12722 /* pcm configuration: identical with ALC880 */
12723 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12724 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12725 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12726 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12729 * BIOS auto configuration
12731 static int alc268_parse_auto_config(struct hda_codec *codec)
12733 struct alc_spec *spec = codec->spec;
12734 int err;
12735 static hda_nid_t alc268_ignore[] = { 0 };
12737 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12738 alc268_ignore);
12739 if (err < 0)
12740 return err;
12741 if (!spec->autocfg.line_outs) {
12742 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12743 spec->multiout.max_channels = 2;
12744 spec->no_analog = 1;
12745 goto dig_only;
12747 return 0; /* can't find valid BIOS pin config */
12749 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12750 if (err < 0)
12751 return err;
12752 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12753 if (err < 0)
12754 return err;
12756 spec->multiout.max_channels = 2;
12758 dig_only:
12759 /* digital only support output */
12760 if (spec->autocfg.dig_outs) {
12761 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12762 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12764 if (spec->kctls.list)
12765 add_mixer(spec, spec->kctls.list);
12767 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12768 add_mixer(spec, alc268_beep_mixer);
12770 add_verb(spec, alc268_volume_init_verbs);
12771 spec->num_mux_defs = 2;
12772 spec->input_mux = &spec->private_imux[0];
12774 err = alc_auto_add_mic_boost(codec);
12775 if (err < 0)
12776 return err;
12778 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12780 return 1;
12783 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12785 /* init callback for auto-configuration model -- overriding the default init */
12786 static void alc268_auto_init(struct hda_codec *codec)
12788 struct alc_spec *spec = codec->spec;
12789 alc268_auto_init_multi_out(codec);
12790 alc268_auto_init_hp_out(codec);
12791 alc268_auto_init_mono_speaker_out(codec);
12792 alc268_auto_init_analog_input(codec);
12793 if (spec->unsol_event)
12794 alc_inithook(codec);
12798 * configuration and preset
12800 static const char *alc268_models[ALC268_MODEL_LAST] = {
12801 [ALC267_QUANTA_IL1] = "quanta-il1",
12802 [ALC268_3ST] = "3stack",
12803 [ALC268_TOSHIBA] = "toshiba",
12804 [ALC268_ACER] = "acer",
12805 [ALC268_ACER_DMIC] = "acer-dmic",
12806 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12807 [ALC268_DELL] = "dell",
12808 [ALC268_ZEPTO] = "zepto",
12809 #ifdef CONFIG_SND_DEBUG
12810 [ALC268_TEST] = "test",
12811 #endif
12812 [ALC268_AUTO] = "auto",
12815 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12816 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12817 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12818 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12819 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12820 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12821 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12822 ALC268_ACER_ASPIRE_ONE),
12823 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12824 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
12825 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
12826 /* almost compatible with toshiba but with optional digital outs;
12827 * auto-probing seems working fine
12829 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12830 ALC268_AUTO),
12831 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12832 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12833 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12834 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12835 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12836 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12840 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
12841 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12842 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12843 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12844 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12845 ALC268_TOSHIBA),
12849 static struct alc_config_preset alc268_presets[] = {
12850 [ALC267_QUANTA_IL1] = {
12851 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12852 alc268_capture_nosrc_mixer },
12853 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12854 alc267_quanta_il1_verbs },
12855 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12856 .dac_nids = alc268_dac_nids,
12857 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12858 .adc_nids = alc268_adc_nids_alt,
12859 .hp_nid = 0x03,
12860 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12861 .channel_mode = alc268_modes,
12862 .unsol_event = alc_sku_unsol_event,
12863 .setup = alc267_quanta_il1_setup,
12864 .init_hook = alc_inithook,
12866 [ALC268_3ST] = {
12867 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12868 alc268_beep_mixer },
12869 .init_verbs = { alc268_base_init_verbs },
12870 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12871 .dac_nids = alc268_dac_nids,
12872 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12873 .adc_nids = alc268_adc_nids_alt,
12874 .capsrc_nids = alc268_capsrc_nids,
12875 .hp_nid = 0x03,
12876 .dig_out_nid = ALC268_DIGOUT_NID,
12877 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12878 .channel_mode = alc268_modes,
12879 .input_mux = &alc268_capture_source,
12881 [ALC268_TOSHIBA] = {
12882 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12883 alc268_beep_mixer },
12884 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12885 alc268_toshiba_verbs },
12886 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12887 .dac_nids = alc268_dac_nids,
12888 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12889 .adc_nids = alc268_adc_nids_alt,
12890 .capsrc_nids = alc268_capsrc_nids,
12891 .hp_nid = 0x03,
12892 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12893 .channel_mode = alc268_modes,
12894 .input_mux = &alc268_capture_source,
12895 .unsol_event = alc268_toshiba_unsol_event,
12896 .setup = alc268_toshiba_setup,
12897 .init_hook = alc268_toshiba_automute,
12899 [ALC268_ACER] = {
12900 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12901 alc268_beep_mixer },
12902 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12903 alc268_acer_verbs },
12904 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12905 .dac_nids = alc268_dac_nids,
12906 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12907 .adc_nids = alc268_adc_nids_alt,
12908 .capsrc_nids = alc268_capsrc_nids,
12909 .hp_nid = 0x02,
12910 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12911 .channel_mode = alc268_modes,
12912 .input_mux = &alc268_acer_capture_source,
12913 .unsol_event = alc268_acer_unsol_event,
12914 .init_hook = alc268_acer_init_hook,
12916 [ALC268_ACER_DMIC] = {
12917 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12918 alc268_beep_mixer },
12919 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12920 alc268_acer_verbs },
12921 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12922 .dac_nids = alc268_dac_nids,
12923 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12924 .adc_nids = alc268_adc_nids_alt,
12925 .capsrc_nids = alc268_capsrc_nids,
12926 .hp_nid = 0x02,
12927 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12928 .channel_mode = alc268_modes,
12929 .input_mux = &alc268_acer_dmic_capture_source,
12930 .unsol_event = alc268_acer_unsol_event,
12931 .init_hook = alc268_acer_init_hook,
12933 [ALC268_ACER_ASPIRE_ONE] = {
12934 .mixers = { alc268_acer_aspire_one_mixer,
12935 alc268_beep_mixer,
12936 alc268_capture_nosrc_mixer },
12937 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12938 alc268_acer_aspire_one_verbs },
12939 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12940 .dac_nids = alc268_dac_nids,
12941 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12942 .adc_nids = alc268_adc_nids_alt,
12943 .capsrc_nids = alc268_capsrc_nids,
12944 .hp_nid = 0x03,
12945 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12946 .channel_mode = alc268_modes,
12947 .unsol_event = alc268_acer_lc_unsol_event,
12948 .setup = alc268_acer_lc_setup,
12949 .init_hook = alc268_acer_lc_init_hook,
12951 [ALC268_DELL] = {
12952 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12953 alc268_capture_nosrc_mixer },
12954 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12955 alc268_dell_verbs },
12956 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12957 .dac_nids = alc268_dac_nids,
12958 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12959 .adc_nids = alc268_adc_nids_alt,
12960 .capsrc_nids = alc268_capsrc_nids,
12961 .hp_nid = 0x02,
12962 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12963 .channel_mode = alc268_modes,
12964 .unsol_event = alc_sku_unsol_event,
12965 .setup = alc268_dell_setup,
12966 .init_hook = alc_inithook,
12968 [ALC268_ZEPTO] = {
12969 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12970 alc268_beep_mixer },
12971 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12972 alc268_toshiba_verbs },
12973 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12974 .dac_nids = alc268_dac_nids,
12975 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12976 .adc_nids = alc268_adc_nids_alt,
12977 .capsrc_nids = alc268_capsrc_nids,
12978 .hp_nid = 0x03,
12979 .dig_out_nid = ALC268_DIGOUT_NID,
12980 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12981 .channel_mode = alc268_modes,
12982 .input_mux = &alc268_capture_source,
12983 .setup = alc268_toshiba_setup,
12984 .init_hook = alc268_toshiba_automute,
12986 #ifdef CONFIG_SND_DEBUG
12987 [ALC268_TEST] = {
12988 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12989 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12990 alc268_volume_init_verbs },
12991 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12992 .dac_nids = alc268_dac_nids,
12993 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12994 .adc_nids = alc268_adc_nids_alt,
12995 .capsrc_nids = alc268_capsrc_nids,
12996 .hp_nid = 0x03,
12997 .dig_out_nid = ALC268_DIGOUT_NID,
12998 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12999 .channel_mode = alc268_modes,
13000 .input_mux = &alc268_capture_source,
13002 #endif
13005 static int patch_alc268(struct hda_codec *codec)
13007 struct alc_spec *spec;
13008 int board_config;
13009 int i, has_beep, err;
13011 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13012 if (spec == NULL)
13013 return -ENOMEM;
13015 codec->spec = spec;
13017 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13018 alc268_models,
13019 alc268_cfg_tbl);
13021 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13022 board_config = snd_hda_check_board_codec_sid_config(codec,
13023 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13025 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13026 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13027 codec->chip_name);
13028 board_config = ALC268_AUTO;
13031 if (board_config == ALC268_AUTO) {
13032 /* automatic parse from the BIOS config */
13033 err = alc268_parse_auto_config(codec);
13034 if (err < 0) {
13035 alc_free(codec);
13036 return err;
13037 } else if (!err) {
13038 printk(KERN_INFO
13039 "hda_codec: Cannot set up configuration "
13040 "from BIOS. Using base mode...\n");
13041 board_config = ALC268_3ST;
13045 if (board_config != ALC268_AUTO)
13046 setup_preset(codec, &alc268_presets[board_config]);
13048 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13049 spec->stream_analog_capture = &alc268_pcm_analog_capture;
13050 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
13052 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13054 has_beep = 0;
13055 for (i = 0; i < spec->num_mixers; i++) {
13056 if (spec->mixers[i] == alc268_beep_mixer) {
13057 has_beep = 1;
13058 break;
13062 if (has_beep) {
13063 err = snd_hda_attach_beep_device(codec, 0x1);
13064 if (err < 0) {
13065 alc_free(codec);
13066 return err;
13068 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13069 /* override the amp caps for beep generator */
13070 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13071 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13072 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13073 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13074 (0 << AC_AMPCAP_MUTE_SHIFT));
13077 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13078 /* check whether NID 0x07 is valid */
13079 unsigned int wcap = get_wcaps(codec, 0x07);
13080 int i;
13082 spec->capsrc_nids = alc268_capsrc_nids;
13083 /* get type */
13084 wcap = get_wcaps_type(wcap);
13085 if (spec->auto_mic ||
13086 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
13087 spec->adc_nids = alc268_adc_nids_alt;
13088 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
13089 if (spec->auto_mic)
13090 fixup_automic_adc(codec);
13091 if (spec->auto_mic || spec->input_mux->num_items == 1)
13092 add_mixer(spec, alc268_capture_nosrc_mixer);
13093 else
13094 add_mixer(spec, alc268_capture_alt_mixer);
13095 } else {
13096 spec->adc_nids = alc268_adc_nids;
13097 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13098 add_mixer(spec, alc268_capture_mixer);
13100 /* set default input source */
13101 for (i = 0; i < spec->num_adc_nids; i++)
13102 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13103 0, AC_VERB_SET_CONNECT_SEL,
13104 i < spec->num_mux_defs ?
13105 spec->input_mux[i].items[0].index :
13106 spec->input_mux->items[0].index);
13109 spec->vmaster_nid = 0x02;
13111 codec->patch_ops = alc_patch_ops;
13112 if (board_config == ALC268_AUTO)
13113 spec->init_hook = alc268_auto_init;
13115 codec->proc_widget_hook = print_realtek_coef;
13117 return 0;
13121 * ALC269 channel source setting (2 channel)
13123 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13125 #define alc269_dac_nids alc260_dac_nids
13127 static hda_nid_t alc269_adc_nids[1] = {
13128 /* ADC1 */
13129 0x08,
13132 static hda_nid_t alc269_capsrc_nids[1] = {
13133 0x23,
13136 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13137 * not a mux!
13140 #define alc269_modes alc260_modes
13141 #define alc269_capture_source alc880_lg_lw_capture_source
13143 static struct snd_kcontrol_new alc269_base_mixer[] = {
13144 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13145 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13150 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13153 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13155 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13156 { } /* end */
13159 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13160 /* output mixer control */
13161 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13164 .name = "Master Playback Switch",
13165 .info = snd_hda_mixer_amp_switch_info,
13166 .get = snd_hda_mixer_amp_switch_get,
13167 .put = alc268_acer_master_sw_put,
13168 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13172 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13175 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13179 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13180 /* output mixer control */
13181 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13183 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13184 .name = "Master Playback Switch",
13185 .info = snd_hda_mixer_amp_switch_info,
13186 .get = snd_hda_mixer_amp_switch_get,
13187 .put = alc268_acer_master_sw_put,
13188 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13192 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13193 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13194 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13195 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13196 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13197 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13198 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
13202 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13203 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13204 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13206 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13207 { } /* end */
13210 /* capture mixer elements */
13211 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
13212 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13213 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13214 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13215 { } /* end */
13218 /* FSC amilo */
13219 #define alc269_fujitsu_mixer alc269_eeepc_mixer
13221 static struct hda_verb alc269_quanta_fl1_verbs[] = {
13222 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13223 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13225 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13226 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13227 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13231 static struct hda_verb alc269_lifebook_verbs[] = {
13232 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13233 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13234 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13236 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13237 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13238 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13239 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13240 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13241 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13245 /* toggle speaker-output according to the hp-jack state */
13246 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13248 unsigned int present;
13249 unsigned char bits;
13251 present = snd_hda_jack_detect(codec, 0x15);
13252 bits = present ? AMP_IN_MUTE(0) : 0;
13253 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13254 AMP_IN_MUTE(0), bits);
13255 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13256 AMP_IN_MUTE(0), bits);
13258 snd_hda_codec_write(codec, 0x20, 0,
13259 AC_VERB_SET_COEF_INDEX, 0x0c);
13260 snd_hda_codec_write(codec, 0x20, 0,
13261 AC_VERB_SET_PROC_COEF, 0x680);
13263 snd_hda_codec_write(codec, 0x20, 0,
13264 AC_VERB_SET_COEF_INDEX, 0x0c);
13265 snd_hda_codec_write(codec, 0x20, 0,
13266 AC_VERB_SET_PROC_COEF, 0x480);
13269 /* toggle speaker-output according to the hp-jacks state */
13270 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13272 unsigned int present;
13273 unsigned char bits;
13275 /* Check laptop headphone socket */
13276 present = snd_hda_jack_detect(codec, 0x15);
13278 /* Check port replicator headphone socket */
13279 present |= snd_hda_jack_detect(codec, 0x1a);
13281 bits = present ? AMP_IN_MUTE(0) : 0;
13282 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13283 AMP_IN_MUTE(0), bits);
13284 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13285 AMP_IN_MUTE(0), bits);
13287 snd_hda_codec_write(codec, 0x20, 0,
13288 AC_VERB_SET_COEF_INDEX, 0x0c);
13289 snd_hda_codec_write(codec, 0x20, 0,
13290 AC_VERB_SET_PROC_COEF, 0x680);
13292 snd_hda_codec_write(codec, 0x20, 0,
13293 AC_VERB_SET_COEF_INDEX, 0x0c);
13294 snd_hda_codec_write(codec, 0x20, 0,
13295 AC_VERB_SET_PROC_COEF, 0x480);
13298 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13300 unsigned int present_laptop;
13301 unsigned int present_dock;
13303 present_laptop = snd_hda_jack_detect(codec, 0x18);
13304 present_dock = snd_hda_jack_detect(codec, 0x1b);
13306 /* Laptop mic port overrides dock mic port, design decision */
13307 if (present_dock)
13308 snd_hda_codec_write(codec, 0x23, 0,
13309 AC_VERB_SET_CONNECT_SEL, 0x3);
13310 if (present_laptop)
13311 snd_hda_codec_write(codec, 0x23, 0,
13312 AC_VERB_SET_CONNECT_SEL, 0x0);
13313 if (!present_dock && !present_laptop)
13314 snd_hda_codec_write(codec, 0x23, 0,
13315 AC_VERB_SET_CONNECT_SEL, 0x1);
13318 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13319 unsigned int res)
13321 switch (res >> 26) {
13322 case ALC880_HP_EVENT:
13323 alc269_quanta_fl1_speaker_automute(codec);
13324 break;
13325 case ALC880_MIC_EVENT:
13326 alc_mic_automute(codec);
13327 break;
13331 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13332 unsigned int res)
13334 if ((res >> 26) == ALC880_HP_EVENT)
13335 alc269_lifebook_speaker_automute(codec);
13336 if ((res >> 26) == ALC880_MIC_EVENT)
13337 alc269_lifebook_mic_autoswitch(codec);
13340 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13342 struct alc_spec *spec = codec->spec;
13343 spec->ext_mic.pin = 0x18;
13344 spec->ext_mic.mux_idx = 0;
13345 spec->int_mic.pin = 0x19;
13346 spec->int_mic.mux_idx = 1;
13347 spec->auto_mic = 1;
13350 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13352 alc269_quanta_fl1_speaker_automute(codec);
13353 alc_mic_automute(codec);
13356 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13358 alc269_lifebook_speaker_automute(codec);
13359 alc269_lifebook_mic_autoswitch(codec);
13362 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13363 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13364 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13365 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13366 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13367 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13368 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13369 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13373 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13374 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13375 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13376 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13377 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13378 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13379 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13383 /* toggle speaker-output according to the hp-jack state */
13384 static void alc269_speaker_automute(struct hda_codec *codec)
13386 struct alc_spec *spec = codec->spec;
13387 unsigned int nid = spec->autocfg.hp_pins[0];
13388 unsigned int present;
13389 unsigned char bits;
13391 present = snd_hda_jack_detect(codec, nid);
13392 bits = present ? AMP_IN_MUTE(0) : 0;
13393 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13394 AMP_IN_MUTE(0), bits);
13395 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13396 AMP_IN_MUTE(0), bits);
13399 /* unsolicited event for HP jack sensing */
13400 static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13401 unsigned int res)
13403 switch (res >> 26) {
13404 case ALC880_HP_EVENT:
13405 alc269_speaker_automute(codec);
13406 break;
13407 case ALC880_MIC_EVENT:
13408 alc_mic_automute(codec);
13409 break;
13413 static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13415 struct alc_spec *spec = codec->spec;
13416 spec->ext_mic.pin = 0x18;
13417 spec->ext_mic.mux_idx = 0;
13418 spec->int_mic.pin = 0x12;
13419 spec->int_mic.mux_idx = 5;
13420 spec->auto_mic = 1;
13423 static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13425 struct alc_spec *spec = codec->spec;
13426 spec->ext_mic.pin = 0x18;
13427 spec->ext_mic.mux_idx = 0;
13428 spec->int_mic.pin = 0x19;
13429 spec->int_mic.mux_idx = 1;
13430 spec->auto_mic = 1;
13433 static void alc269_eeepc_inithook(struct hda_codec *codec)
13435 alc269_speaker_automute(codec);
13436 alc_mic_automute(codec);
13440 * generic initialization of ADC, input mixers and output mixers
13442 static struct hda_verb alc269_init_verbs[] = {
13444 * Unmute ADC0 and set the default input to mic-in
13446 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13448 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13449 * analog-loopback mixer widget
13450 * Note: PASD motherboards uses the Line In 2 as the input for
13451 * front panel mic (mic 2)
13453 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13461 * Set up output mixers (0x0c - 0x0e)
13463 /* set vol=0 to output mixers */
13464 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13465 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13467 /* set up input amps for analog loopback */
13468 /* Amp Indices: DAC = 0, mixer = 1 */
13469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13477 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13478 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13480 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13481 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13482 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13485 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13486 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13487 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13488 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13489 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13490 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13492 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13495 /* FIXME: use matrix-type input source selection */
13496 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13497 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13498 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13499 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13500 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13501 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13503 /* set EAPD */
13504 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13505 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13509 #define alc269_auto_create_multi_out_ctls \
13510 alc268_auto_create_multi_out_ctls
13511 #define alc269_auto_create_input_ctls \
13512 alc268_auto_create_input_ctls
13514 #ifdef CONFIG_SND_HDA_POWER_SAVE
13515 #define alc269_loopbacks alc880_loopbacks
13516 #endif
13518 /* pcm configuration: identical with ALC880 */
13519 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13520 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13521 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13522 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13524 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13525 .substreams = 1,
13526 .channels_min = 2,
13527 .channels_max = 8,
13528 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13529 /* NID is set in alc_build_pcms */
13530 .ops = {
13531 .open = alc880_playback_pcm_open,
13532 .prepare = alc880_playback_pcm_prepare,
13533 .cleanup = alc880_playback_pcm_cleanup
13537 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13538 .substreams = 1,
13539 .channels_min = 2,
13540 .channels_max = 2,
13541 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13542 /* NID is set in alc_build_pcms */
13546 * BIOS auto configuration
13548 static int alc269_parse_auto_config(struct hda_codec *codec)
13550 struct alc_spec *spec = codec->spec;
13551 int err;
13552 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13554 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13555 alc269_ignore);
13556 if (err < 0)
13557 return err;
13559 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13560 if (err < 0)
13561 return err;
13562 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13563 if (err < 0)
13564 return err;
13566 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13568 if (spec->autocfg.dig_outs)
13569 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13571 if (spec->kctls.list)
13572 add_mixer(spec, spec->kctls.list);
13574 add_verb(spec, alc269_init_verbs);
13575 spec->num_mux_defs = 1;
13576 spec->input_mux = &spec->private_imux[0];
13577 /* set default input source */
13578 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13579 0, AC_VERB_SET_CONNECT_SEL,
13580 spec->input_mux->items[0].index);
13582 err = alc_auto_add_mic_boost(codec);
13583 if (err < 0)
13584 return err;
13586 if (!spec->cap_mixer && !spec->no_analog)
13587 set_capture_mixer(codec);
13589 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13591 return 1;
13594 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
13595 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
13596 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13599 /* init callback for auto-configuration model -- overriding the default init */
13600 static void alc269_auto_init(struct hda_codec *codec)
13602 struct alc_spec *spec = codec->spec;
13603 alc269_auto_init_multi_out(codec);
13604 alc269_auto_init_hp_out(codec);
13605 alc269_auto_init_analog_input(codec);
13606 if (spec->unsol_event)
13607 alc_inithook(codec);
13611 * configuration and preset
13613 static const char *alc269_models[ALC269_MODEL_LAST] = {
13614 [ALC269_BASIC] = "basic",
13615 [ALC269_QUANTA_FL1] = "quanta",
13616 [ALC269_ASUS_AMIC] = "asus-amic",
13617 [ALC269_ASUS_DMIC] = "asus-dmic",
13618 [ALC269_FUJITSU] = "fujitsu",
13619 [ALC269_LIFEBOOK] = "lifebook",
13620 [ALC269_AUTO] = "auto",
13623 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13624 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13625 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13626 ALC269_ASUS_AMIC),
13627 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC),
13628 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC),
13629 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC),
13630 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC),
13631 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC),
13632 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC),
13633 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC),
13634 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC),
13635 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC),
13636 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC),
13637 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC),
13638 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC),
13639 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC),
13640 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC),
13641 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC),
13642 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC),
13643 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC),
13644 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC),
13645 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC),
13646 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC),
13647 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC),
13648 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC),
13649 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC),
13650 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC),
13651 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC),
13652 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC),
13653 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC),
13654 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC),
13655 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13656 ALC269_ASUS_DMIC),
13657 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13658 ALC269_ASUS_DMIC),
13659 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC),
13660 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC),
13661 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13662 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13666 static struct alc_config_preset alc269_presets[] = {
13667 [ALC269_BASIC] = {
13668 .mixers = { alc269_base_mixer },
13669 .init_verbs = { alc269_init_verbs },
13670 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13671 .dac_nids = alc269_dac_nids,
13672 .hp_nid = 0x03,
13673 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13674 .channel_mode = alc269_modes,
13675 .input_mux = &alc269_capture_source,
13677 [ALC269_QUANTA_FL1] = {
13678 .mixers = { alc269_quanta_fl1_mixer },
13679 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13680 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13681 .dac_nids = alc269_dac_nids,
13682 .hp_nid = 0x03,
13683 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13684 .channel_mode = alc269_modes,
13685 .input_mux = &alc269_capture_source,
13686 .unsol_event = alc269_quanta_fl1_unsol_event,
13687 .setup = alc269_quanta_fl1_setup,
13688 .init_hook = alc269_quanta_fl1_init_hook,
13690 [ALC269_ASUS_AMIC] = {
13691 .mixers = { alc269_eeepc_mixer },
13692 .cap_mixer = alc269_epc_capture_mixer,
13693 .init_verbs = { alc269_init_verbs,
13694 alc269_eeepc_amic_init_verbs },
13695 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13696 .dac_nids = alc269_dac_nids,
13697 .hp_nid = 0x03,
13698 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13699 .channel_mode = alc269_modes,
13700 .unsol_event = alc269_eeepc_unsol_event,
13701 .setup = alc269_eeepc_amic_setup,
13702 .init_hook = alc269_eeepc_inithook,
13704 [ALC269_ASUS_DMIC] = {
13705 .mixers = { alc269_eeepc_mixer },
13706 .cap_mixer = alc269_epc_capture_mixer,
13707 .init_verbs = { alc269_init_verbs,
13708 alc269_eeepc_dmic_init_verbs },
13709 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13710 .dac_nids = alc269_dac_nids,
13711 .hp_nid = 0x03,
13712 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13713 .channel_mode = alc269_modes,
13714 .unsol_event = alc269_eeepc_unsol_event,
13715 .setup = alc269_eeepc_dmic_setup,
13716 .init_hook = alc269_eeepc_inithook,
13718 [ALC269_FUJITSU] = {
13719 .mixers = { alc269_fujitsu_mixer },
13720 .cap_mixer = alc269_epc_capture_mixer,
13721 .init_verbs = { alc269_init_verbs,
13722 alc269_eeepc_dmic_init_verbs },
13723 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13724 .dac_nids = alc269_dac_nids,
13725 .hp_nid = 0x03,
13726 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13727 .channel_mode = alc269_modes,
13728 .unsol_event = alc269_eeepc_unsol_event,
13729 .setup = alc269_eeepc_dmic_setup,
13730 .init_hook = alc269_eeepc_inithook,
13732 [ALC269_LIFEBOOK] = {
13733 .mixers = { alc269_lifebook_mixer },
13734 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13735 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13736 .dac_nids = alc269_dac_nids,
13737 .hp_nid = 0x03,
13738 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13739 .channel_mode = alc269_modes,
13740 .input_mux = &alc269_capture_source,
13741 .unsol_event = alc269_lifebook_unsol_event,
13742 .init_hook = alc269_lifebook_init_hook,
13746 static int patch_alc269(struct hda_codec *codec)
13748 struct alc_spec *spec;
13749 int board_config;
13750 int err;
13752 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13753 if (spec == NULL)
13754 return -ENOMEM;
13756 codec->spec = spec;
13758 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13760 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
13761 kfree(codec->chip_name);
13762 codec->chip_name = kstrdup("ALC259", GFP_KERNEL);
13763 if (!codec->chip_name) {
13764 alc_free(codec);
13765 return -ENOMEM;
13769 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13770 alc269_models,
13771 alc269_cfg_tbl);
13773 if (board_config < 0) {
13774 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13775 codec->chip_name);
13776 board_config = ALC269_AUTO;
13779 if (board_config == ALC269_AUTO) {
13780 /* automatic parse from the BIOS config */
13781 err = alc269_parse_auto_config(codec);
13782 if (err < 0) {
13783 alc_free(codec);
13784 return err;
13785 } else if (!err) {
13786 printk(KERN_INFO
13787 "hda_codec: Cannot set up configuration "
13788 "from BIOS. Using base mode...\n");
13789 board_config = ALC269_BASIC;
13793 err = snd_hda_attach_beep_device(codec, 0x1);
13794 if (err < 0) {
13795 alc_free(codec);
13796 return err;
13799 if (board_config != ALC269_AUTO)
13800 setup_preset(codec, &alc269_presets[board_config]);
13802 if (codec->subsystem_id == 0x17aa3bf8) {
13803 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13804 * fix the sample rate of analog I/O to 44.1kHz
13806 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13807 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13808 } else {
13809 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13810 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13812 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13813 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13815 spec->adc_nids = alc269_adc_nids;
13816 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13817 spec->capsrc_nids = alc269_capsrc_nids;
13818 if (!spec->cap_mixer)
13819 set_capture_mixer(codec);
13820 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13822 spec->vmaster_nid = 0x02;
13824 codec->patch_ops = alc_patch_ops;
13825 if (board_config == ALC269_AUTO)
13826 spec->init_hook = alc269_auto_init;
13827 #ifdef CONFIG_SND_HDA_POWER_SAVE
13828 if (!spec->loopback.amplist)
13829 spec->loopback.amplist = alc269_loopbacks;
13830 #endif
13831 codec->proc_widget_hook = print_realtek_coef;
13833 return 0;
13837 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13841 * set the path ways for 2 channel output
13842 * need to set the codec line out and mic 1 pin widgets to inputs
13844 static struct hda_verb alc861_threestack_ch2_init[] = {
13845 /* set pin widget 1Ah (line in) for input */
13846 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13847 /* set pin widget 18h (mic1/2) for input, for mic also enable
13848 * the vref
13850 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13852 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13853 #if 0
13854 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13855 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13856 #endif
13857 { } /* end */
13860 * 6ch mode
13861 * need to set the codec line out and mic 1 pin widgets to outputs
13863 static struct hda_verb alc861_threestack_ch6_init[] = {
13864 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13865 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13866 /* set pin widget 18h (mic1) for output (CLFE)*/
13867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13869 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13870 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13872 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13873 #if 0
13874 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13875 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13876 #endif
13877 { } /* end */
13880 static struct hda_channel_mode alc861_threestack_modes[2] = {
13881 { 2, alc861_threestack_ch2_init },
13882 { 6, alc861_threestack_ch6_init },
13884 /* Set mic1 as input and unmute the mixer */
13885 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13886 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13887 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13888 { } /* end */
13890 /* Set mic1 as output and mute mixer */
13891 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13892 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13893 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13894 { } /* end */
13897 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13898 { 2, alc861_uniwill_m31_ch2_init },
13899 { 4, alc861_uniwill_m31_ch4_init },
13902 /* Set mic1 and line-in as input and unmute the mixer */
13903 static struct hda_verb alc861_asus_ch2_init[] = {
13904 /* set pin widget 1Ah (line in) for input */
13905 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13906 /* set pin widget 18h (mic1/2) for input, for mic also enable
13907 * the vref
13909 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13911 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13912 #if 0
13913 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13914 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13915 #endif
13916 { } /* end */
13918 /* Set mic1 nad line-in as output and mute mixer */
13919 static struct hda_verb alc861_asus_ch6_init[] = {
13920 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13921 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13922 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13923 /* set pin widget 18h (mic1) for output (CLFE)*/
13924 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13925 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13926 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13927 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13929 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13930 #if 0
13931 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13932 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13933 #endif
13934 { } /* end */
13937 static struct hda_channel_mode alc861_asus_modes[2] = {
13938 { 2, alc861_asus_ch2_init },
13939 { 6, alc861_asus_ch6_init },
13942 /* patch-ALC861 */
13944 static struct snd_kcontrol_new alc861_base_mixer[] = {
13945 /* output mixer control */
13946 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13947 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13948 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13949 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13950 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13952 /*Input mixer control */
13953 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13954 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13955 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13956 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13957 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13958 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13959 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13960 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13961 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13962 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13964 { } /* end */
13967 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13968 /* output mixer control */
13969 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13970 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13971 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13972 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13973 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13975 /* Input mixer control */
13976 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13977 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13978 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13979 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13980 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13981 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13983 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13984 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13988 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13989 .name = "Channel Mode",
13990 .info = alc_ch_mode_info,
13991 .get = alc_ch_mode_get,
13992 .put = alc_ch_mode_put,
13993 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13995 { } /* end */
13998 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13999 /* output mixer control */
14000 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14002 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14004 { } /* end */
14007 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14008 /* output mixer control */
14009 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14010 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14011 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14012 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14013 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14015 /* Input mixer control */
14016 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14017 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14018 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14019 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14020 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14021 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14023 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14024 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14025 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14028 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14029 .name = "Channel Mode",
14030 .info = alc_ch_mode_info,
14031 .get = alc_ch_mode_get,
14032 .put = alc_ch_mode_put,
14033 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14035 { } /* end */
14038 static struct snd_kcontrol_new alc861_asus_mixer[] = {
14039 /* output mixer control */
14040 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14041 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14042 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14043 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14044 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14046 /* Input mixer control */
14047 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14048 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14049 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14050 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14051 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14052 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14054 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14055 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14056 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14060 .name = "Channel Mode",
14061 .info = alc_ch_mode_info,
14062 .get = alc_ch_mode_get,
14063 .put = alc_ch_mode_put,
14064 .private_value = ARRAY_SIZE(alc861_asus_modes),
14069 /* additional mixer */
14070 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
14071 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14072 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14077 * generic initialization of ADC, input mixers and output mixers
14079 static struct hda_verb alc861_base_init_verbs[] = {
14081 * Unmute ADC0 and set the default input to mic-in
14083 /* port-A for surround (rear panel) */
14084 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14085 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14086 /* port-B for mic-in (rear panel) with vref */
14087 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14088 /* port-C for line-in (rear panel) */
14089 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14090 /* port-D for Front */
14091 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14092 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14093 /* port-E for HP out (front panel) */
14094 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14095 /* route front PCM to HP */
14096 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14097 /* port-F for mic-in (front panel) with vref */
14098 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14099 /* port-G for CLFE (rear panel) */
14100 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14101 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14102 /* port-H for side (rear panel) */
14103 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14104 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14105 /* CD-in */
14106 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14107 /* route front mic to ADC1*/
14108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14109 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14111 /* Unmute DAC0~3 & spdif out*/
14112 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14113 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14114 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14115 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14118 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14119 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14120 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14121 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14122 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14124 /* Unmute Stereo Mixer 15 */
14125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14126 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14127 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14128 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14130 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14131 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14132 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14133 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14134 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14137 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14138 /* hp used DAC 3 (Front) */
14139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14140 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14145 static struct hda_verb alc861_threestack_init_verbs[] = {
14147 * Unmute ADC0 and set the default input to mic-in
14149 /* port-A for surround (rear panel) */
14150 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14151 /* port-B for mic-in (rear panel) with vref */
14152 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14153 /* port-C for line-in (rear panel) */
14154 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14155 /* port-D for Front */
14156 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14157 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14158 /* port-E for HP out (front panel) */
14159 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14160 /* route front PCM to HP */
14161 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14162 /* port-F for mic-in (front panel) with vref */
14163 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14164 /* port-G for CLFE (rear panel) */
14165 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14166 /* port-H for side (rear panel) */
14167 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14168 /* CD-in */
14169 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14170 /* route front mic to ADC1*/
14171 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14173 /* Unmute DAC0~3 & spdif out*/
14174 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14175 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14176 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14177 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14178 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14180 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14181 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14182 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14183 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14184 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14186 /* Unmute Stereo Mixer 15 */
14187 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14188 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14190 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14192 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14193 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14194 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14195 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14196 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14197 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14198 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14200 /* hp used DAC 3 (Front) */
14201 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14202 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14206 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14208 * Unmute ADC0 and set the default input to mic-in
14210 /* port-A for surround (rear panel) */
14211 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14212 /* port-B for mic-in (rear panel) with vref */
14213 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14214 /* port-C for line-in (rear panel) */
14215 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14216 /* port-D for Front */
14217 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14218 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14219 /* port-E for HP out (front panel) */
14220 /* this has to be set to VREF80 */
14221 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14222 /* route front PCM to HP */
14223 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14224 /* port-F for mic-in (front panel) with vref */
14225 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14226 /* port-G for CLFE (rear panel) */
14227 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14228 /* port-H for side (rear panel) */
14229 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14230 /* CD-in */
14231 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14232 /* route front mic to ADC1*/
14233 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14235 /* Unmute DAC0~3 & spdif out*/
14236 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14237 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14238 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14239 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14240 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14242 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14243 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14244 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14245 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14246 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14248 /* Unmute Stereo Mixer 15 */
14249 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14250 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14251 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14252 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14254 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14255 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14256 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14257 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14258 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14259 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14260 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14261 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14262 /* hp used DAC 3 (Front) */
14263 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14264 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14268 static struct hda_verb alc861_asus_init_verbs[] = {
14270 * Unmute ADC0 and set the default input to mic-in
14272 /* port-A for surround (rear panel)
14273 * according to codec#0 this is the HP jack
14275 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14276 /* route front PCM to HP */
14277 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14278 /* port-B for mic-in (rear panel) with vref */
14279 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14280 /* port-C for line-in (rear panel) */
14281 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14282 /* port-D for Front */
14283 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14284 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14285 /* port-E for HP out (front panel) */
14286 /* this has to be set to VREF80 */
14287 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14288 /* route front PCM to HP */
14289 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14290 /* port-F for mic-in (front panel) with vref */
14291 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14292 /* port-G for CLFE (rear panel) */
14293 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14294 /* port-H for side (rear panel) */
14295 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14296 /* CD-in */
14297 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14298 /* route front mic to ADC1*/
14299 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14300 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14301 /* Unmute DAC0~3 & spdif out*/
14302 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14303 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14304 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14305 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14307 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14308 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14309 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14310 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14311 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14313 /* Unmute Stereo Mixer 15 */
14314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14316 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14317 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14319 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14320 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14321 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14322 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14323 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14324 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14325 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14326 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14327 /* hp used DAC 3 (Front) */
14328 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14329 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14333 /* additional init verbs for ASUS laptops */
14334 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14335 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14336 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14341 * generic initialization of ADC, input mixers and output mixers
14343 static struct hda_verb alc861_auto_init_verbs[] = {
14345 * Unmute ADC0 and set the default input to mic-in
14347 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14348 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14350 /* Unmute DAC0~3 & spdif out*/
14351 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14352 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14353 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14354 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14355 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14357 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14358 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14359 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14360 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14361 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14363 /* Unmute Stereo Mixer 15 */
14364 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14366 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14369 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14370 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14371 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14372 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14373 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14374 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14375 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14376 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14378 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14382 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14383 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14384 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14385 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14387 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14392 static struct hda_verb alc861_toshiba_init_verbs[] = {
14393 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14398 /* toggle speaker-output according to the hp-jack state */
14399 static void alc861_toshiba_automute(struct hda_codec *codec)
14401 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
14403 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14404 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14405 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14406 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14409 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14410 unsigned int res)
14412 if ((res >> 26) == ALC880_HP_EVENT)
14413 alc861_toshiba_automute(codec);
14416 /* pcm configuration: identical with ALC880 */
14417 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
14418 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
14419 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
14420 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
14423 #define ALC861_DIGOUT_NID 0x07
14425 static struct hda_channel_mode alc861_8ch_modes[1] = {
14426 { 8, NULL }
14429 static hda_nid_t alc861_dac_nids[4] = {
14430 /* front, surround, clfe, side */
14431 0x03, 0x06, 0x05, 0x04
14434 static hda_nid_t alc660_dac_nids[3] = {
14435 /* front, clfe, surround */
14436 0x03, 0x05, 0x06
14439 static hda_nid_t alc861_adc_nids[1] = {
14440 /* ADC0-2 */
14441 0x08,
14444 static struct hda_input_mux alc861_capture_source = {
14445 .num_items = 5,
14446 .items = {
14447 { "Mic", 0x0 },
14448 { "Front Mic", 0x3 },
14449 { "Line", 0x1 },
14450 { "CD", 0x4 },
14451 { "Mixer", 0x5 },
14455 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14457 struct alc_spec *spec = codec->spec;
14458 hda_nid_t mix, srcs[5];
14459 int i, j, num;
14461 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14462 return 0;
14463 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14464 if (num < 0)
14465 return 0;
14466 for (i = 0; i < num; i++) {
14467 unsigned int type;
14468 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14469 if (type != AC_WID_AUD_OUT)
14470 continue;
14471 for (j = 0; j < spec->multiout.num_dacs; j++)
14472 if (spec->multiout.dac_nids[j] == srcs[i])
14473 break;
14474 if (j >= spec->multiout.num_dacs)
14475 return srcs[i];
14477 return 0;
14480 /* fill in the dac_nids table from the parsed pin configuration */
14481 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14482 const struct auto_pin_cfg *cfg)
14484 struct alc_spec *spec = codec->spec;
14485 int i;
14486 hda_nid_t nid, dac;
14488 spec->multiout.dac_nids = spec->private_dac_nids;
14489 for (i = 0; i < cfg->line_outs; i++) {
14490 nid = cfg->line_out_pins[i];
14491 dac = alc861_look_for_dac(codec, nid);
14492 if (!dac)
14493 continue;
14494 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14496 return 0;
14499 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14500 hda_nid_t nid, unsigned int chs)
14502 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
14503 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14506 /* add playback controls from the parsed DAC table */
14507 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14508 const struct auto_pin_cfg *cfg)
14510 struct alc_spec *spec = codec->spec;
14511 static const char *chname[4] = {
14512 "Front", "Surround", NULL /*CLFE*/, "Side"
14514 hda_nid_t nid;
14515 int i, err;
14517 if (cfg->line_outs == 1) {
14518 const char *pfx = NULL;
14519 if (!cfg->hp_outs)
14520 pfx = "Master";
14521 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14522 pfx = "Speaker";
14523 if (pfx) {
14524 nid = spec->multiout.dac_nids[0];
14525 return alc861_create_out_sw(codec, pfx, nid, 3);
14529 for (i = 0; i < cfg->line_outs; i++) {
14530 nid = spec->multiout.dac_nids[i];
14531 if (!nid)
14532 continue;
14533 if (i == 2) {
14534 /* Center/LFE */
14535 err = alc861_create_out_sw(codec, "Center", nid, 1);
14536 if (err < 0)
14537 return err;
14538 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14539 if (err < 0)
14540 return err;
14541 } else {
14542 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14543 if (err < 0)
14544 return err;
14547 return 0;
14550 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14552 struct alc_spec *spec = codec->spec;
14553 int err;
14554 hda_nid_t nid;
14556 if (!pin)
14557 return 0;
14559 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14560 nid = alc861_look_for_dac(codec, pin);
14561 if (nid) {
14562 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14563 if (err < 0)
14564 return err;
14565 spec->multiout.hp_nid = nid;
14568 return 0;
14571 /* create playback/capture controls for input pins */
14572 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14573 const struct auto_pin_cfg *cfg)
14575 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14578 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14579 hda_nid_t nid,
14580 int pin_type, hda_nid_t dac)
14582 hda_nid_t mix, srcs[5];
14583 int i, num;
14585 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14586 pin_type);
14587 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14588 AMP_OUT_UNMUTE);
14589 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14590 return;
14591 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14592 if (num < 0)
14593 return;
14594 for (i = 0; i < num; i++) {
14595 unsigned int mute;
14596 if (srcs[i] == dac || srcs[i] == 0x15)
14597 mute = AMP_IN_UNMUTE(i);
14598 else
14599 mute = AMP_IN_MUTE(i);
14600 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14601 mute);
14605 static void alc861_auto_init_multi_out(struct hda_codec *codec)
14607 struct alc_spec *spec = codec->spec;
14608 int i;
14610 for (i = 0; i < spec->autocfg.line_outs; i++) {
14611 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14612 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14613 if (nid)
14614 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14615 spec->multiout.dac_nids[i]);
14619 static void alc861_auto_init_hp_out(struct hda_codec *codec)
14621 struct alc_spec *spec = codec->spec;
14623 if (spec->autocfg.hp_outs)
14624 alc861_auto_set_output_and_unmute(codec,
14625 spec->autocfg.hp_pins[0],
14626 PIN_HP,
14627 spec->multiout.hp_nid);
14628 if (spec->autocfg.speaker_outs)
14629 alc861_auto_set_output_and_unmute(codec,
14630 spec->autocfg.speaker_pins[0],
14631 PIN_OUT,
14632 spec->multiout.dac_nids[0]);
14635 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14637 struct alc_spec *spec = codec->spec;
14638 int i;
14640 for (i = 0; i < AUTO_PIN_LAST; i++) {
14641 hda_nid_t nid = spec->autocfg.input_pins[i];
14642 if (nid >= 0x0c && nid <= 0x11)
14643 alc_set_input_pin(codec, nid, i);
14647 /* parse the BIOS configuration and set up the alc_spec */
14648 /* return 1 if successful, 0 if the proper config is not found,
14649 * or a negative error code
14651 static int alc861_parse_auto_config(struct hda_codec *codec)
14653 struct alc_spec *spec = codec->spec;
14654 int err;
14655 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14657 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14658 alc861_ignore);
14659 if (err < 0)
14660 return err;
14661 if (!spec->autocfg.line_outs)
14662 return 0; /* can't find valid BIOS pin config */
14664 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14665 if (err < 0)
14666 return err;
14667 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14668 if (err < 0)
14669 return err;
14670 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14671 if (err < 0)
14672 return err;
14673 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14674 if (err < 0)
14675 return err;
14677 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14679 if (spec->autocfg.dig_outs)
14680 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14682 if (spec->kctls.list)
14683 add_mixer(spec, spec->kctls.list);
14685 add_verb(spec, alc861_auto_init_verbs);
14687 spec->num_mux_defs = 1;
14688 spec->input_mux = &spec->private_imux[0];
14690 spec->adc_nids = alc861_adc_nids;
14691 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14692 set_capture_mixer(codec);
14694 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14696 return 1;
14699 /* additional initialization for auto-configuration model */
14700 static void alc861_auto_init(struct hda_codec *codec)
14702 struct alc_spec *spec = codec->spec;
14703 alc861_auto_init_multi_out(codec);
14704 alc861_auto_init_hp_out(codec);
14705 alc861_auto_init_analog_input(codec);
14706 if (spec->unsol_event)
14707 alc_inithook(codec);
14710 #ifdef CONFIG_SND_HDA_POWER_SAVE
14711 static struct hda_amp_list alc861_loopbacks[] = {
14712 { 0x15, HDA_INPUT, 0 },
14713 { 0x15, HDA_INPUT, 1 },
14714 { 0x15, HDA_INPUT, 2 },
14715 { 0x15, HDA_INPUT, 3 },
14716 { } /* end */
14718 #endif
14722 * configuration and preset
14724 static const char *alc861_models[ALC861_MODEL_LAST] = {
14725 [ALC861_3ST] = "3stack",
14726 [ALC660_3ST] = "3stack-660",
14727 [ALC861_3ST_DIG] = "3stack-dig",
14728 [ALC861_6ST_DIG] = "6stack-dig",
14729 [ALC861_UNIWILL_M31] = "uniwill-m31",
14730 [ALC861_TOSHIBA] = "toshiba",
14731 [ALC861_ASUS] = "asus",
14732 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14733 [ALC861_AUTO] = "auto",
14736 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14737 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14738 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14739 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14740 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14741 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14742 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14743 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14744 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14745 * Any other models that need this preset?
14747 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14748 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14749 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14750 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14751 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14752 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14753 /* FIXME: the below seems conflict */
14754 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14755 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14756 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14760 static struct alc_config_preset alc861_presets[] = {
14761 [ALC861_3ST] = {
14762 .mixers = { alc861_3ST_mixer },
14763 .init_verbs = { alc861_threestack_init_verbs },
14764 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14765 .dac_nids = alc861_dac_nids,
14766 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14767 .channel_mode = alc861_threestack_modes,
14768 .need_dac_fix = 1,
14769 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14770 .adc_nids = alc861_adc_nids,
14771 .input_mux = &alc861_capture_source,
14773 [ALC861_3ST_DIG] = {
14774 .mixers = { alc861_base_mixer },
14775 .init_verbs = { alc861_threestack_init_verbs },
14776 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14777 .dac_nids = alc861_dac_nids,
14778 .dig_out_nid = ALC861_DIGOUT_NID,
14779 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14780 .channel_mode = alc861_threestack_modes,
14781 .need_dac_fix = 1,
14782 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14783 .adc_nids = alc861_adc_nids,
14784 .input_mux = &alc861_capture_source,
14786 [ALC861_6ST_DIG] = {
14787 .mixers = { alc861_base_mixer },
14788 .init_verbs = { alc861_base_init_verbs },
14789 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14790 .dac_nids = alc861_dac_nids,
14791 .dig_out_nid = ALC861_DIGOUT_NID,
14792 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14793 .channel_mode = alc861_8ch_modes,
14794 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14795 .adc_nids = alc861_adc_nids,
14796 .input_mux = &alc861_capture_source,
14798 [ALC660_3ST] = {
14799 .mixers = { alc861_3ST_mixer },
14800 .init_verbs = { alc861_threestack_init_verbs },
14801 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14802 .dac_nids = alc660_dac_nids,
14803 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14804 .channel_mode = alc861_threestack_modes,
14805 .need_dac_fix = 1,
14806 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14807 .adc_nids = alc861_adc_nids,
14808 .input_mux = &alc861_capture_source,
14810 [ALC861_UNIWILL_M31] = {
14811 .mixers = { alc861_uniwill_m31_mixer },
14812 .init_verbs = { alc861_uniwill_m31_init_verbs },
14813 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14814 .dac_nids = alc861_dac_nids,
14815 .dig_out_nid = ALC861_DIGOUT_NID,
14816 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14817 .channel_mode = alc861_uniwill_m31_modes,
14818 .need_dac_fix = 1,
14819 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14820 .adc_nids = alc861_adc_nids,
14821 .input_mux = &alc861_capture_source,
14823 [ALC861_TOSHIBA] = {
14824 .mixers = { alc861_toshiba_mixer },
14825 .init_verbs = { alc861_base_init_verbs,
14826 alc861_toshiba_init_verbs },
14827 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14828 .dac_nids = alc861_dac_nids,
14829 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14830 .channel_mode = alc883_3ST_2ch_modes,
14831 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14832 .adc_nids = alc861_adc_nids,
14833 .input_mux = &alc861_capture_source,
14834 .unsol_event = alc861_toshiba_unsol_event,
14835 .init_hook = alc861_toshiba_automute,
14837 [ALC861_ASUS] = {
14838 .mixers = { alc861_asus_mixer },
14839 .init_verbs = { alc861_asus_init_verbs },
14840 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14841 .dac_nids = alc861_dac_nids,
14842 .dig_out_nid = ALC861_DIGOUT_NID,
14843 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14844 .channel_mode = alc861_asus_modes,
14845 .need_dac_fix = 1,
14846 .hp_nid = 0x06,
14847 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14848 .adc_nids = alc861_adc_nids,
14849 .input_mux = &alc861_capture_source,
14851 [ALC861_ASUS_LAPTOP] = {
14852 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14853 .init_verbs = { alc861_asus_init_verbs,
14854 alc861_asus_laptop_init_verbs },
14855 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14856 .dac_nids = alc861_dac_nids,
14857 .dig_out_nid = ALC861_DIGOUT_NID,
14858 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14859 .channel_mode = alc883_3ST_2ch_modes,
14860 .need_dac_fix = 1,
14861 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14862 .adc_nids = alc861_adc_nids,
14863 .input_mux = &alc861_capture_source,
14867 /* Pin config fixes */
14868 enum {
14869 PINFIX_FSC_AMILO_PI1505,
14872 static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
14873 { 0x0b, 0x0221101f }, /* HP */
14874 { 0x0f, 0x90170310 }, /* speaker */
14878 static const struct alc_fixup alc861_fixups[] = {
14879 [PINFIX_FSC_AMILO_PI1505] = {
14880 .pins = alc861_fsc_amilo_pi1505_pinfix
14884 static struct snd_pci_quirk alc861_fixup_tbl[] = {
14885 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
14889 static int patch_alc861(struct hda_codec *codec)
14891 struct alc_spec *spec;
14892 int board_config;
14893 int err;
14895 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14896 if (spec == NULL)
14897 return -ENOMEM;
14899 codec->spec = spec;
14901 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14902 alc861_models,
14903 alc861_cfg_tbl);
14905 if (board_config < 0) {
14906 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14907 codec->chip_name);
14908 board_config = ALC861_AUTO;
14911 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
14913 if (board_config == ALC861_AUTO) {
14914 /* automatic parse from the BIOS config */
14915 err = alc861_parse_auto_config(codec);
14916 if (err < 0) {
14917 alc_free(codec);
14918 return err;
14919 } else if (!err) {
14920 printk(KERN_INFO
14921 "hda_codec: Cannot set up configuration "
14922 "from BIOS. Using base mode...\n");
14923 board_config = ALC861_3ST_DIG;
14927 err = snd_hda_attach_beep_device(codec, 0x23);
14928 if (err < 0) {
14929 alc_free(codec);
14930 return err;
14933 if (board_config != ALC861_AUTO)
14934 setup_preset(codec, &alc861_presets[board_config]);
14936 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14937 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14939 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14940 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14942 if (!spec->cap_mixer)
14943 set_capture_mixer(codec);
14944 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14946 spec->vmaster_nid = 0x03;
14948 codec->patch_ops = alc_patch_ops;
14949 if (board_config == ALC861_AUTO)
14950 spec->init_hook = alc861_auto_init;
14951 #ifdef CONFIG_SND_HDA_POWER_SAVE
14952 if (!spec->loopback.amplist)
14953 spec->loopback.amplist = alc861_loopbacks;
14954 #endif
14955 codec->proc_widget_hook = print_realtek_coef;
14957 return 0;
14961 * ALC861-VD support
14963 * Based on ALC882
14965 * In addition, an independent DAC
14967 #define ALC861VD_DIGOUT_NID 0x06
14969 static hda_nid_t alc861vd_dac_nids[4] = {
14970 /* front, surr, clfe, side surr */
14971 0x02, 0x03, 0x04, 0x05
14974 /* dac_nids for ALC660vd are in a different order - according to
14975 * Realtek's driver.
14976 * This should probably result in a different mixer for 6stack models
14977 * of ALC660vd codecs, but for now there is only 3stack mixer
14978 * - and it is the same as in 861vd.
14979 * adc_nids in ALC660vd are (is) the same as in 861vd
14981 static hda_nid_t alc660vd_dac_nids[3] = {
14982 /* front, rear, clfe, rear_surr */
14983 0x02, 0x04, 0x03
14986 static hda_nid_t alc861vd_adc_nids[1] = {
14987 /* ADC0 */
14988 0x09,
14991 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14993 /* input MUX */
14994 /* FIXME: should be a matrix-type input source selection */
14995 static struct hda_input_mux alc861vd_capture_source = {
14996 .num_items = 4,
14997 .items = {
14998 { "Mic", 0x0 },
14999 { "Front Mic", 0x1 },
15000 { "Line", 0x2 },
15001 { "CD", 0x4 },
15005 static struct hda_input_mux alc861vd_dallas_capture_source = {
15006 .num_items = 2,
15007 .items = {
15008 { "Ext Mic", 0x0 },
15009 { "Int Mic", 0x1 },
15013 static struct hda_input_mux alc861vd_hp_capture_source = {
15014 .num_items = 2,
15015 .items = {
15016 { "Front Mic", 0x0 },
15017 { "ATAPI Mic", 0x1 },
15022 * 2ch mode
15024 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15025 { 2, NULL }
15029 * 6ch mode
15031 static struct hda_verb alc861vd_6stack_ch6_init[] = {
15032 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15033 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15034 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15035 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15036 { } /* end */
15040 * 8ch mode
15042 static struct hda_verb alc861vd_6stack_ch8_init[] = {
15043 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15044 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15045 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15046 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15047 { } /* end */
15050 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15051 { 6, alc861vd_6stack_ch6_init },
15052 { 8, alc861vd_6stack_ch8_init },
15055 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15057 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15058 .name = "Channel Mode",
15059 .info = alc_ch_mode_info,
15060 .get = alc_ch_mode_get,
15061 .put = alc_ch_mode_put,
15063 { } /* end */
15066 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15067 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15069 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15070 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15071 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15073 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15074 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15076 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15077 HDA_OUTPUT),
15078 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15079 HDA_OUTPUT),
15080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15081 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15083 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15084 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15086 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15088 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15092 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15093 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15094 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15096 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15097 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15102 { } /* end */
15105 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15106 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15107 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15111 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15115 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15119 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15120 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15125 { } /* end */
15128 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15129 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15130 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15131 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15133 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15135 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15139 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15140 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15141 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15143 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15144 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15146 { } /* end */
15149 /* Pin assignment: Speaker=0x14, HP = 0x15,
15150 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
15152 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
15153 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15154 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
15155 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15156 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15157 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15158 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15159 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15160 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15161 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15162 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15163 { } /* end */
15166 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
15167 * Front Mic=0x18, ATAPI Mic = 0x19,
15169 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15170 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15171 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15172 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15173 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15174 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15175 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15176 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15177 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15179 { } /* end */
15183 * generic initialization of ADC, input mixers and output mixers
15185 static struct hda_verb alc861vd_volume_init_verbs[] = {
15187 * Unmute ADC0 and set the default input to mic-in
15189 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15190 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15192 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15193 * the analog-loopback mixer widget
15195 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15197 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15198 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15199 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15200 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15202 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
15203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15204 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15205 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15209 * Set up output mixers (0x02 - 0x05)
15211 /* set vol=0 to output mixers */
15212 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15213 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15214 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15215 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15217 /* set up input amps for analog loopback */
15218 /* Amp Indices: DAC = 0, mixer = 1 */
15219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15223 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15225 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15226 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15232 * 3-stack pin configuration:
15233 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15235 static struct hda_verb alc861vd_3stack_init_verbs[] = {
15237 * Set pin mode and muting
15239 /* set front pin widgets 0x14 for output */
15240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15241 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15242 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15244 /* Mic (rear) pin: input vref at 80% */
15245 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15246 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15247 /* Front Mic pin: input vref at 80% */
15248 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15249 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15250 /* Line In pin: input */
15251 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15252 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15253 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15254 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15255 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15256 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15257 /* CD pin widget for input */
15258 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15264 * 6-stack pin configuration:
15266 static struct hda_verb alc861vd_6stack_init_verbs[] = {
15268 * Set pin mode and muting
15270 /* set front pin widgets 0x14 for output */
15271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15275 /* Rear Pin: output 1 (0x0d) */
15276 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15277 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15278 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15279 /* CLFE Pin: output 2 (0x0e) */
15280 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15282 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15283 /* Side Pin: output 3 (0x0f) */
15284 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15285 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15286 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15288 /* Mic (rear) pin: input vref at 80% */
15289 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15290 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15291 /* Front Mic pin: input vref at 80% */
15292 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15293 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15294 /* Line In pin: input */
15295 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15296 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15297 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15298 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15299 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15300 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15301 /* CD pin widget for input */
15302 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15307 static struct hda_verb alc861vd_eapd_verbs[] = {
15308 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15312 static struct hda_verb alc660vd_eapd_verbs[] = {
15313 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15314 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15318 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15319 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15320 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15321 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15323 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15327 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15329 unsigned int present;
15330 unsigned char bits;
15332 present = snd_hda_jack_detect(codec, 0x18);
15333 bits = present ? HDA_AMP_MUTE : 0;
15335 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15336 HDA_AMP_MUTE, bits);
15339 static void alc861vd_lenovo_setup(struct hda_codec *codec)
15341 struct alc_spec *spec = codec->spec;
15342 spec->autocfg.hp_pins[0] = 0x1b;
15343 spec->autocfg.speaker_pins[0] = 0x14;
15346 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15348 alc_automute_amp(codec);
15349 alc861vd_lenovo_mic_automute(codec);
15352 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15353 unsigned int res)
15355 switch (res >> 26) {
15356 case ALC880_MIC_EVENT:
15357 alc861vd_lenovo_mic_automute(codec);
15358 break;
15359 default:
15360 alc_automute_amp_unsol_event(codec, res);
15361 break;
15365 static struct hda_verb alc861vd_dallas_verbs[] = {
15366 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15367 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15368 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15369 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15377 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15384 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15385 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15386 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15387 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15389 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15390 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15391 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15394 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15395 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15396 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15398 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15399 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15403 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15404 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15405 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15407 { } /* end */
15410 /* toggle speaker-output according to the hp-jack state */
15411 static void alc861vd_dallas_setup(struct hda_codec *codec)
15413 struct alc_spec *spec = codec->spec;
15415 spec->autocfg.hp_pins[0] = 0x15;
15416 spec->autocfg.speaker_pins[0] = 0x14;
15419 #ifdef CONFIG_SND_HDA_POWER_SAVE
15420 #define alc861vd_loopbacks alc880_loopbacks
15421 #endif
15423 /* pcm configuration: identical with ALC880 */
15424 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15425 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15426 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15427 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15430 * configuration and preset
15432 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15433 [ALC660VD_3ST] = "3stack-660",
15434 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15435 [ALC660VD_ASUS_V1S] = "asus-v1s",
15436 [ALC861VD_3ST] = "3stack",
15437 [ALC861VD_3ST_DIG] = "3stack-digout",
15438 [ALC861VD_6ST_DIG] = "6stack-digout",
15439 [ALC861VD_LENOVO] = "lenovo",
15440 [ALC861VD_DALLAS] = "dallas",
15441 [ALC861VD_HP] = "hp",
15442 [ALC861VD_AUTO] = "auto",
15445 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15446 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15447 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15448 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15449 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15450 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15451 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15452 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15453 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15454 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15455 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
15456 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15457 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15458 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15459 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15460 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15464 static struct alc_config_preset alc861vd_presets[] = {
15465 [ALC660VD_3ST] = {
15466 .mixers = { alc861vd_3st_mixer },
15467 .init_verbs = { alc861vd_volume_init_verbs,
15468 alc861vd_3stack_init_verbs },
15469 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15470 .dac_nids = alc660vd_dac_nids,
15471 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15472 .channel_mode = alc861vd_3stack_2ch_modes,
15473 .input_mux = &alc861vd_capture_source,
15475 [ALC660VD_3ST_DIG] = {
15476 .mixers = { alc861vd_3st_mixer },
15477 .init_verbs = { alc861vd_volume_init_verbs,
15478 alc861vd_3stack_init_verbs },
15479 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15480 .dac_nids = alc660vd_dac_nids,
15481 .dig_out_nid = ALC861VD_DIGOUT_NID,
15482 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15483 .channel_mode = alc861vd_3stack_2ch_modes,
15484 .input_mux = &alc861vd_capture_source,
15486 [ALC861VD_3ST] = {
15487 .mixers = { alc861vd_3st_mixer },
15488 .init_verbs = { alc861vd_volume_init_verbs,
15489 alc861vd_3stack_init_verbs },
15490 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15491 .dac_nids = alc861vd_dac_nids,
15492 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15493 .channel_mode = alc861vd_3stack_2ch_modes,
15494 .input_mux = &alc861vd_capture_source,
15496 [ALC861VD_3ST_DIG] = {
15497 .mixers = { alc861vd_3st_mixer },
15498 .init_verbs = { alc861vd_volume_init_verbs,
15499 alc861vd_3stack_init_verbs },
15500 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15501 .dac_nids = alc861vd_dac_nids,
15502 .dig_out_nid = ALC861VD_DIGOUT_NID,
15503 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15504 .channel_mode = alc861vd_3stack_2ch_modes,
15505 .input_mux = &alc861vd_capture_source,
15507 [ALC861VD_6ST_DIG] = {
15508 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15509 .init_verbs = { alc861vd_volume_init_verbs,
15510 alc861vd_6stack_init_verbs },
15511 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15512 .dac_nids = alc861vd_dac_nids,
15513 .dig_out_nid = ALC861VD_DIGOUT_NID,
15514 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15515 .channel_mode = alc861vd_6stack_modes,
15516 .input_mux = &alc861vd_capture_source,
15518 [ALC861VD_LENOVO] = {
15519 .mixers = { alc861vd_lenovo_mixer },
15520 .init_verbs = { alc861vd_volume_init_verbs,
15521 alc861vd_3stack_init_verbs,
15522 alc861vd_eapd_verbs,
15523 alc861vd_lenovo_unsol_verbs },
15524 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15525 .dac_nids = alc660vd_dac_nids,
15526 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15527 .channel_mode = alc861vd_3stack_2ch_modes,
15528 .input_mux = &alc861vd_capture_source,
15529 .unsol_event = alc861vd_lenovo_unsol_event,
15530 .setup = alc861vd_lenovo_setup,
15531 .init_hook = alc861vd_lenovo_init_hook,
15533 [ALC861VD_DALLAS] = {
15534 .mixers = { alc861vd_dallas_mixer },
15535 .init_verbs = { alc861vd_dallas_verbs },
15536 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15537 .dac_nids = alc861vd_dac_nids,
15538 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15539 .channel_mode = alc861vd_3stack_2ch_modes,
15540 .input_mux = &alc861vd_dallas_capture_source,
15541 .unsol_event = alc_automute_amp_unsol_event,
15542 .setup = alc861vd_dallas_setup,
15543 .init_hook = alc_automute_amp,
15545 [ALC861VD_HP] = {
15546 .mixers = { alc861vd_hp_mixer },
15547 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15548 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15549 .dac_nids = alc861vd_dac_nids,
15550 .dig_out_nid = ALC861VD_DIGOUT_NID,
15551 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15552 .channel_mode = alc861vd_3stack_2ch_modes,
15553 .input_mux = &alc861vd_hp_capture_source,
15554 .unsol_event = alc_automute_amp_unsol_event,
15555 .setup = alc861vd_dallas_setup,
15556 .init_hook = alc_automute_amp,
15558 [ALC660VD_ASUS_V1S] = {
15559 .mixers = { alc861vd_lenovo_mixer },
15560 .init_verbs = { alc861vd_volume_init_verbs,
15561 alc861vd_3stack_init_verbs,
15562 alc861vd_eapd_verbs,
15563 alc861vd_lenovo_unsol_verbs },
15564 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15565 .dac_nids = alc660vd_dac_nids,
15566 .dig_out_nid = ALC861VD_DIGOUT_NID,
15567 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15568 .channel_mode = alc861vd_3stack_2ch_modes,
15569 .input_mux = &alc861vd_capture_source,
15570 .unsol_event = alc861vd_lenovo_unsol_event,
15571 .setup = alc861vd_lenovo_setup,
15572 .init_hook = alc861vd_lenovo_init_hook,
15577 * BIOS auto configuration
15579 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15580 const struct auto_pin_cfg *cfg)
15582 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0);
15586 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15587 hda_nid_t nid, int pin_type, int dac_idx)
15589 alc_set_pin_output(codec, nid, pin_type);
15592 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15594 struct alc_spec *spec = codec->spec;
15595 int i;
15597 for (i = 0; i <= HDA_SIDE; i++) {
15598 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15599 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15600 if (nid)
15601 alc861vd_auto_set_output_and_unmute(codec, nid,
15602 pin_type, i);
15607 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15609 struct alc_spec *spec = codec->spec;
15610 hda_nid_t pin;
15612 pin = spec->autocfg.hp_pins[0];
15613 if (pin) /* connect to front and use dac 0 */
15614 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15615 pin = spec->autocfg.speaker_pins[0];
15616 if (pin)
15617 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15620 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15622 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15624 struct alc_spec *spec = codec->spec;
15625 int i;
15627 for (i = 0; i < AUTO_PIN_LAST; i++) {
15628 hda_nid_t nid = spec->autocfg.input_pins[i];
15629 if (alc_is_input_pin(codec, nid)) {
15630 alc_set_input_pin(codec, nid, i);
15631 if (nid != ALC861VD_PIN_CD_NID &&
15632 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15633 snd_hda_codec_write(codec, nid, 0,
15634 AC_VERB_SET_AMP_GAIN_MUTE,
15635 AMP_OUT_MUTE);
15640 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
15642 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15643 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15645 /* add playback controls from the parsed DAC table */
15646 /* Based on ALC880 version. But ALC861VD has separate,
15647 * different NIDs for mute/unmute switch and volume control */
15648 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15649 const struct auto_pin_cfg *cfg)
15651 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15652 hda_nid_t nid_v, nid_s;
15653 int i, err;
15655 for (i = 0; i < cfg->line_outs; i++) {
15656 if (!spec->multiout.dac_nids[i])
15657 continue;
15658 nid_v = alc861vd_idx_to_mixer_vol(
15659 alc880_dac_to_idx(
15660 spec->multiout.dac_nids[i]));
15661 nid_s = alc861vd_idx_to_mixer_switch(
15662 alc880_dac_to_idx(
15663 spec->multiout.dac_nids[i]));
15665 if (i == 2) {
15666 /* Center/LFE */
15667 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15668 "Center",
15669 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15670 HDA_OUTPUT));
15671 if (err < 0)
15672 return err;
15673 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
15674 "LFE",
15675 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15676 HDA_OUTPUT));
15677 if (err < 0)
15678 return err;
15679 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15680 "Center",
15681 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15682 HDA_INPUT));
15683 if (err < 0)
15684 return err;
15685 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
15686 "LFE",
15687 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15688 HDA_INPUT));
15689 if (err < 0)
15690 return err;
15691 } else {
15692 const char *pfx;
15693 if (cfg->line_outs == 1 &&
15694 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15695 if (!cfg->hp_pins)
15696 pfx = "Speaker";
15697 else
15698 pfx = "PCM";
15699 } else
15700 pfx = chname[i];
15701 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15702 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15703 HDA_OUTPUT));
15704 if (err < 0)
15705 return err;
15706 if (cfg->line_outs == 1 &&
15707 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15708 pfx = "Speaker";
15709 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15710 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15711 HDA_INPUT));
15712 if (err < 0)
15713 return err;
15716 return 0;
15719 /* add playback controls for speaker and HP outputs */
15720 /* Based on ALC880 version. But ALC861VD has separate,
15721 * different NIDs for mute/unmute switch and volume control */
15722 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15723 hda_nid_t pin, const char *pfx)
15725 hda_nid_t nid_v, nid_s;
15726 int err;
15728 if (!pin)
15729 return 0;
15731 if (alc880_is_fixed_pin(pin)) {
15732 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15733 /* specify the DAC as the extra output */
15734 if (!spec->multiout.hp_nid)
15735 spec->multiout.hp_nid = nid_v;
15736 else
15737 spec->multiout.extra_out_nid[0] = nid_v;
15738 /* control HP volume/switch on the output mixer amp */
15739 nid_v = alc861vd_idx_to_mixer_vol(
15740 alc880_fixed_pin_idx(pin));
15741 nid_s = alc861vd_idx_to_mixer_switch(
15742 alc880_fixed_pin_idx(pin));
15744 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
15745 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15746 if (err < 0)
15747 return err;
15748 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
15749 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15750 if (err < 0)
15751 return err;
15752 } else if (alc880_is_multi_pin(pin)) {
15753 /* set manual connection */
15754 /* we have only a switch on HP-out PIN */
15755 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
15756 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15757 if (err < 0)
15758 return err;
15760 return 0;
15763 /* parse the BIOS configuration and set up the alc_spec
15764 * return 1 if successful, 0 if the proper config is not found,
15765 * or a negative error code
15766 * Based on ALC880 version - had to change it to override
15767 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15768 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15770 struct alc_spec *spec = codec->spec;
15771 int err;
15772 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15774 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15775 alc861vd_ignore);
15776 if (err < 0)
15777 return err;
15778 if (!spec->autocfg.line_outs)
15779 return 0; /* can't find valid BIOS pin config */
15781 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15782 if (err < 0)
15783 return err;
15784 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15785 if (err < 0)
15786 return err;
15787 err = alc861vd_auto_create_extra_out(spec,
15788 spec->autocfg.speaker_pins[0],
15789 "Speaker");
15790 if (err < 0)
15791 return err;
15792 err = alc861vd_auto_create_extra_out(spec,
15793 spec->autocfg.hp_pins[0],
15794 "Headphone");
15795 if (err < 0)
15796 return err;
15797 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15798 if (err < 0)
15799 return err;
15801 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15803 if (spec->autocfg.dig_outs)
15804 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15806 if (spec->kctls.list)
15807 add_mixer(spec, spec->kctls.list);
15809 add_verb(spec, alc861vd_volume_init_verbs);
15811 spec->num_mux_defs = 1;
15812 spec->input_mux = &spec->private_imux[0];
15814 err = alc_auto_add_mic_boost(codec);
15815 if (err < 0)
15816 return err;
15818 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15820 return 1;
15823 /* additional initialization for auto-configuration model */
15824 static void alc861vd_auto_init(struct hda_codec *codec)
15826 struct alc_spec *spec = codec->spec;
15827 alc861vd_auto_init_multi_out(codec);
15828 alc861vd_auto_init_hp_out(codec);
15829 alc861vd_auto_init_analog_input(codec);
15830 alc861vd_auto_init_input_src(codec);
15831 if (spec->unsol_event)
15832 alc_inithook(codec);
15835 enum {
15836 ALC660VD_FIX_ASUS_GPIO1
15839 /* reset GPIO1 */
15840 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15841 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15842 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15843 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15847 static const struct alc_fixup alc861vd_fixups[] = {
15848 [ALC660VD_FIX_ASUS_GPIO1] = {
15849 .verbs = alc660vd_fix_asus_gpio1_verbs,
15853 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15854 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15858 static int patch_alc861vd(struct hda_codec *codec)
15860 struct alc_spec *spec;
15861 int err, board_config;
15863 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15864 if (spec == NULL)
15865 return -ENOMEM;
15867 codec->spec = spec;
15869 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15870 alc861vd_models,
15871 alc861vd_cfg_tbl);
15873 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15874 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15875 codec->chip_name);
15876 board_config = ALC861VD_AUTO;
15879 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15881 if (board_config == ALC861VD_AUTO) {
15882 /* automatic parse from the BIOS config */
15883 err = alc861vd_parse_auto_config(codec);
15884 if (err < 0) {
15885 alc_free(codec);
15886 return err;
15887 } else if (!err) {
15888 printk(KERN_INFO
15889 "hda_codec: Cannot set up configuration "
15890 "from BIOS. Using base mode...\n");
15891 board_config = ALC861VD_3ST;
15895 err = snd_hda_attach_beep_device(codec, 0x23);
15896 if (err < 0) {
15897 alc_free(codec);
15898 return err;
15901 if (board_config != ALC861VD_AUTO)
15902 setup_preset(codec, &alc861vd_presets[board_config]);
15904 if (codec->vendor_id == 0x10ec0660) {
15905 /* always turn on EAPD */
15906 add_verb(spec, alc660vd_eapd_verbs);
15909 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15910 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15912 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15913 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15915 if (!spec->adc_nids) {
15916 spec->adc_nids = alc861vd_adc_nids;
15917 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15919 if (!spec->capsrc_nids)
15920 spec->capsrc_nids = alc861vd_capsrc_nids;
15922 set_capture_mixer(codec);
15923 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15925 spec->vmaster_nid = 0x02;
15927 codec->patch_ops = alc_patch_ops;
15929 if (board_config == ALC861VD_AUTO)
15930 spec->init_hook = alc861vd_auto_init;
15931 #ifdef CONFIG_SND_HDA_POWER_SAVE
15932 if (!spec->loopback.amplist)
15933 spec->loopback.amplist = alc861vd_loopbacks;
15934 #endif
15935 codec->proc_widget_hook = print_realtek_coef;
15937 return 0;
15941 * ALC662 support
15943 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15944 * configuration. Each pin widget can choose any input DACs and a mixer.
15945 * Each ADC is connected from a mixer of all inputs. This makes possible
15946 * 6-channel independent captures.
15948 * In addition, an independent DAC for the multi-playback (not used in this
15949 * driver yet).
15951 #define ALC662_DIGOUT_NID 0x06
15952 #define ALC662_DIGIN_NID 0x0a
15954 static hda_nid_t alc662_dac_nids[4] = {
15955 /* front, rear, clfe, rear_surr */
15956 0x02, 0x03, 0x04
15959 static hda_nid_t alc272_dac_nids[2] = {
15960 0x02, 0x03
15963 static hda_nid_t alc662_adc_nids[2] = {
15964 /* ADC1-2 */
15965 0x09, 0x08
15968 static hda_nid_t alc272_adc_nids[1] = {
15969 /* ADC1-2 */
15970 0x08,
15973 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15974 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15977 /* input MUX */
15978 /* FIXME: should be a matrix-type input source selection */
15979 static struct hda_input_mux alc662_capture_source = {
15980 .num_items = 4,
15981 .items = {
15982 { "Mic", 0x0 },
15983 { "Front Mic", 0x1 },
15984 { "Line", 0x2 },
15985 { "CD", 0x4 },
15989 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15990 .num_items = 2,
15991 .items = {
15992 { "Mic", 0x1 },
15993 { "Line", 0x2 },
15997 static struct hda_input_mux alc663_capture_source = {
15998 .num_items = 3,
15999 .items = {
16000 { "Mic", 0x0 },
16001 { "Front Mic", 0x1 },
16002 { "Line", 0x2 },
16006 #if 0 /* set to 1 for testing other input sources below */
16007 static struct hda_input_mux alc272_nc10_capture_source = {
16008 .num_items = 16,
16009 .items = {
16010 { "Autoselect Mic", 0x0 },
16011 { "Internal Mic", 0x1 },
16012 { "In-0x02", 0x2 },
16013 { "In-0x03", 0x3 },
16014 { "In-0x04", 0x4 },
16015 { "In-0x05", 0x5 },
16016 { "In-0x06", 0x6 },
16017 { "In-0x07", 0x7 },
16018 { "In-0x08", 0x8 },
16019 { "In-0x09", 0x9 },
16020 { "In-0x0a", 0x0a },
16021 { "In-0x0b", 0x0b },
16022 { "In-0x0c", 0x0c },
16023 { "In-0x0d", 0x0d },
16024 { "In-0x0e", 0x0e },
16025 { "In-0x0f", 0x0f },
16028 #endif
16031 * 2ch mode
16033 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16034 { 2, NULL }
16038 * 2ch mode
16040 static struct hda_verb alc662_3ST_ch2_init[] = {
16041 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16042 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16043 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16044 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16045 { } /* end */
16049 * 6ch mode
16051 static struct hda_verb alc662_3ST_ch6_init[] = {
16052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16058 { } /* end */
16061 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16062 { 2, alc662_3ST_ch2_init },
16063 { 6, alc662_3ST_ch6_init },
16067 * 2ch mode
16069 static struct hda_verb alc662_sixstack_ch6_init[] = {
16070 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16071 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16072 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16073 { } /* end */
16077 * 6ch mode
16079 static struct hda_verb alc662_sixstack_ch8_init[] = {
16080 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16081 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16082 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16083 { } /* end */
16086 static struct hda_channel_mode alc662_5stack_modes[2] = {
16087 { 2, alc662_sixstack_ch6_init },
16088 { 6, alc662_sixstack_ch8_init },
16091 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16092 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16095 static struct snd_kcontrol_new alc662_base_mixer[] = {
16096 /* output mixer control */
16097 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16098 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16099 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16100 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16101 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16102 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16103 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16104 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16105 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16107 /*Input mixer control */
16108 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16109 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16110 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16111 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16112 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16113 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16116 { } /* end */
16119 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16120 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16121 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16128 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16129 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16130 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16131 { } /* end */
16134 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16135 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16136 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16137 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16138 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16139 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16140 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16141 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16142 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16143 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16150 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16151 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16152 { } /* end */
16155 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16156 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16157 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
16158 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16159 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
16160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16161 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16162 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16163 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16165 { } /* end */
16168 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
16169 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16170 ALC262_HIPPO_MASTER_SWITCH,
16172 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16173 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16174 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16176 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16177 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16178 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16179 { } /* end */
16182 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
16183 ALC262_HIPPO_MASTER_SWITCH,
16184 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16185 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16186 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16187 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16188 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16193 { } /* end */
16196 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16197 .ops = &snd_hda_bind_vol,
16198 .values = {
16199 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16200 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16205 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16206 .ops = &snd_hda_bind_sw,
16207 .values = {
16208 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16209 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16214 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
16215 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16216 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16219 { } /* end */
16222 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16223 .ops = &snd_hda_bind_sw,
16224 .values = {
16225 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16226 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16227 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16232 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16233 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16234 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16237 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16238 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16240 { } /* end */
16243 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16244 .ops = &snd_hda_bind_sw,
16245 .values = {
16246 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16247 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16248 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16253 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16254 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16255 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16258 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16259 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16260 { } /* end */
16263 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
16264 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16265 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16267 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16268 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16269 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16270 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16271 { } /* end */
16274 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16275 .ops = &snd_hda_bind_vol,
16276 .values = {
16277 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16278 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16283 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16284 .ops = &snd_hda_bind_sw,
16285 .values = {
16286 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16287 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16292 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16293 HDA_BIND_VOL("Master Playback Volume",
16294 &alc663_asus_two_bind_master_vol),
16295 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16298 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16299 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16300 { } /* end */
16303 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16304 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16305 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16306 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16307 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16310 { } /* end */
16313 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16314 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16315 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16316 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16317 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16318 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16322 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16323 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16324 { } /* end */
16327 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16328 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16329 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16330 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16334 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16335 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16336 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16337 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16338 { } /* end */
16341 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16342 .ops = &snd_hda_bind_sw,
16343 .values = {
16344 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16345 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16346 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16347 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16348 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16353 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16354 .ops = &snd_hda_bind_sw,
16355 .values = {
16356 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16357 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16362 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16363 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16364 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16365 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16366 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16367 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16368 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16369 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16372 { } /* end */
16375 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16376 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16377 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16378 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16379 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16380 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16383 { } /* end */
16387 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16389 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16390 .name = "Channel Mode",
16391 .info = alc_ch_mode_info,
16392 .get = alc_ch_mode_get,
16393 .put = alc_ch_mode_put,
16395 { } /* end */
16398 static struct hda_verb alc662_init_verbs[] = {
16399 /* ADC: mute amp left and right */
16400 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16401 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16402 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16408 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16413 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16415 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16417 /* Front Pin: output 0 (0x0c) */
16418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16421 /* Rear Pin: output 1 (0x0d) */
16422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16423 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16425 /* CLFE Pin: output 2 (0x0e) */
16426 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16427 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16429 /* Mic (rear) pin: input vref at 80% */
16430 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16431 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16432 /* Front Mic pin: input vref at 80% */
16433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16434 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16435 /* Line In pin: input */
16436 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16437 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16438 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16442 /* CD pin widget for input */
16443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16445 /* FIXME: use matrix-type input source selection */
16446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16447 /* Input mixer */
16448 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16449 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16451 /* always trun on EAPD */
16452 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16453 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16458 static struct hda_verb alc662_sue_init_verbs[] = {
16459 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16460 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16464 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16466 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16470 /* Set Unsolicited Event*/
16471 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16472 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16473 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16478 * generic initialization of ADC, input mixers and output mixers
16480 static struct hda_verb alc662_auto_init_verbs[] = {
16482 * Unmute ADC and set the default input to mic-in
16484 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16487 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16488 * mixer widget
16489 * Note: PASD motherboards uses the Line In 2 as the input for front
16490 * panel mic (mic 2)
16492 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16494 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16495 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16496 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16497 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16500 * Set up output mixers (0x0c - 0x0f)
16502 /* set vol=0 to output mixers */
16503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16507 /* set up input amps for analog loopback */
16508 /* Amp Indices: DAC = 0, mixer = 1 */
16509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16511 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16513 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16517 /* FIXME: use matrix-type input source selection */
16518 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16519 /* Input mixer */
16520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16525 /* additional verbs for ALC663 */
16526 static struct hda_verb alc663_auto_init_verbs[] = {
16527 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16528 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16532 static struct hda_verb alc663_m51va_init_verbs[] = {
16533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16534 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16535 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16536 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16537 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16540 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16541 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16545 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16546 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16547 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16548 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16549 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16550 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16551 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16552 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16556 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16557 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16560 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16561 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16562 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16563 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16564 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16568 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16571 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16574 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16579 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16580 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16581 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16582 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16583 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16586 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16590 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16591 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16595 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16596 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16597 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16598 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16599 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16602 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16603 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16604 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16605 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16606 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16607 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16611 static struct hda_verb alc663_g71v_init_verbs[] = {
16612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16613 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16614 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16616 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16617 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16618 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16620 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16621 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16626 static struct hda_verb alc663_g50v_init_verbs[] = {
16627 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16628 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16629 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16631 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16632 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16636 static struct hda_verb alc662_ecs_init_verbs[] = {
16637 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16638 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16639 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16640 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16644 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16645 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16646 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16649 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16650 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16651 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16652 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16653 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16654 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16655 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16659 static struct hda_verb alc272_dell_init_verbs[] = {
16660 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16661 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16663 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16664 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16665 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16666 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16667 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16669 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16670 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16674 static struct hda_verb alc663_mode7_init_verbs[] = {
16675 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16676 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16677 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16678 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16679 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16680 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16681 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
16682 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16683 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16684 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16686 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16687 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16688 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16689 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16693 static struct hda_verb alc663_mode8_init_verbs[] = {
16694 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16695 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16698 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16699 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16701 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16702 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16703 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16704 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16705 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16706 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16707 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16708 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16709 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16713 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16714 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16715 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16716 { } /* end */
16719 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16720 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16721 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16722 { } /* end */
16725 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16727 unsigned int present;
16728 unsigned char bits;
16730 present = snd_hda_jack_detect(codec, 0x14);
16731 bits = present ? HDA_AMP_MUTE : 0;
16733 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16734 HDA_AMP_MUTE, bits);
16737 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16739 unsigned int present;
16740 unsigned char bits;
16742 present = snd_hda_jack_detect(codec, 0x1b);
16743 bits = present ? HDA_AMP_MUTE : 0;
16745 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16746 HDA_AMP_MUTE, bits);
16747 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16748 HDA_AMP_MUTE, bits);
16751 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16752 unsigned int res)
16754 if ((res >> 26) == ALC880_HP_EVENT)
16755 alc662_lenovo_101e_all_automute(codec);
16756 if ((res >> 26) == ALC880_FRONT_EVENT)
16757 alc662_lenovo_101e_ispeaker_automute(codec);
16760 /* unsolicited event for HP jack sensing */
16761 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16762 unsigned int res)
16764 if ((res >> 26) == ALC880_MIC_EVENT)
16765 alc_mic_automute(codec);
16766 else
16767 alc262_hippo_unsol_event(codec, res);
16770 static void alc662_eeepc_setup(struct hda_codec *codec)
16772 struct alc_spec *spec = codec->spec;
16774 alc262_hippo1_setup(codec);
16775 spec->ext_mic.pin = 0x18;
16776 spec->ext_mic.mux_idx = 0;
16777 spec->int_mic.pin = 0x19;
16778 spec->int_mic.mux_idx = 1;
16779 spec->auto_mic = 1;
16782 static void alc662_eeepc_inithook(struct hda_codec *codec)
16784 alc262_hippo_automute(codec);
16785 alc_mic_automute(codec);
16788 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16790 struct alc_spec *spec = codec->spec;
16792 spec->autocfg.hp_pins[0] = 0x14;
16793 spec->autocfg.speaker_pins[0] = 0x1b;
16796 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16798 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16800 unsigned int present;
16801 unsigned char bits;
16803 present = snd_hda_jack_detect(codec, 0x21);
16804 bits = present ? HDA_AMP_MUTE : 0;
16805 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16806 AMP_IN_MUTE(0), bits);
16807 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16808 AMP_IN_MUTE(0), bits);
16811 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16813 unsigned int present;
16814 unsigned char bits;
16816 present = snd_hda_jack_detect(codec, 0x21);
16817 bits = present ? HDA_AMP_MUTE : 0;
16818 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16819 AMP_IN_MUTE(0), bits);
16820 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16821 AMP_IN_MUTE(0), bits);
16822 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16823 AMP_IN_MUTE(0), bits);
16824 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16825 AMP_IN_MUTE(0), bits);
16828 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16830 unsigned int present;
16831 unsigned char bits;
16833 present = snd_hda_jack_detect(codec, 0x15);
16834 bits = present ? HDA_AMP_MUTE : 0;
16835 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16836 AMP_IN_MUTE(0), bits);
16837 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16838 AMP_IN_MUTE(0), bits);
16839 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16840 AMP_IN_MUTE(0), bits);
16841 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16842 AMP_IN_MUTE(0), bits);
16845 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16847 unsigned int present;
16848 unsigned char bits;
16850 present = snd_hda_jack_detect(codec, 0x1b);
16851 bits = present ? 0 : PIN_OUT;
16852 snd_hda_codec_write(codec, 0x14, 0,
16853 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16856 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16858 unsigned int present1, present2;
16860 present1 = snd_hda_jack_detect(codec, 0x21);
16861 present2 = snd_hda_jack_detect(codec, 0x15);
16863 if (present1 || present2) {
16864 snd_hda_codec_write_cache(codec, 0x14, 0,
16865 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16866 } else {
16867 snd_hda_codec_write_cache(codec, 0x14, 0,
16868 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16872 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16874 unsigned int present1, present2;
16876 present1 = snd_hda_jack_detect(codec, 0x1b);
16877 present2 = snd_hda_jack_detect(codec, 0x15);
16879 if (present1 || present2) {
16880 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16881 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16882 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16883 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16884 } else {
16885 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16886 AMP_IN_MUTE(0), 0);
16887 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16888 AMP_IN_MUTE(0), 0);
16892 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
16894 unsigned int present1, present2;
16896 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16897 AC_VERB_GET_PIN_SENSE, 0)
16898 & AC_PINSENSE_PRESENCE;
16899 present2 = snd_hda_codec_read(codec, 0x21, 0,
16900 AC_VERB_GET_PIN_SENSE, 0)
16901 & AC_PINSENSE_PRESENCE;
16903 if (present1 || present2) {
16904 snd_hda_codec_write_cache(codec, 0x14, 0,
16905 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16906 snd_hda_codec_write_cache(codec, 0x17, 0,
16907 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16908 } else {
16909 snd_hda_codec_write_cache(codec, 0x14, 0,
16910 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16911 snd_hda_codec_write_cache(codec, 0x17, 0,
16912 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16916 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
16918 unsigned int present1, present2;
16920 present1 = snd_hda_codec_read(codec, 0x21, 0,
16921 AC_VERB_GET_PIN_SENSE, 0)
16922 & AC_PINSENSE_PRESENCE;
16923 present2 = snd_hda_codec_read(codec, 0x15, 0,
16924 AC_VERB_GET_PIN_SENSE, 0)
16925 & AC_PINSENSE_PRESENCE;
16927 if (present1 || present2) {
16928 snd_hda_codec_write_cache(codec, 0x14, 0,
16929 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16930 snd_hda_codec_write_cache(codec, 0x17, 0,
16931 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16932 } else {
16933 snd_hda_codec_write_cache(codec, 0x14, 0,
16934 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16935 snd_hda_codec_write_cache(codec, 0x17, 0,
16936 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16940 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16941 unsigned int res)
16943 switch (res >> 26) {
16944 case ALC880_HP_EVENT:
16945 alc663_m51va_speaker_automute(codec);
16946 break;
16947 case ALC880_MIC_EVENT:
16948 alc_mic_automute(codec);
16949 break;
16953 static void alc663_m51va_setup(struct hda_codec *codec)
16955 struct alc_spec *spec = codec->spec;
16956 spec->ext_mic.pin = 0x18;
16957 spec->ext_mic.mux_idx = 0;
16958 spec->int_mic.pin = 0x12;
16959 spec->int_mic.mux_idx = 9;
16960 spec->auto_mic = 1;
16963 static void alc663_m51va_inithook(struct hda_codec *codec)
16965 alc663_m51va_speaker_automute(codec);
16966 alc_mic_automute(codec);
16969 /* ***************** Mode1 ******************************/
16970 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
16972 static void alc663_mode1_setup(struct hda_codec *codec)
16974 struct alc_spec *spec = codec->spec;
16975 spec->ext_mic.pin = 0x18;
16976 spec->ext_mic.mux_idx = 0;
16977 spec->int_mic.pin = 0x19;
16978 spec->int_mic.mux_idx = 1;
16979 spec->auto_mic = 1;
16982 #define alc663_mode1_inithook alc663_m51va_inithook
16984 /* ***************** Mode2 ******************************/
16985 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16986 unsigned int res)
16988 switch (res >> 26) {
16989 case ALC880_HP_EVENT:
16990 alc662_f5z_speaker_automute(codec);
16991 break;
16992 case ALC880_MIC_EVENT:
16993 alc_mic_automute(codec);
16994 break;
16998 #define alc662_mode2_setup alc663_mode1_setup
17000 static void alc662_mode2_inithook(struct hda_codec *codec)
17002 alc662_f5z_speaker_automute(codec);
17003 alc_mic_automute(codec);
17005 /* ***************** Mode3 ******************************/
17006 static void alc663_mode3_unsol_event(struct hda_codec *codec,
17007 unsigned int res)
17009 switch (res >> 26) {
17010 case ALC880_HP_EVENT:
17011 alc663_two_hp_m1_speaker_automute(codec);
17012 break;
17013 case ALC880_MIC_EVENT:
17014 alc_mic_automute(codec);
17015 break;
17019 #define alc663_mode3_setup alc663_mode1_setup
17021 static void alc663_mode3_inithook(struct hda_codec *codec)
17023 alc663_two_hp_m1_speaker_automute(codec);
17024 alc_mic_automute(codec);
17026 /* ***************** Mode4 ******************************/
17027 static void alc663_mode4_unsol_event(struct hda_codec *codec,
17028 unsigned int res)
17030 switch (res >> 26) {
17031 case ALC880_HP_EVENT:
17032 alc663_21jd_two_speaker_automute(codec);
17033 break;
17034 case ALC880_MIC_EVENT:
17035 alc_mic_automute(codec);
17036 break;
17040 #define alc663_mode4_setup alc663_mode1_setup
17042 static void alc663_mode4_inithook(struct hda_codec *codec)
17044 alc663_21jd_two_speaker_automute(codec);
17045 alc_mic_automute(codec);
17047 /* ***************** Mode5 ******************************/
17048 static void alc663_mode5_unsol_event(struct hda_codec *codec,
17049 unsigned int res)
17051 switch (res >> 26) {
17052 case ALC880_HP_EVENT:
17053 alc663_15jd_two_speaker_automute(codec);
17054 break;
17055 case ALC880_MIC_EVENT:
17056 alc_mic_automute(codec);
17057 break;
17061 #define alc663_mode5_setup alc663_mode1_setup
17063 static void alc663_mode5_inithook(struct hda_codec *codec)
17065 alc663_15jd_two_speaker_automute(codec);
17066 alc_mic_automute(codec);
17068 /* ***************** Mode6 ******************************/
17069 static void alc663_mode6_unsol_event(struct hda_codec *codec,
17070 unsigned int res)
17072 switch (res >> 26) {
17073 case ALC880_HP_EVENT:
17074 alc663_two_hp_m2_speaker_automute(codec);
17075 break;
17076 case ALC880_MIC_EVENT:
17077 alc_mic_automute(codec);
17078 break;
17082 #define alc663_mode6_setup alc663_mode1_setup
17084 static void alc663_mode6_inithook(struct hda_codec *codec)
17086 alc663_two_hp_m2_speaker_automute(codec);
17087 alc_mic_automute(codec);
17090 /* ***************** Mode7 ******************************/
17091 static void alc663_mode7_unsol_event(struct hda_codec *codec,
17092 unsigned int res)
17094 switch (res >> 26) {
17095 case ALC880_HP_EVENT:
17096 alc663_two_hp_m7_speaker_automute(codec);
17097 break;
17098 case ALC880_MIC_EVENT:
17099 alc_mic_automute(codec);
17100 break;
17104 #define alc663_mode7_setup alc663_mode1_setup
17106 static void alc663_mode7_inithook(struct hda_codec *codec)
17108 alc663_two_hp_m7_speaker_automute(codec);
17109 alc_mic_automute(codec);
17112 /* ***************** Mode8 ******************************/
17113 static void alc663_mode8_unsol_event(struct hda_codec *codec,
17114 unsigned int res)
17116 switch (res >> 26) {
17117 case ALC880_HP_EVENT:
17118 alc663_two_hp_m8_speaker_automute(codec);
17119 break;
17120 case ALC880_MIC_EVENT:
17121 alc_mic_automute(codec);
17122 break;
17126 #define alc663_mode8_setup alc663_m51va_setup
17128 static void alc663_mode8_inithook(struct hda_codec *codec)
17130 alc663_two_hp_m8_speaker_automute(codec);
17131 alc_mic_automute(codec);
17134 static void alc663_g71v_hp_automute(struct hda_codec *codec)
17136 unsigned int present;
17137 unsigned char bits;
17139 present = snd_hda_jack_detect(codec, 0x21);
17140 bits = present ? HDA_AMP_MUTE : 0;
17141 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17142 HDA_AMP_MUTE, bits);
17143 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17144 HDA_AMP_MUTE, bits);
17147 static void alc663_g71v_front_automute(struct hda_codec *codec)
17149 unsigned int present;
17150 unsigned char bits;
17152 present = snd_hda_jack_detect(codec, 0x15);
17153 bits = present ? HDA_AMP_MUTE : 0;
17154 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17155 HDA_AMP_MUTE, bits);
17158 static void alc663_g71v_unsol_event(struct hda_codec *codec,
17159 unsigned int res)
17161 switch (res >> 26) {
17162 case ALC880_HP_EVENT:
17163 alc663_g71v_hp_automute(codec);
17164 break;
17165 case ALC880_FRONT_EVENT:
17166 alc663_g71v_front_automute(codec);
17167 break;
17168 case ALC880_MIC_EVENT:
17169 alc_mic_automute(codec);
17170 break;
17174 #define alc663_g71v_setup alc663_m51va_setup
17176 static void alc663_g71v_inithook(struct hda_codec *codec)
17178 alc663_g71v_front_automute(codec);
17179 alc663_g71v_hp_automute(codec);
17180 alc_mic_automute(codec);
17183 static void alc663_g50v_unsol_event(struct hda_codec *codec,
17184 unsigned int res)
17186 switch (res >> 26) {
17187 case ALC880_HP_EVENT:
17188 alc663_m51va_speaker_automute(codec);
17189 break;
17190 case ALC880_MIC_EVENT:
17191 alc_mic_automute(codec);
17192 break;
17196 #define alc663_g50v_setup alc663_m51va_setup
17198 static void alc663_g50v_inithook(struct hda_codec *codec)
17200 alc663_m51va_speaker_automute(codec);
17201 alc_mic_automute(codec);
17204 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17205 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17206 ALC262_HIPPO_MASTER_SWITCH,
17208 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17209 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17210 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17212 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17213 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17214 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17215 { } /* end */
17218 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17219 /* Master Playback automatically created from Speaker and Headphone */
17220 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17221 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17222 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17223 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17225 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17226 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17227 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17229 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17230 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17231 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17232 { } /* end */
17235 #ifdef CONFIG_SND_HDA_POWER_SAVE
17236 #define alc662_loopbacks alc880_loopbacks
17237 #endif
17240 /* pcm configuration: identical with ALC880 */
17241 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
17242 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
17243 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
17244 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
17247 * configuration and preset
17249 static const char *alc662_models[ALC662_MODEL_LAST] = {
17250 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17251 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17252 [ALC662_3ST_6ch] = "3stack-6ch",
17253 [ALC662_5ST_DIG] = "6stack-dig",
17254 [ALC662_LENOVO_101E] = "lenovo-101e",
17255 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17256 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17257 [ALC662_ECS] = "ecs",
17258 [ALC663_ASUS_M51VA] = "m51va",
17259 [ALC663_ASUS_G71V] = "g71v",
17260 [ALC663_ASUS_H13] = "h13",
17261 [ALC663_ASUS_G50V] = "g50v",
17262 [ALC663_ASUS_MODE1] = "asus-mode1",
17263 [ALC662_ASUS_MODE2] = "asus-mode2",
17264 [ALC663_ASUS_MODE3] = "asus-mode3",
17265 [ALC663_ASUS_MODE4] = "asus-mode4",
17266 [ALC663_ASUS_MODE5] = "asus-mode5",
17267 [ALC663_ASUS_MODE6] = "asus-mode6",
17268 [ALC663_ASUS_MODE7] = "asus-mode7",
17269 [ALC663_ASUS_MODE8] = "asus-mode8",
17270 [ALC272_DELL] = "dell",
17271 [ALC272_DELL_ZM1] = "dell-zm1",
17272 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17273 [ALC662_AUTO] = "auto",
17276 static struct snd_pci_quirk alc662_cfg_tbl[] = {
17277 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17278 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17279 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17280 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17281 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17282 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17283 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17284 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17285 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17286 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17287 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17288 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17289 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17290 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17291 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17292 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17293 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17294 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17295 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17296 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17297 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17298 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17299 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17300 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17301 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17302 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17303 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17304 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17305 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17306 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17307 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17308 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17309 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17310 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17311 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17312 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17313 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17314 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17315 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17316 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17317 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17318 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17319 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17320 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17321 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17322 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17323 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17324 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17325 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17326 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17327 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17328 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17329 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17330 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17331 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17332 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17333 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17334 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17335 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17336 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17337 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17338 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17339 ALC662_3ST_6ch_DIG),
17340 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17341 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17342 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17343 ALC662_3ST_6ch_DIG),
17344 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17345 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17346 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17347 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17348 ALC662_3ST_6ch_DIG),
17349 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17350 ALC663_ASUS_H13),
17351 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
17355 static struct alc_config_preset alc662_presets[] = {
17356 [ALC662_3ST_2ch_DIG] = {
17357 .mixers = { alc662_3ST_2ch_mixer },
17358 .init_verbs = { alc662_init_verbs },
17359 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17360 .dac_nids = alc662_dac_nids,
17361 .dig_out_nid = ALC662_DIGOUT_NID,
17362 .dig_in_nid = ALC662_DIGIN_NID,
17363 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17364 .channel_mode = alc662_3ST_2ch_modes,
17365 .input_mux = &alc662_capture_source,
17367 [ALC662_3ST_6ch_DIG] = {
17368 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17369 .init_verbs = { alc662_init_verbs },
17370 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17371 .dac_nids = alc662_dac_nids,
17372 .dig_out_nid = ALC662_DIGOUT_NID,
17373 .dig_in_nid = ALC662_DIGIN_NID,
17374 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17375 .channel_mode = alc662_3ST_6ch_modes,
17376 .need_dac_fix = 1,
17377 .input_mux = &alc662_capture_source,
17379 [ALC662_3ST_6ch] = {
17380 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17381 .init_verbs = { alc662_init_verbs },
17382 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17383 .dac_nids = alc662_dac_nids,
17384 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17385 .channel_mode = alc662_3ST_6ch_modes,
17386 .need_dac_fix = 1,
17387 .input_mux = &alc662_capture_source,
17389 [ALC662_5ST_DIG] = {
17390 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17391 .init_verbs = { alc662_init_verbs },
17392 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17393 .dac_nids = alc662_dac_nids,
17394 .dig_out_nid = ALC662_DIGOUT_NID,
17395 .dig_in_nid = ALC662_DIGIN_NID,
17396 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17397 .channel_mode = alc662_5stack_modes,
17398 .input_mux = &alc662_capture_source,
17400 [ALC662_LENOVO_101E] = {
17401 .mixers = { alc662_lenovo_101e_mixer },
17402 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17403 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17404 .dac_nids = alc662_dac_nids,
17405 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17406 .channel_mode = alc662_3ST_2ch_modes,
17407 .input_mux = &alc662_lenovo_101e_capture_source,
17408 .unsol_event = alc662_lenovo_101e_unsol_event,
17409 .init_hook = alc662_lenovo_101e_all_automute,
17411 [ALC662_ASUS_EEEPC_P701] = {
17412 .mixers = { alc662_eeepc_p701_mixer },
17413 .init_verbs = { alc662_init_verbs,
17414 alc662_eeepc_sue_init_verbs },
17415 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17416 .dac_nids = alc662_dac_nids,
17417 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17418 .channel_mode = alc662_3ST_2ch_modes,
17419 .unsol_event = alc662_eeepc_unsol_event,
17420 .setup = alc662_eeepc_setup,
17421 .init_hook = alc662_eeepc_inithook,
17423 [ALC662_ASUS_EEEPC_EP20] = {
17424 .mixers = { alc662_eeepc_ep20_mixer,
17425 alc662_chmode_mixer },
17426 .init_verbs = { alc662_init_verbs,
17427 alc662_eeepc_ep20_sue_init_verbs },
17428 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17429 .dac_nids = alc662_dac_nids,
17430 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17431 .channel_mode = alc662_3ST_6ch_modes,
17432 .input_mux = &alc662_lenovo_101e_capture_source,
17433 .unsol_event = alc662_eeepc_unsol_event,
17434 .setup = alc662_eeepc_ep20_setup,
17435 .init_hook = alc662_eeepc_ep20_inithook,
17437 [ALC662_ECS] = {
17438 .mixers = { alc662_ecs_mixer },
17439 .init_verbs = { alc662_init_verbs,
17440 alc662_ecs_init_verbs },
17441 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17442 .dac_nids = alc662_dac_nids,
17443 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17444 .channel_mode = alc662_3ST_2ch_modes,
17445 .unsol_event = alc662_eeepc_unsol_event,
17446 .setup = alc662_eeepc_setup,
17447 .init_hook = alc662_eeepc_inithook,
17449 [ALC663_ASUS_M51VA] = {
17450 .mixers = { alc663_m51va_mixer },
17451 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17452 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17453 .dac_nids = alc662_dac_nids,
17454 .dig_out_nid = ALC662_DIGOUT_NID,
17455 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17456 .channel_mode = alc662_3ST_2ch_modes,
17457 .unsol_event = alc663_m51va_unsol_event,
17458 .setup = alc663_m51va_setup,
17459 .init_hook = alc663_m51va_inithook,
17461 [ALC663_ASUS_G71V] = {
17462 .mixers = { alc663_g71v_mixer },
17463 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17464 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17465 .dac_nids = alc662_dac_nids,
17466 .dig_out_nid = ALC662_DIGOUT_NID,
17467 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17468 .channel_mode = alc662_3ST_2ch_modes,
17469 .unsol_event = alc663_g71v_unsol_event,
17470 .setup = alc663_g71v_setup,
17471 .init_hook = alc663_g71v_inithook,
17473 [ALC663_ASUS_H13] = {
17474 .mixers = { alc663_m51va_mixer },
17475 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17476 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17477 .dac_nids = alc662_dac_nids,
17478 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17479 .channel_mode = alc662_3ST_2ch_modes,
17480 .unsol_event = alc663_m51va_unsol_event,
17481 .init_hook = alc663_m51va_inithook,
17483 [ALC663_ASUS_G50V] = {
17484 .mixers = { alc663_g50v_mixer },
17485 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17486 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17487 .dac_nids = alc662_dac_nids,
17488 .dig_out_nid = ALC662_DIGOUT_NID,
17489 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17490 .channel_mode = alc662_3ST_6ch_modes,
17491 .input_mux = &alc663_capture_source,
17492 .unsol_event = alc663_g50v_unsol_event,
17493 .setup = alc663_g50v_setup,
17494 .init_hook = alc663_g50v_inithook,
17496 [ALC663_ASUS_MODE1] = {
17497 .mixers = { alc663_m51va_mixer },
17498 .cap_mixer = alc662_auto_capture_mixer,
17499 .init_verbs = { alc662_init_verbs,
17500 alc663_21jd_amic_init_verbs },
17501 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17502 .hp_nid = 0x03,
17503 .dac_nids = alc662_dac_nids,
17504 .dig_out_nid = ALC662_DIGOUT_NID,
17505 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17506 .channel_mode = alc662_3ST_2ch_modes,
17507 .unsol_event = alc663_mode1_unsol_event,
17508 .setup = alc663_mode1_setup,
17509 .init_hook = alc663_mode1_inithook,
17511 [ALC662_ASUS_MODE2] = {
17512 .mixers = { alc662_1bjd_mixer },
17513 .cap_mixer = alc662_auto_capture_mixer,
17514 .init_verbs = { alc662_init_verbs,
17515 alc662_1bjd_amic_init_verbs },
17516 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17517 .dac_nids = alc662_dac_nids,
17518 .dig_out_nid = ALC662_DIGOUT_NID,
17519 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17520 .channel_mode = alc662_3ST_2ch_modes,
17521 .unsol_event = alc662_mode2_unsol_event,
17522 .setup = alc662_mode2_setup,
17523 .init_hook = alc662_mode2_inithook,
17525 [ALC663_ASUS_MODE3] = {
17526 .mixers = { alc663_two_hp_m1_mixer },
17527 .cap_mixer = alc662_auto_capture_mixer,
17528 .init_verbs = { alc662_init_verbs,
17529 alc663_two_hp_amic_m1_init_verbs },
17530 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17531 .hp_nid = 0x03,
17532 .dac_nids = alc662_dac_nids,
17533 .dig_out_nid = ALC662_DIGOUT_NID,
17534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17535 .channel_mode = alc662_3ST_2ch_modes,
17536 .unsol_event = alc663_mode3_unsol_event,
17537 .setup = alc663_mode3_setup,
17538 .init_hook = alc663_mode3_inithook,
17540 [ALC663_ASUS_MODE4] = {
17541 .mixers = { alc663_asus_21jd_clfe_mixer },
17542 .cap_mixer = alc662_auto_capture_mixer,
17543 .init_verbs = { alc662_init_verbs,
17544 alc663_21jd_amic_init_verbs},
17545 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17546 .hp_nid = 0x03,
17547 .dac_nids = alc662_dac_nids,
17548 .dig_out_nid = ALC662_DIGOUT_NID,
17549 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17550 .channel_mode = alc662_3ST_2ch_modes,
17551 .unsol_event = alc663_mode4_unsol_event,
17552 .setup = alc663_mode4_setup,
17553 .init_hook = alc663_mode4_inithook,
17555 [ALC663_ASUS_MODE5] = {
17556 .mixers = { alc663_asus_15jd_clfe_mixer },
17557 .cap_mixer = alc662_auto_capture_mixer,
17558 .init_verbs = { alc662_init_verbs,
17559 alc663_15jd_amic_init_verbs },
17560 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17561 .hp_nid = 0x03,
17562 .dac_nids = alc662_dac_nids,
17563 .dig_out_nid = ALC662_DIGOUT_NID,
17564 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17565 .channel_mode = alc662_3ST_2ch_modes,
17566 .unsol_event = alc663_mode5_unsol_event,
17567 .setup = alc663_mode5_setup,
17568 .init_hook = alc663_mode5_inithook,
17570 [ALC663_ASUS_MODE6] = {
17571 .mixers = { alc663_two_hp_m2_mixer },
17572 .cap_mixer = alc662_auto_capture_mixer,
17573 .init_verbs = { alc662_init_verbs,
17574 alc663_two_hp_amic_m2_init_verbs },
17575 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17576 .hp_nid = 0x03,
17577 .dac_nids = alc662_dac_nids,
17578 .dig_out_nid = ALC662_DIGOUT_NID,
17579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17580 .channel_mode = alc662_3ST_2ch_modes,
17581 .unsol_event = alc663_mode6_unsol_event,
17582 .setup = alc663_mode6_setup,
17583 .init_hook = alc663_mode6_inithook,
17585 [ALC663_ASUS_MODE7] = {
17586 .mixers = { alc663_mode7_mixer },
17587 .cap_mixer = alc662_auto_capture_mixer,
17588 .init_verbs = { alc662_init_verbs,
17589 alc663_mode7_init_verbs },
17590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17591 .hp_nid = 0x03,
17592 .dac_nids = alc662_dac_nids,
17593 .dig_out_nid = ALC662_DIGOUT_NID,
17594 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17595 .channel_mode = alc662_3ST_2ch_modes,
17596 .unsol_event = alc663_mode7_unsol_event,
17597 .setup = alc663_mode7_setup,
17598 .init_hook = alc663_mode7_inithook,
17600 [ALC663_ASUS_MODE8] = {
17601 .mixers = { alc663_mode8_mixer },
17602 .cap_mixer = alc662_auto_capture_mixer,
17603 .init_verbs = { alc662_init_verbs,
17604 alc663_mode8_init_verbs },
17605 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17606 .hp_nid = 0x03,
17607 .dac_nids = alc662_dac_nids,
17608 .dig_out_nid = ALC662_DIGOUT_NID,
17609 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17610 .channel_mode = alc662_3ST_2ch_modes,
17611 .unsol_event = alc663_mode8_unsol_event,
17612 .setup = alc663_mode8_setup,
17613 .init_hook = alc663_mode8_inithook,
17615 [ALC272_DELL] = {
17616 .mixers = { alc663_m51va_mixer },
17617 .cap_mixer = alc272_auto_capture_mixer,
17618 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17619 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17620 .dac_nids = alc662_dac_nids,
17621 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17622 .adc_nids = alc272_adc_nids,
17623 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17624 .capsrc_nids = alc272_capsrc_nids,
17625 .channel_mode = alc662_3ST_2ch_modes,
17626 .unsol_event = alc663_m51va_unsol_event,
17627 .setup = alc663_m51va_setup,
17628 .init_hook = alc663_m51va_inithook,
17630 [ALC272_DELL_ZM1] = {
17631 .mixers = { alc663_m51va_mixer },
17632 .cap_mixer = alc662_auto_capture_mixer,
17633 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17634 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17635 .dac_nids = alc662_dac_nids,
17636 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17637 .adc_nids = alc662_adc_nids,
17638 .num_adc_nids = 1,
17639 .capsrc_nids = alc662_capsrc_nids,
17640 .channel_mode = alc662_3ST_2ch_modes,
17641 .unsol_event = alc663_m51va_unsol_event,
17642 .setup = alc663_m51va_setup,
17643 .init_hook = alc663_m51va_inithook,
17645 [ALC272_SAMSUNG_NC10] = {
17646 .mixers = { alc272_nc10_mixer },
17647 .init_verbs = { alc662_init_verbs,
17648 alc663_21jd_amic_init_verbs },
17649 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17650 .dac_nids = alc272_dac_nids,
17651 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17652 .channel_mode = alc662_3ST_2ch_modes,
17653 /*.input_mux = &alc272_nc10_capture_source,*/
17654 .unsol_event = alc663_mode4_unsol_event,
17655 .setup = alc663_mode4_setup,
17656 .init_hook = alc663_mode4_inithook,
17662 * BIOS auto configuration
17665 /* convert from MIX nid to DAC */
17666 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17668 if (nid == 0x0f)
17669 return 0x02;
17670 else if (nid >= 0x0c && nid <= 0x0e)
17671 return nid - 0x0c + 0x02;
17672 else
17673 return 0;
17676 /* get MIX nid connected to the given pin targeted to DAC */
17677 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17678 hda_nid_t dac)
17680 hda_nid_t mix[4];
17681 int i, num;
17683 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17684 for (i = 0; i < num; i++) {
17685 if (alc662_mix_to_dac(mix[i]) == dac)
17686 return mix[i];
17688 return 0;
17691 /* look for an empty DAC slot */
17692 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17694 struct alc_spec *spec = codec->spec;
17695 hda_nid_t srcs[5];
17696 int i, j, num;
17698 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17699 if (num < 0)
17700 return 0;
17701 for (i = 0; i < num; i++) {
17702 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17703 if (!nid)
17704 continue;
17705 for (j = 0; j < spec->multiout.num_dacs; j++)
17706 if (spec->multiout.dac_nids[j] == nid)
17707 break;
17708 if (j >= spec->multiout.num_dacs)
17709 return nid;
17711 return 0;
17714 /* fill in the dac_nids table from the parsed pin configuration */
17715 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17716 const struct auto_pin_cfg *cfg)
17718 struct alc_spec *spec = codec->spec;
17719 int i;
17720 hda_nid_t dac;
17722 spec->multiout.dac_nids = spec->private_dac_nids;
17723 for (i = 0; i < cfg->line_outs; i++) {
17724 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17725 if (!dac)
17726 continue;
17727 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17729 return 0;
17732 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17733 hda_nid_t nid, unsigned int chs)
17735 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17736 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17739 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17740 hda_nid_t nid, unsigned int chs)
17742 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17743 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17746 #define alc662_add_stereo_vol(spec, pfx, nid) \
17747 alc662_add_vol_ctl(spec, pfx, nid, 3)
17748 #define alc662_add_stereo_sw(spec, pfx, nid) \
17749 alc662_add_sw_ctl(spec, pfx, nid, 3)
17751 /* add playback controls from the parsed DAC table */
17752 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17753 const struct auto_pin_cfg *cfg)
17755 struct alc_spec *spec = codec->spec;
17756 static const char *chname[4] = {
17757 "Front", "Surround", NULL /*CLFE*/, "Side"
17759 hda_nid_t nid, mix;
17760 int i, err;
17762 for (i = 0; i < cfg->line_outs; i++) {
17763 nid = spec->multiout.dac_nids[i];
17764 if (!nid)
17765 continue;
17766 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17767 if (!mix)
17768 continue;
17769 if (i == 2) {
17770 /* Center/LFE */
17771 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17772 if (err < 0)
17773 return err;
17774 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17775 if (err < 0)
17776 return err;
17777 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17778 if (err < 0)
17779 return err;
17780 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17781 if (err < 0)
17782 return err;
17783 } else {
17784 const char *pfx;
17785 if (cfg->line_outs == 1 &&
17786 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17787 if (cfg->hp_outs)
17788 pfx = "Speaker";
17789 else
17790 pfx = "PCM";
17791 } else
17792 pfx = chname[i];
17793 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17794 if (err < 0)
17795 return err;
17796 if (cfg->line_outs == 1 &&
17797 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17798 pfx = "Speaker";
17799 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17800 if (err < 0)
17801 return err;
17804 return 0;
17807 /* add playback controls for speaker and HP outputs */
17808 /* return DAC nid if any new DAC is assigned */
17809 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17810 const char *pfx)
17812 struct alc_spec *spec = codec->spec;
17813 hda_nid_t nid, mix;
17814 int err;
17816 if (!pin)
17817 return 0;
17818 nid = alc662_look_for_dac(codec, pin);
17819 if (!nid) {
17820 /* the corresponding DAC is already occupied */
17821 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17822 return 0; /* no way */
17823 /* create a switch only */
17824 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17825 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17828 mix = alc662_dac_to_mix(codec, pin, nid);
17829 if (!mix)
17830 return 0;
17831 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17832 if (err < 0)
17833 return err;
17834 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17835 if (err < 0)
17836 return err;
17837 return nid;
17840 /* create playback/capture controls for input pins */
17841 #define alc662_auto_create_input_ctls \
17842 alc882_auto_create_input_ctls
17844 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17845 hda_nid_t nid, int pin_type,
17846 hda_nid_t dac)
17848 int i, num;
17849 hda_nid_t srcs[4];
17851 alc_set_pin_output(codec, nid, pin_type);
17852 /* need the manual connection? */
17853 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17854 if (num <= 1)
17855 return;
17856 for (i = 0; i < num; i++) {
17857 if (alc662_mix_to_dac(srcs[i]) != dac)
17858 continue;
17859 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17860 return;
17864 static void alc662_auto_init_multi_out(struct hda_codec *codec)
17866 struct alc_spec *spec = codec->spec;
17867 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17868 int i;
17870 for (i = 0; i <= HDA_SIDE; i++) {
17871 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17872 if (nid)
17873 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17874 spec->multiout.dac_nids[i]);
17878 static void alc662_auto_init_hp_out(struct hda_codec *codec)
17880 struct alc_spec *spec = codec->spec;
17881 hda_nid_t pin;
17883 pin = spec->autocfg.hp_pins[0];
17884 if (pin)
17885 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17886 spec->multiout.hp_nid);
17887 pin = spec->autocfg.speaker_pins[0];
17888 if (pin)
17889 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17890 spec->multiout.extra_out_nid[0]);
17893 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17895 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17897 struct alc_spec *spec = codec->spec;
17898 int i;
17900 for (i = 0; i < AUTO_PIN_LAST; i++) {
17901 hda_nid_t nid = spec->autocfg.input_pins[i];
17902 if (alc_is_input_pin(codec, nid)) {
17903 alc_set_input_pin(codec, nid, i);
17904 if (nid != ALC662_PIN_CD_NID &&
17905 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17906 snd_hda_codec_write(codec, nid, 0,
17907 AC_VERB_SET_AMP_GAIN_MUTE,
17908 AMP_OUT_MUTE);
17913 #define alc662_auto_init_input_src alc882_auto_init_input_src
17915 static int alc662_parse_auto_config(struct hda_codec *codec)
17917 struct alc_spec *spec = codec->spec;
17918 int err;
17919 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17921 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17922 alc662_ignore);
17923 if (err < 0)
17924 return err;
17925 if (!spec->autocfg.line_outs)
17926 return 0; /* can't find valid BIOS pin config */
17928 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17929 if (err < 0)
17930 return err;
17931 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17932 if (err < 0)
17933 return err;
17934 err = alc662_auto_create_extra_out(codec,
17935 spec->autocfg.speaker_pins[0],
17936 "Speaker");
17937 if (err < 0)
17938 return err;
17939 if (err)
17940 spec->multiout.extra_out_nid[0] = err;
17941 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17942 "Headphone");
17943 if (err < 0)
17944 return err;
17945 if (err)
17946 spec->multiout.hp_nid = err;
17947 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17948 if (err < 0)
17949 return err;
17951 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17953 if (spec->autocfg.dig_outs)
17954 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17956 if (spec->kctls.list)
17957 add_mixer(spec, spec->kctls.list);
17959 spec->num_mux_defs = 1;
17960 spec->input_mux = &spec->private_imux[0];
17962 add_verb(spec, alc662_auto_init_verbs);
17963 if (codec->vendor_id == 0x10ec0663)
17964 add_verb(spec, alc663_auto_init_verbs);
17966 err = alc_auto_add_mic_boost(codec);
17967 if (err < 0)
17968 return err;
17970 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17972 return 1;
17975 /* additional initialization for auto-configuration model */
17976 static void alc662_auto_init(struct hda_codec *codec)
17978 struct alc_spec *spec = codec->spec;
17979 alc662_auto_init_multi_out(codec);
17980 alc662_auto_init_hp_out(codec);
17981 alc662_auto_init_analog_input(codec);
17982 alc662_auto_init_input_src(codec);
17983 if (spec->unsol_event)
17984 alc_inithook(codec);
17987 static int patch_alc662(struct hda_codec *codec)
17989 struct alc_spec *spec;
17990 int err, board_config;
17992 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17993 if (!spec)
17994 return -ENOMEM;
17996 codec->spec = spec;
17998 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18000 if (alc_read_coef_idx(codec, 0)==0x8020){
18001 kfree(codec->chip_name);
18002 codec->chip_name = kstrdup("ALC661", GFP_KERNEL);
18003 if (!codec->chip_name) {
18004 alc_free(codec);
18005 return -ENOMEM;
18009 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18010 alc662_models,
18011 alc662_cfg_tbl);
18012 if (board_config < 0) {
18013 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18014 codec->chip_name);
18015 board_config = ALC662_AUTO;
18018 if (board_config == ALC662_AUTO) {
18019 /* automatic parse from the BIOS config */
18020 err = alc662_parse_auto_config(codec);
18021 if (err < 0) {
18022 alc_free(codec);
18023 return err;
18024 } else if (!err) {
18025 printk(KERN_INFO
18026 "hda_codec: Cannot set up configuration "
18027 "from BIOS. Using base mode...\n");
18028 board_config = ALC662_3ST_2ch_DIG;
18032 err = snd_hda_attach_beep_device(codec, 0x1);
18033 if (err < 0) {
18034 alc_free(codec);
18035 return err;
18038 if (board_config != ALC662_AUTO)
18039 setup_preset(codec, &alc662_presets[board_config]);
18041 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18042 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18044 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18045 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18047 if (!spec->adc_nids) {
18048 spec->adc_nids = alc662_adc_nids;
18049 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18051 if (!spec->capsrc_nids)
18052 spec->capsrc_nids = alc662_capsrc_nids;
18054 if (!spec->cap_mixer)
18055 set_capture_mixer(codec);
18056 if (codec->vendor_id == 0x10ec0662)
18057 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18058 else
18059 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18061 spec->vmaster_nid = 0x02;
18063 codec->patch_ops = alc_patch_ops;
18064 if (board_config == ALC662_AUTO)
18065 spec->init_hook = alc662_auto_init;
18066 #ifdef CONFIG_SND_HDA_POWER_SAVE
18067 if (!spec->loopback.amplist)
18068 spec->loopback.amplist = alc662_loopbacks;
18069 #endif
18070 codec->proc_widget_hook = print_realtek_coef;
18072 return 0;
18075 static int patch_alc888(struct hda_codec *codec)
18077 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18078 kfree(codec->chip_name);
18079 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18080 if (!codec->chip_name) {
18081 alc_free(codec);
18082 return -ENOMEM;
18084 return patch_alc662(codec);
18086 return patch_alc882(codec);
18090 * patch entries
18092 static struct hda_codec_preset snd_hda_preset_realtek[] = {
18093 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
18094 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
18095 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
18096 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
18097 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
18098 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
18099 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
18100 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
18101 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
18102 .patch = patch_alc861 },
18103 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18104 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18105 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
18106 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
18107 .patch = patch_alc882 },
18108 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18109 .patch = patch_alc662 },
18110 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18111 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18112 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18113 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
18114 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
18115 .patch = patch_alc882 },
18116 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
18117 .patch = patch_alc882 },
18118 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
18119 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
18120 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
18121 .patch = patch_alc882 },
18122 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
18123 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
18124 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
18125 {} /* terminator */
18128 MODULE_ALIAS("snd-hda-codec-id:10ec*");
18130 MODULE_LICENSE("GPL");
18131 MODULE_DESCRIPTION("Realtek HD-audio codec");
18133 static struct hda_codec_preset_list realtek_list = {
18134 .preset = snd_hda_preset_realtek,
18135 .owner = THIS_MODULE,
18138 static int __init patch_realtek_init(void)
18140 return snd_hda_add_codec_preset(&realtek_list);
18143 static void __exit patch_realtek_exit(void)
18145 snd_hda_delete_codec_preset(&realtek_list);
18148 module_init(patch_realtek_init)
18149 module_exit(patch_realtek_exit)