ALSA: hda: Use LPIB and 6stack-dig for eMachines T5212
[linux-2.6/mini2440.git] / sound / pci / hda / patch_realtek.c
blob36a7fa43041fae185ec82eadd12684f8861d8e23
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_EEEPC_P703,
135 ALC269_ASUS_EEEPC_P901,
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 ALC272_DELL,
192 ALC272_DELL_ZM1,
193 ALC272_SAMSUNG_NC10,
194 ALC662_AUTO,
195 ALC662_MODEL_LAST,
198 /* ALC882 models */
199 enum {
200 ALC882_3ST_DIG,
201 ALC882_6ST_DIG,
202 ALC882_ARIMA,
203 ALC882_W2JC,
204 ALC882_TARGA,
205 ALC882_ASUS_A7J,
206 ALC882_ASUS_A7M,
207 ALC885_MACPRO,
208 ALC885_MBP3,
209 ALC885_MB5,
210 ALC885_IMAC24,
211 ALC883_3ST_2ch_DIG,
212 ALC883_3ST_6ch_DIG,
213 ALC883_3ST_6ch,
214 ALC883_6ST_DIG,
215 ALC883_TARGA_DIG,
216 ALC883_TARGA_2ch_DIG,
217 ALC883_TARGA_8ch_DIG,
218 ALC883_ACER,
219 ALC883_ACER_ASPIRE,
220 ALC888_ACER_ASPIRE_4930G,
221 ALC888_ACER_ASPIRE_6530G,
222 ALC888_ACER_ASPIRE_8930G,
223 ALC888_ACER_ASPIRE_7730G,
224 ALC883_MEDION,
225 ALC883_MEDION_MD2,
226 ALC883_LAPTOP_EAPD,
227 ALC883_LENOVO_101E_2ch,
228 ALC883_LENOVO_NB0763,
229 ALC888_LENOVO_MS7195_DIG,
230 ALC888_LENOVO_SKY,
231 ALC883_HAIER_W66,
232 ALC888_3ST_HP,
233 ALC888_6ST_DELL,
234 ALC883_MITAC,
235 ALC883_CLEVO_M540R,
236 ALC883_CLEVO_M720,
237 ALC883_FUJITSU_PI2515,
238 ALC888_FUJITSU_XA3530,
239 ALC883_3ST_6ch_INTEL,
240 ALC889A_INTEL,
241 ALC889_INTEL,
242 ALC888_ASUS_M90V,
243 ALC888_ASUS_EEE1601,
244 ALC889A_MB31,
245 ALC1200_ASUS_P5Q,
246 ALC883_SONY_VAIO_TT,
247 ALC882_AUTO,
248 ALC882_MODEL_LAST,
251 /* for GPIO Poll */
252 #define GPIO_MASK 0x03
254 /* extra amp-initialization sequence types */
255 enum {
256 ALC_INIT_NONE,
257 ALC_INIT_DEFAULT,
258 ALC_INIT_GPIO1,
259 ALC_INIT_GPIO2,
260 ALC_INIT_GPIO3,
263 struct alc_mic_route {
264 hda_nid_t pin;
265 unsigned char mux_idx;
266 unsigned char amix_idx;
269 #define MUX_IDX_UNDEF ((unsigned char)-1)
271 struct alc_spec {
272 /* codec parameterization */
273 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
274 unsigned int num_mixers;
275 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
276 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
278 const struct hda_verb *init_verbs[10]; /* initialization verbs
279 * don't forget NULL
280 * termination!
282 unsigned int num_init_verbs;
284 char stream_name_analog[32]; /* analog PCM stream */
285 struct hda_pcm_stream *stream_analog_playback;
286 struct hda_pcm_stream *stream_analog_capture;
287 struct hda_pcm_stream *stream_analog_alt_playback;
288 struct hda_pcm_stream *stream_analog_alt_capture;
290 char stream_name_digital[32]; /* digital PCM stream */
291 struct hda_pcm_stream *stream_digital_playback;
292 struct hda_pcm_stream *stream_digital_capture;
294 /* playback */
295 struct hda_multi_out multiout; /* playback set-up
296 * max_channels, dacs must be set
297 * dig_out_nid and hp_nid are optional
299 hda_nid_t alt_dac_nid;
300 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
301 int dig_out_type;
303 /* capture */
304 unsigned int num_adc_nids;
305 hda_nid_t *adc_nids;
306 hda_nid_t *capsrc_nids;
307 hda_nid_t dig_in_nid; /* digital-in NID; optional */
309 /* capture source */
310 unsigned int num_mux_defs;
311 const struct hda_input_mux *input_mux;
312 unsigned int cur_mux[3];
313 struct alc_mic_route ext_mic;
314 struct alc_mic_route int_mic;
316 /* channel model */
317 const struct hda_channel_mode *channel_mode;
318 int num_channel_mode;
319 int need_dac_fix;
320 int const_channel_count;
321 int ext_channel_count;
323 /* PCM information */
324 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
326 /* dynamic controls, init_verbs and input_mux */
327 struct auto_pin_cfg autocfg;
328 struct snd_array kctls;
329 struct hda_input_mux private_imux[3];
330 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
331 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
332 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
334 /* hooks */
335 void (*init_hook)(struct hda_codec *codec);
336 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
338 /* for pin sensing */
339 unsigned int sense_updated: 1;
340 unsigned int jack_present: 1;
341 unsigned int master_sw: 1;
342 unsigned int auto_mic:1;
344 /* other flags */
345 unsigned int no_analog :1; /* digital I/O only */
346 int init_amp;
348 /* for virtual master */
349 hda_nid_t vmaster_nid;
350 #ifdef CONFIG_SND_HDA_POWER_SAVE
351 struct hda_loopback_check loopback;
352 #endif
354 /* for PLL fix */
355 hda_nid_t pll_nid;
356 unsigned int pll_coef_idx, pll_coef_bit;
360 * configuration template - to be copied to the spec instance
362 struct alc_config_preset {
363 struct snd_kcontrol_new *mixers[5]; /* should be identical size
364 * with spec
366 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
367 const struct hda_verb *init_verbs[5];
368 unsigned int num_dacs;
369 hda_nid_t *dac_nids;
370 hda_nid_t dig_out_nid; /* optional */
371 hda_nid_t hp_nid; /* optional */
372 hda_nid_t *slave_dig_outs;
373 unsigned int num_adc_nids;
374 hda_nid_t *adc_nids;
375 hda_nid_t *capsrc_nids;
376 hda_nid_t dig_in_nid;
377 unsigned int num_channel_mode;
378 const struct hda_channel_mode *channel_mode;
379 int need_dac_fix;
380 int const_channel_count;
381 unsigned int num_mux_defs;
382 const struct hda_input_mux *input_mux;
383 void (*unsol_event)(struct hda_codec *, unsigned int);
384 void (*setup)(struct hda_codec *);
385 void (*init_hook)(struct hda_codec *);
386 #ifdef CONFIG_SND_HDA_POWER_SAVE
387 struct hda_amp_list *loopbacks;
388 #endif
393 * input MUX handling
395 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
396 struct snd_ctl_elem_info *uinfo)
398 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
399 struct alc_spec *spec = codec->spec;
400 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
401 if (mux_idx >= spec->num_mux_defs)
402 mux_idx = 0;
403 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
404 mux_idx = 0;
405 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
408 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
409 struct snd_ctl_elem_value *ucontrol)
411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412 struct alc_spec *spec = codec->spec;
413 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
415 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
416 return 0;
419 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
420 struct snd_ctl_elem_value *ucontrol)
422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423 struct alc_spec *spec = codec->spec;
424 const struct hda_input_mux *imux;
425 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
426 unsigned int mux_idx;
427 hda_nid_t nid = spec->capsrc_nids ?
428 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
429 unsigned int type;
431 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
432 imux = &spec->input_mux[mux_idx];
433 if (!imux->num_items && mux_idx > 0)
434 imux = &spec->input_mux[0];
436 type = get_wcaps_type(get_wcaps(codec, nid));
437 if (type == AC_WID_AUD_MIX) {
438 /* Matrix-mixer style (e.g. ALC882) */
439 unsigned int *cur_val = &spec->cur_mux[adc_idx];
440 unsigned int i, idx;
442 idx = ucontrol->value.enumerated.item[0];
443 if (idx >= imux->num_items)
444 idx = imux->num_items - 1;
445 if (*cur_val == idx)
446 return 0;
447 for (i = 0; i < imux->num_items; i++) {
448 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
449 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
450 imux->items[i].index,
451 HDA_AMP_MUTE, v);
453 *cur_val = idx;
454 return 1;
455 } else {
456 /* MUX style (e.g. ALC880) */
457 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
458 &spec->cur_mux[adc_idx]);
463 * channel mode setting
465 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
466 struct snd_ctl_elem_info *uinfo)
468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
469 struct alc_spec *spec = codec->spec;
470 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
471 spec->num_channel_mode);
474 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_value *ucontrol)
477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
478 struct alc_spec *spec = codec->spec;
479 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
480 spec->num_channel_mode,
481 spec->ext_channel_count);
484 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_value *ucontrol)
487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
488 struct alc_spec *spec = codec->spec;
489 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
490 spec->num_channel_mode,
491 &spec->ext_channel_count);
492 if (err >= 0 && !spec->const_channel_count) {
493 spec->multiout.max_channels = spec->ext_channel_count;
494 if (spec->need_dac_fix)
495 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
497 return err;
501 * Control the mode of pin widget settings via the mixer. "pc" is used
502 * instead of "%" to avoid consequences of accidently treating the % as
503 * being part of a format specifier. Maximum allowed length of a value is
504 * 63 characters plus NULL terminator.
506 * Note: some retasking pin complexes seem to ignore requests for input
507 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
508 * are requested. Therefore order this list so that this behaviour will not
509 * cause problems when mixer clients move through the enum sequentially.
510 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
511 * March 2006.
513 static char *alc_pin_mode_names[] = {
514 "Mic 50pc bias", "Mic 80pc bias",
515 "Line in", "Line out", "Headphone out",
517 static unsigned char alc_pin_mode_values[] = {
518 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
520 /* The control can present all 5 options, or it can limit the options based
521 * in the pin being assumed to be exclusively an input or an output pin. In
522 * addition, "input" pins may or may not process the mic bias option
523 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
524 * accept requests for bias as of chip versions up to March 2006) and/or
525 * wiring in the computer.
527 #define ALC_PIN_DIR_IN 0x00
528 #define ALC_PIN_DIR_OUT 0x01
529 #define ALC_PIN_DIR_INOUT 0x02
530 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
531 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
533 /* Info about the pin modes supported by the different pin direction modes.
534 * For each direction the minimum and maximum values are given.
536 static signed char alc_pin_mode_dir_info[5][2] = {
537 { 0, 2 }, /* ALC_PIN_DIR_IN */
538 { 3, 4 }, /* ALC_PIN_DIR_OUT */
539 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
540 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
541 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
543 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
544 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
545 #define alc_pin_mode_n_items(_dir) \
546 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
548 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_info *uinfo)
551 unsigned int item_num = uinfo->value.enumerated.item;
552 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
554 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
555 uinfo->count = 1;
556 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
558 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
559 item_num = alc_pin_mode_min(dir);
560 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
561 return 0;
564 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
567 unsigned int i;
568 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
569 hda_nid_t nid = kcontrol->private_value & 0xffff;
570 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
571 long *valp = ucontrol->value.integer.value;
572 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
573 AC_VERB_GET_PIN_WIDGET_CONTROL,
574 0x00);
576 /* Find enumerated value for current pinctl setting */
577 i = alc_pin_mode_min(dir);
578 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
579 i++;
580 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
581 return 0;
584 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
587 signed int change;
588 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
589 hda_nid_t nid = kcontrol->private_value & 0xffff;
590 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
591 long val = *ucontrol->value.integer.value;
592 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
593 AC_VERB_GET_PIN_WIDGET_CONTROL,
594 0x00);
596 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
597 val = alc_pin_mode_min(dir);
599 change = pinctl != alc_pin_mode_values[val];
600 if (change) {
601 /* Set pin mode to that requested */
602 snd_hda_codec_write_cache(codec, nid, 0,
603 AC_VERB_SET_PIN_WIDGET_CONTROL,
604 alc_pin_mode_values[val]);
606 /* Also enable the retasking pin's input/output as required
607 * for the requested pin mode. Enum values of 2 or less are
608 * input modes.
610 * Dynamically switching the input/output buffers probably
611 * reduces noise slightly (particularly on input) so we'll
612 * do it. However, having both input and output buffers
613 * enabled simultaneously doesn't seem to be problematic if
614 * this turns out to be necessary in the future.
616 if (val <= 2) {
617 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
618 HDA_AMP_MUTE, HDA_AMP_MUTE);
619 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
620 HDA_AMP_MUTE, 0);
621 } else {
622 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
623 HDA_AMP_MUTE, HDA_AMP_MUTE);
624 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
625 HDA_AMP_MUTE, 0);
628 return change;
631 #define ALC_PIN_MODE(xname, nid, dir) \
632 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
633 .info = alc_pin_mode_info, \
634 .get = alc_pin_mode_get, \
635 .put = alc_pin_mode_put, \
636 .private_value = nid | (dir<<16) }
638 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
639 * together using a mask with more than one bit set. This control is
640 * currently used only by the ALC260 test model. At this stage they are not
641 * needed for any "production" models.
643 #ifdef CONFIG_SND_DEBUG
644 #define alc_gpio_data_info snd_ctl_boolean_mono_info
646 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
647 struct snd_ctl_elem_value *ucontrol)
649 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
650 hda_nid_t nid = kcontrol->private_value & 0xffff;
651 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
652 long *valp = ucontrol->value.integer.value;
653 unsigned int val = snd_hda_codec_read(codec, nid, 0,
654 AC_VERB_GET_GPIO_DATA, 0x00);
656 *valp = (val & mask) != 0;
657 return 0;
659 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
660 struct snd_ctl_elem_value *ucontrol)
662 signed int change;
663 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
664 hda_nid_t nid = kcontrol->private_value & 0xffff;
665 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
666 long val = *ucontrol->value.integer.value;
667 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
668 AC_VERB_GET_GPIO_DATA,
669 0x00);
671 /* Set/unset the masked GPIO bit(s) as needed */
672 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
673 if (val == 0)
674 gpio_data &= ~mask;
675 else
676 gpio_data |= mask;
677 snd_hda_codec_write_cache(codec, nid, 0,
678 AC_VERB_SET_GPIO_DATA, gpio_data);
680 return change;
682 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
683 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
684 .info = alc_gpio_data_info, \
685 .get = alc_gpio_data_get, \
686 .put = alc_gpio_data_put, \
687 .private_value = nid | (mask<<16) }
688 #endif /* CONFIG_SND_DEBUG */
690 /* A switch control to allow the enabling of the digital IO pins on the
691 * ALC260. This is incredibly simplistic; the intention of this control is
692 * to provide something in the test model allowing digital outputs to be
693 * identified if present. If models are found which can utilise these
694 * outputs a more complete mixer control can be devised for those models if
695 * necessary.
697 #ifdef CONFIG_SND_DEBUG
698 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
700 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
701 struct snd_ctl_elem_value *ucontrol)
703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
704 hda_nid_t nid = kcontrol->private_value & 0xffff;
705 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
706 long *valp = ucontrol->value.integer.value;
707 unsigned int val = snd_hda_codec_read(codec, nid, 0,
708 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
710 *valp = (val & mask) != 0;
711 return 0;
713 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
716 signed int change;
717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
718 hda_nid_t nid = kcontrol->private_value & 0xffff;
719 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
720 long val = *ucontrol->value.integer.value;
721 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
722 AC_VERB_GET_DIGI_CONVERT_1,
723 0x00);
725 /* Set/unset the masked control bit(s) as needed */
726 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
727 if (val==0)
728 ctrl_data &= ~mask;
729 else
730 ctrl_data |= mask;
731 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
732 ctrl_data);
734 return change;
736 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
737 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
738 .info = alc_spdif_ctrl_info, \
739 .get = alc_spdif_ctrl_get, \
740 .put = alc_spdif_ctrl_put, \
741 .private_value = nid | (mask<<16) }
742 #endif /* CONFIG_SND_DEBUG */
744 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
745 * Again, this is only used in the ALC26x test models to help identify when
746 * the EAPD line must be asserted for features to work.
748 #ifdef CONFIG_SND_DEBUG
749 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
751 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
752 struct snd_ctl_elem_value *ucontrol)
754 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
755 hda_nid_t nid = kcontrol->private_value & 0xffff;
756 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
757 long *valp = ucontrol->value.integer.value;
758 unsigned int val = snd_hda_codec_read(codec, nid, 0,
759 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
761 *valp = (val & mask) != 0;
762 return 0;
765 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
766 struct snd_ctl_elem_value *ucontrol)
768 int change;
769 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
770 hda_nid_t nid = kcontrol->private_value & 0xffff;
771 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
772 long val = *ucontrol->value.integer.value;
773 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
774 AC_VERB_GET_EAPD_BTLENABLE,
775 0x00);
777 /* Set/unset the masked control bit(s) as needed */
778 change = (!val ? 0 : mask) != (ctrl_data & mask);
779 if (!val)
780 ctrl_data &= ~mask;
781 else
782 ctrl_data |= mask;
783 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
784 ctrl_data);
786 return change;
789 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
790 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
791 .info = alc_eapd_ctrl_info, \
792 .get = alc_eapd_ctrl_get, \
793 .put = alc_eapd_ctrl_put, \
794 .private_value = nid | (mask<<16) }
795 #endif /* CONFIG_SND_DEBUG */
798 * set up the input pin config (depending on the given auto-pin type)
800 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
801 int auto_pin_type)
803 unsigned int val = PIN_IN;
805 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
806 unsigned int pincap;
807 pincap = snd_hda_query_pin_caps(codec, nid);
808 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
809 if (pincap & AC_PINCAP_VREF_80)
810 val = PIN_VREF80;
811 else if (pincap & AC_PINCAP_VREF_50)
812 val = PIN_VREF50;
813 else if (pincap & AC_PINCAP_VREF_100)
814 val = PIN_VREF100;
815 else if (pincap & AC_PINCAP_VREF_GRD)
816 val = PIN_VREFGRD;
818 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
823 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
825 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
826 return;
827 spec->mixers[spec->num_mixers++] = mix;
830 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
832 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
833 return;
834 spec->init_verbs[spec->num_init_verbs++] = verb;
837 #ifdef CONFIG_PROC_FS
839 * hook for proc
841 static void print_realtek_coef(struct snd_info_buffer *buffer,
842 struct hda_codec *codec, hda_nid_t nid)
844 int coeff;
846 if (nid != 0x20)
847 return;
848 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
849 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
850 coeff = snd_hda_codec_read(codec, nid, 0,
851 AC_VERB_GET_COEF_INDEX, 0);
852 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
854 #else
855 #define print_realtek_coef NULL
856 #endif
859 * set up from the preset table
861 static void setup_preset(struct hda_codec *codec,
862 const struct alc_config_preset *preset)
864 struct alc_spec *spec = codec->spec;
865 int i;
867 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
868 add_mixer(spec, preset->mixers[i]);
869 spec->cap_mixer = preset->cap_mixer;
870 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
871 i++)
872 add_verb(spec, preset->init_verbs[i]);
874 spec->channel_mode = preset->channel_mode;
875 spec->num_channel_mode = preset->num_channel_mode;
876 spec->need_dac_fix = preset->need_dac_fix;
877 spec->const_channel_count = preset->const_channel_count;
879 if (preset->const_channel_count)
880 spec->multiout.max_channels = preset->const_channel_count;
881 else
882 spec->multiout.max_channels = spec->channel_mode[0].channels;
883 spec->ext_channel_count = spec->channel_mode[0].channels;
885 spec->multiout.num_dacs = preset->num_dacs;
886 spec->multiout.dac_nids = preset->dac_nids;
887 spec->multiout.dig_out_nid = preset->dig_out_nid;
888 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
889 spec->multiout.hp_nid = preset->hp_nid;
891 spec->num_mux_defs = preset->num_mux_defs;
892 if (!spec->num_mux_defs)
893 spec->num_mux_defs = 1;
894 spec->input_mux = preset->input_mux;
896 spec->num_adc_nids = preset->num_adc_nids;
897 spec->adc_nids = preset->adc_nids;
898 spec->capsrc_nids = preset->capsrc_nids;
899 spec->dig_in_nid = preset->dig_in_nid;
901 spec->unsol_event = preset->unsol_event;
902 spec->init_hook = preset->init_hook;
903 #ifdef CONFIG_SND_HDA_POWER_SAVE
904 spec->loopback.amplist = preset->loopbacks;
905 #endif
907 if (preset->setup)
908 preset->setup(codec);
911 /* Enable GPIO mask and set output */
912 static struct hda_verb alc_gpio1_init_verbs[] = {
913 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
914 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
915 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
919 static struct hda_verb alc_gpio2_init_verbs[] = {
920 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
921 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
922 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
926 static struct hda_verb alc_gpio3_init_verbs[] = {
927 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
928 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
929 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
934 * Fix hardware PLL issue
935 * On some codecs, the analog PLL gating control must be off while
936 * the default value is 1.
938 static void alc_fix_pll(struct hda_codec *codec)
940 struct alc_spec *spec = codec->spec;
941 unsigned int val;
943 if (!spec->pll_nid)
944 return;
945 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
946 spec->pll_coef_idx);
947 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
948 AC_VERB_GET_PROC_COEF, 0);
949 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
950 spec->pll_coef_idx);
951 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
952 val & ~(1 << spec->pll_coef_bit));
955 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
956 unsigned int coef_idx, unsigned int coef_bit)
958 struct alc_spec *spec = codec->spec;
959 spec->pll_nid = nid;
960 spec->pll_coef_idx = coef_idx;
961 spec->pll_coef_bit = coef_bit;
962 alc_fix_pll(codec);
965 static void alc_automute_pin(struct hda_codec *codec)
967 struct alc_spec *spec = codec->spec;
968 unsigned int present, pincap;
969 unsigned int nid = spec->autocfg.hp_pins[0];
970 int i;
972 if (!nid)
973 return;
974 pincap = snd_hda_query_pin_caps(codec, nid);
975 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
976 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
977 present = snd_hda_codec_read(codec, nid, 0,
978 AC_VERB_GET_PIN_SENSE, 0);
979 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
980 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
981 nid = spec->autocfg.speaker_pins[i];
982 if (!nid)
983 break;
984 snd_hda_codec_write(codec, nid, 0,
985 AC_VERB_SET_PIN_WIDGET_CONTROL,
986 spec->jack_present ? 0 : PIN_OUT);
990 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
991 hda_nid_t nid)
993 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
994 int i, nums;
996 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
997 for (i = 0; i < nums; i++)
998 if (conn[i] == nid)
999 return i;
1000 return -1;
1003 static void alc_mic_automute(struct hda_codec *codec)
1005 struct alc_spec *spec = codec->spec;
1006 struct alc_mic_route *dead, *alive;
1007 unsigned int present, type;
1008 hda_nid_t cap_nid;
1010 if (!spec->auto_mic)
1011 return;
1012 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1013 return;
1014 if (snd_BUG_ON(!spec->adc_nids))
1015 return;
1017 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1019 present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0,
1020 AC_VERB_GET_PIN_SENSE, 0);
1021 present &= AC_PINSENSE_PRESENCE;
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 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1102 unsigned int tmp;
1104 switch (type) {
1105 case ALC_INIT_GPIO1:
1106 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1107 break;
1108 case ALC_INIT_GPIO2:
1109 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1110 break;
1111 case ALC_INIT_GPIO3:
1112 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1113 break;
1114 case ALC_INIT_DEFAULT:
1115 switch (codec->vendor_id) {
1116 case 0x10ec0260:
1117 snd_hda_codec_write(codec, 0x0f, 0,
1118 AC_VERB_SET_EAPD_BTLENABLE, 2);
1119 snd_hda_codec_write(codec, 0x10, 0,
1120 AC_VERB_SET_EAPD_BTLENABLE, 2);
1121 break;
1122 case 0x10ec0262:
1123 case 0x10ec0267:
1124 case 0x10ec0268:
1125 case 0x10ec0269:
1126 case 0x10ec0272:
1127 case 0x10ec0660:
1128 case 0x10ec0662:
1129 case 0x10ec0663:
1130 case 0x10ec0862:
1131 case 0x10ec0889:
1132 snd_hda_codec_write(codec, 0x14, 0,
1133 AC_VERB_SET_EAPD_BTLENABLE, 2);
1134 snd_hda_codec_write(codec, 0x15, 0,
1135 AC_VERB_SET_EAPD_BTLENABLE, 2);
1136 break;
1138 switch (codec->vendor_id) {
1139 case 0x10ec0260:
1140 snd_hda_codec_write(codec, 0x1a, 0,
1141 AC_VERB_SET_COEF_INDEX, 7);
1142 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1143 AC_VERB_GET_PROC_COEF, 0);
1144 snd_hda_codec_write(codec, 0x1a, 0,
1145 AC_VERB_SET_COEF_INDEX, 7);
1146 snd_hda_codec_write(codec, 0x1a, 0,
1147 AC_VERB_SET_PROC_COEF,
1148 tmp | 0x2010);
1149 break;
1150 case 0x10ec0262:
1151 case 0x10ec0880:
1152 case 0x10ec0882:
1153 case 0x10ec0883:
1154 case 0x10ec0885:
1155 case 0x10ec0887:
1156 case 0x10ec0889:
1157 alc889_coef_init(codec);
1158 break;
1159 case 0x10ec0888:
1160 alc888_coef_init(codec);
1161 break;
1162 case 0x10ec0267:
1163 case 0x10ec0268:
1164 snd_hda_codec_write(codec, 0x20, 0,
1165 AC_VERB_SET_COEF_INDEX, 7);
1166 tmp = snd_hda_codec_read(codec, 0x20, 0,
1167 AC_VERB_GET_PROC_COEF, 0);
1168 snd_hda_codec_write(codec, 0x20, 0,
1169 AC_VERB_SET_COEF_INDEX, 7);
1170 snd_hda_codec_write(codec, 0x20, 0,
1171 AC_VERB_SET_PROC_COEF,
1172 tmp | 0x3000);
1173 break;
1175 break;
1179 static void alc_init_auto_hp(struct hda_codec *codec)
1181 struct alc_spec *spec = codec->spec;
1183 if (!spec->autocfg.hp_pins[0])
1184 return;
1186 if (!spec->autocfg.speaker_pins[0]) {
1187 if (spec->autocfg.line_out_pins[0] &&
1188 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1189 spec->autocfg.speaker_pins[0] =
1190 spec->autocfg.line_out_pins[0];
1191 else
1192 return;
1195 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1196 spec->autocfg.hp_pins[0]);
1197 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1198 AC_VERB_SET_UNSOLICITED_ENABLE,
1199 AC_USRSP_EN | ALC880_HP_EVENT);
1200 spec->unsol_event = alc_sku_unsol_event;
1203 static void alc_init_auto_mic(struct hda_codec *codec)
1205 struct alc_spec *spec = codec->spec;
1206 struct auto_pin_cfg *cfg = &spec->autocfg;
1207 hda_nid_t fixed, ext;
1208 int i;
1210 /* there must be only two mic inputs exclusively */
1211 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1212 if (cfg->input_pins[i])
1213 return;
1215 fixed = ext = 0;
1216 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1217 hda_nid_t nid = cfg->input_pins[i];
1218 unsigned int defcfg;
1219 if (!nid)
1220 return;
1221 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1222 switch (get_defcfg_connect(defcfg)) {
1223 case AC_JACK_PORT_FIXED:
1224 if (fixed)
1225 return; /* already occupied */
1226 fixed = nid;
1227 break;
1228 case AC_JACK_PORT_COMPLEX:
1229 if (ext)
1230 return; /* already occupied */
1231 ext = nid;
1232 break;
1233 default:
1234 return; /* invalid entry */
1237 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1238 return; /* no unsol support */
1239 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1240 ext, fixed);
1241 spec->ext_mic.pin = ext;
1242 spec->int_mic.pin = fixed;
1243 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1244 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1245 spec->auto_mic = 1;
1246 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1247 AC_VERB_SET_UNSOLICITED_ENABLE,
1248 AC_USRSP_EN | ALC880_MIC_EVENT);
1249 spec->unsol_event = alc_sku_unsol_event;
1252 /* check subsystem ID and set up device-specific initialization;
1253 * return 1 if initialized, 0 if invalid SSID
1255 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1256 * 31 ~ 16 : Manufacture ID
1257 * 15 ~ 8 : SKU ID
1258 * 7 ~ 0 : Assembly ID
1259 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1261 static int alc_subsystem_id(struct hda_codec *codec,
1262 hda_nid_t porta, hda_nid_t porte,
1263 hda_nid_t portd)
1265 unsigned int ass, tmp, i;
1266 unsigned nid;
1267 struct alc_spec *spec = codec->spec;
1269 ass = codec->subsystem_id & 0xffff;
1270 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1271 goto do_sku;
1273 /* invalid SSID, check the special NID pin defcfg instead */
1275 * 31~30 : port connectivity
1276 * 29~21 : reserve
1277 * 20 : PCBEEP input
1278 * 19~16 : Check sum (15:1)
1279 * 15~1 : Custom
1280 * 0 : override
1282 nid = 0x1d;
1283 if (codec->vendor_id == 0x10ec0260)
1284 nid = 0x17;
1285 ass = snd_hda_codec_get_pincfg(codec, nid);
1286 snd_printd("realtek: No valid SSID, "
1287 "checking pincfg 0x%08x for NID 0x%x\n",
1288 ass, nid);
1289 if (!(ass & 1) && !(ass & 0x100000))
1290 return 0;
1291 if ((ass >> 30) != 1) /* no physical connection */
1292 return 0;
1294 /* check sum */
1295 tmp = 0;
1296 for (i = 1; i < 16; i++) {
1297 if ((ass >> i) & 1)
1298 tmp++;
1300 if (((ass >> 16) & 0xf) != tmp)
1301 return 0;
1302 do_sku:
1303 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1304 ass & 0xffff, codec->vendor_id);
1306 * 0 : override
1307 * 1 : Swap Jack
1308 * 2 : 0 --> Desktop, 1 --> Laptop
1309 * 3~5 : External Amplifier control
1310 * 7~6 : Reserved
1312 tmp = (ass & 0x38) >> 3; /* external Amp control */
1313 switch (tmp) {
1314 case 1:
1315 spec->init_amp = ALC_INIT_GPIO1;
1316 break;
1317 case 3:
1318 spec->init_amp = ALC_INIT_GPIO2;
1319 break;
1320 case 7:
1321 spec->init_amp = ALC_INIT_GPIO3;
1322 break;
1323 case 5:
1324 spec->init_amp = ALC_INIT_DEFAULT;
1325 break;
1328 /* is laptop or Desktop and enable the function "Mute internal speaker
1329 * when the external headphone out jack is plugged"
1331 if (!(ass & 0x8000))
1332 return 1;
1334 * 10~8 : Jack location
1335 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1336 * 14~13: Resvered
1337 * 15 : 1 --> enable the function "Mute internal speaker
1338 * when the external headphone out jack is plugged"
1340 if (!spec->autocfg.hp_pins[0]) {
1341 hda_nid_t nid;
1342 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1343 if (tmp == 0)
1344 nid = porta;
1345 else if (tmp == 1)
1346 nid = porte;
1347 else if (tmp == 2)
1348 nid = portd;
1349 else
1350 return 1;
1351 for (i = 0; i < spec->autocfg.line_outs; i++)
1352 if (spec->autocfg.line_out_pins[i] == nid)
1353 return 1;
1354 spec->autocfg.hp_pins[0] = nid;
1357 alc_init_auto_hp(codec);
1358 alc_init_auto_mic(codec);
1359 return 1;
1362 static void alc_ssid_check(struct hda_codec *codec,
1363 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1365 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1366 struct alc_spec *spec = codec->spec;
1367 snd_printd("realtek: "
1368 "Enable default setup for auto mode as fallback\n");
1369 spec->init_amp = ALC_INIT_DEFAULT;
1370 alc_init_auto_hp(codec);
1371 alc_init_auto_mic(codec);
1376 * Fix-up pin default configurations and add default verbs
1379 struct alc_pincfg {
1380 hda_nid_t nid;
1381 u32 val;
1384 struct alc_fixup {
1385 const struct alc_pincfg *pins;
1386 const struct hda_verb *verbs;
1389 static void alc_pick_fixup(struct hda_codec *codec,
1390 const struct snd_pci_quirk *quirk,
1391 const struct alc_fixup *fix)
1393 const struct alc_pincfg *cfg;
1395 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1396 if (!quirk)
1397 return;
1399 fix += quirk->value;
1400 cfg = fix->pins;
1401 if (cfg) {
1402 for (; cfg->nid; cfg++)
1403 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1405 if (fix->verbs)
1406 add_verb(codec->spec, fix->verbs);
1410 * ALC888
1414 * 2ch mode
1416 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1417 /* Mic-in jack as mic in */
1418 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1419 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1420 /* Line-in jack as Line in */
1421 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1422 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1423 /* Line-Out as Front */
1424 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1425 { } /* end */
1429 * 4ch mode
1431 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1432 /* Mic-in jack as mic in */
1433 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1434 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1435 /* Line-in jack as Surround */
1436 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1437 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1438 /* Line-Out as Front */
1439 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1440 { } /* end */
1444 * 6ch mode
1446 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1447 /* Mic-in jack as CLFE */
1448 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1449 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1450 /* Line-in jack as Surround */
1451 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1452 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1453 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1454 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1455 { } /* end */
1459 * 8ch mode
1461 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1462 /* Mic-in jack as CLFE */
1463 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1464 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1465 /* Line-in jack as Surround */
1466 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1467 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1468 /* Line-Out as Side */
1469 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1470 { } /* end */
1473 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1474 { 2, alc888_4ST_ch2_intel_init },
1475 { 4, alc888_4ST_ch4_intel_init },
1476 { 6, alc888_4ST_ch6_intel_init },
1477 { 8, alc888_4ST_ch8_intel_init },
1481 * ALC888 Fujitsu Siemens Amillo xa3530
1484 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1485 /* Front Mic: set to PIN_IN (empty by default) */
1486 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1487 /* Connect Internal HP to Front */
1488 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1489 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1490 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1491 /* Connect Bass HP to Front */
1492 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1495 /* Connect Line-Out side jack (SPDIF) to Side */
1496 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1497 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1498 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1499 /* Connect Mic jack to CLFE */
1500 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1501 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1502 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1503 /* Connect Line-in jack to Surround */
1504 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1505 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1506 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1507 /* Connect HP out jack to Front */
1508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1510 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1511 /* Enable unsolicited event for HP jack and Line-out jack */
1512 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1513 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1517 static void alc_automute_amp(struct hda_codec *codec)
1519 struct alc_spec *spec = codec->spec;
1520 unsigned int val, mute, pincap;
1521 hda_nid_t nid;
1522 int i;
1524 spec->jack_present = 0;
1525 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1526 nid = spec->autocfg.hp_pins[i];
1527 if (!nid)
1528 break;
1529 pincap = snd_hda_query_pin_caps(codec, nid);
1530 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1531 snd_hda_codec_read(codec, nid, 0,
1532 AC_VERB_SET_PIN_SENSE, 0);
1533 val = snd_hda_codec_read(codec, nid, 0,
1534 AC_VERB_GET_PIN_SENSE, 0);
1535 if (val & AC_PINSENSE_PRESENCE) {
1536 spec->jack_present = 1;
1537 break;
1541 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1542 /* Toggle internal speakers muting */
1543 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1544 nid = spec->autocfg.speaker_pins[i];
1545 if (!nid)
1546 break;
1547 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1548 HDA_AMP_MUTE, mute);
1552 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1553 unsigned int res)
1555 if (codec->vendor_id == 0x10ec0880)
1556 res >>= 28;
1557 else
1558 res >>= 26;
1559 if (res == ALC880_HP_EVENT)
1560 alc_automute_amp(codec);
1563 static void alc889_automute_setup(struct hda_codec *codec)
1565 struct alc_spec *spec = codec->spec;
1567 spec->autocfg.hp_pins[0] = 0x15;
1568 spec->autocfg.speaker_pins[0] = 0x14;
1569 spec->autocfg.speaker_pins[1] = 0x16;
1570 spec->autocfg.speaker_pins[2] = 0x17;
1571 spec->autocfg.speaker_pins[3] = 0x19;
1572 spec->autocfg.speaker_pins[4] = 0x1a;
1575 static void alc889_intel_init_hook(struct hda_codec *codec)
1577 alc889_coef_init(codec);
1578 alc_automute_amp(codec);
1581 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1583 struct alc_spec *spec = codec->spec;
1585 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1586 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1587 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1588 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1592 * ALC888 Acer Aspire 4930G model
1595 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1596 /* Front Mic: set to PIN_IN (empty by default) */
1597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1598 /* Unselect Front Mic by default in input mixer 3 */
1599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1600 /* Enable unsolicited event for HP jack */
1601 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1602 /* Connect Internal HP to front */
1603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1604 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1605 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1606 /* Connect HP out to front */
1607 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1608 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1609 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1614 * ALC888 Acer Aspire 6530G model
1617 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1618 /* Bias voltage on for external mic port */
1619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1620 /* Front Mic: set to PIN_IN (empty by default) */
1621 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1622 /* Unselect Front Mic by default in input mixer 3 */
1623 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1624 /* Enable unsolicited event for HP jack */
1625 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1626 /* Enable speaker output */
1627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1628 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1629 /* Enable headphone output */
1630 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1632 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1637 * ALC889 Acer Aspire 8930G model
1640 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1641 /* Front Mic: set to PIN_IN (empty by default) */
1642 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1643 /* Unselect Front Mic by default in input mixer 3 */
1644 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1645 /* Enable unsolicited event for HP jack */
1646 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1647 /* Connect Internal Front to Front */
1648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1651 /* Connect Internal Rear to Rear */
1652 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1653 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1654 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1655 /* Connect Internal CLFE to CLFE */
1656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1659 /* Connect HP out to Front */
1660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1662 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1663 /* Enable all DACs */
1664 /* DAC DISABLE/MUTE 1? */
1665 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1666 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1667 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1668 /* DAC DISABLE/MUTE 2? */
1669 /* some bit here disables the other DACs. Init=0x4900 */
1670 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1671 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1672 /* Enable amplifiers */
1673 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1674 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1675 /* DMIC fix
1676 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1677 * which makes the stereo useless. However, either the mic or the ALC889
1678 * makes the signal become a difference/sum signal instead of standard
1679 * stereo, which is annoying. So instead we flip this bit which makes the
1680 * codec replicate the sum signal to both channels, turning it into a
1681 * normal mono mic.
1683 /* DMIC_CONTROL? Init value = 0x0001 */
1684 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1685 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1689 static struct hda_input_mux alc888_2_capture_sources[2] = {
1690 /* Front mic only available on one ADC */
1692 .num_items = 4,
1693 .items = {
1694 { "Mic", 0x0 },
1695 { "Line", 0x2 },
1696 { "CD", 0x4 },
1697 { "Front Mic", 0xb },
1701 .num_items = 3,
1702 .items = {
1703 { "Mic", 0x0 },
1704 { "Line", 0x2 },
1705 { "CD", 0x4 },
1710 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1711 /* Interal mic only available on one ADC */
1713 .num_items = 5,
1714 .items = {
1715 { "Ext Mic", 0x0 },
1716 { "Line In", 0x2 },
1717 { "CD", 0x4 },
1718 { "Input Mix", 0xa },
1719 { "Int Mic", 0xb },
1723 .num_items = 4,
1724 .items = {
1725 { "Ext Mic", 0x0 },
1726 { "Line In", 0x2 },
1727 { "CD", 0x4 },
1728 { "Input Mix", 0xa },
1733 static struct hda_input_mux alc889_capture_sources[3] = {
1734 /* Digital mic only available on first "ADC" */
1736 .num_items = 5,
1737 .items = {
1738 { "Mic", 0x0 },
1739 { "Line", 0x2 },
1740 { "CD", 0x4 },
1741 { "Front Mic", 0xb },
1742 { "Input Mix", 0xa },
1746 .num_items = 4,
1747 .items = {
1748 { "Mic", 0x0 },
1749 { "Line", 0x2 },
1750 { "CD", 0x4 },
1751 { "Input Mix", 0xa },
1755 .num_items = 4,
1756 .items = {
1757 { "Mic", 0x0 },
1758 { "Line", 0x2 },
1759 { "CD", 0x4 },
1760 { "Input Mix", 0xa },
1765 static struct snd_kcontrol_new alc888_base_mixer[] = {
1766 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1767 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1768 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1769 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1770 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1771 HDA_OUTPUT),
1772 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1773 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1774 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1775 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1776 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1777 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1778 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1779 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1780 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1781 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1782 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1784 { } /* end */
1787 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1789 struct alc_spec *spec = codec->spec;
1791 spec->autocfg.hp_pins[0] = 0x15;
1792 spec->autocfg.speaker_pins[0] = 0x14;
1795 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1797 struct alc_spec *spec = codec->spec;
1799 spec->autocfg.hp_pins[0] = 0x15;
1800 spec->autocfg.speaker_pins[0] = 0x14;
1801 spec->autocfg.speaker_pins[1] = 0x16;
1802 spec->autocfg.speaker_pins[2] = 0x17;
1805 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1807 struct alc_spec *spec = codec->spec;
1809 spec->autocfg.hp_pins[0] = 0x15;
1810 spec->autocfg.speaker_pins[0] = 0x14;
1811 spec->autocfg.speaker_pins[1] = 0x16;
1812 spec->autocfg.speaker_pins[2] = 0x1b;
1816 * ALC880 3-stack model
1818 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1819 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1820 * F-Mic = 0x1b, HP = 0x19
1823 static hda_nid_t alc880_dac_nids[4] = {
1824 /* front, rear, clfe, rear_surr */
1825 0x02, 0x05, 0x04, 0x03
1828 static hda_nid_t alc880_adc_nids[3] = {
1829 /* ADC0-2 */
1830 0x07, 0x08, 0x09,
1833 /* The datasheet says the node 0x07 is connected from inputs,
1834 * but it shows zero connection in the real implementation on some devices.
1835 * Note: this is a 915GAV bug, fixed on 915GLV
1837 static hda_nid_t alc880_adc_nids_alt[2] = {
1838 /* ADC1-2 */
1839 0x08, 0x09,
1842 #define ALC880_DIGOUT_NID 0x06
1843 #define ALC880_DIGIN_NID 0x0a
1845 static struct hda_input_mux alc880_capture_source = {
1846 .num_items = 4,
1847 .items = {
1848 { "Mic", 0x0 },
1849 { "Front Mic", 0x3 },
1850 { "Line", 0x2 },
1851 { "CD", 0x4 },
1855 /* channel source setting (2/6 channel selection for 3-stack) */
1856 /* 2ch mode */
1857 static struct hda_verb alc880_threestack_ch2_init[] = {
1858 /* set line-in to input, mute it */
1859 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1860 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1861 /* set mic-in to input vref 80%, mute it */
1862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1864 { } /* end */
1867 /* 6ch mode */
1868 static struct hda_verb alc880_threestack_ch6_init[] = {
1869 /* set line-in to output, unmute it */
1870 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1871 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1872 /* set mic-in to output, unmute it */
1873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1875 { } /* end */
1878 static struct hda_channel_mode alc880_threestack_modes[2] = {
1879 { 2, alc880_threestack_ch2_init },
1880 { 6, alc880_threestack_ch6_init },
1883 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1884 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1886 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1887 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1888 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1889 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1890 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1891 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1892 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1893 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1897 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1898 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1902 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1903 .name = "Channel Mode",
1904 .info = alc_ch_mode_info,
1905 .get = alc_ch_mode_get,
1906 .put = alc_ch_mode_put,
1908 { } /* end */
1911 /* capture mixer elements */
1912 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1913 struct snd_ctl_elem_info *uinfo)
1915 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1916 struct alc_spec *spec = codec->spec;
1917 int err;
1919 mutex_lock(&codec->control_mutex);
1920 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1921 HDA_INPUT);
1922 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1923 mutex_unlock(&codec->control_mutex);
1924 return err;
1927 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1928 unsigned int size, unsigned int __user *tlv)
1930 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1931 struct alc_spec *spec = codec->spec;
1932 int err;
1934 mutex_lock(&codec->control_mutex);
1935 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1936 HDA_INPUT);
1937 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1938 mutex_unlock(&codec->control_mutex);
1939 return err;
1942 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1943 struct snd_ctl_elem_value *ucontrol);
1945 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1946 struct snd_ctl_elem_value *ucontrol,
1947 getput_call_t func)
1949 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1950 struct alc_spec *spec = codec->spec;
1951 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1952 int err;
1954 mutex_lock(&codec->control_mutex);
1955 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1956 3, 0, HDA_INPUT);
1957 err = func(kcontrol, ucontrol);
1958 mutex_unlock(&codec->control_mutex);
1959 return err;
1962 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1963 struct snd_ctl_elem_value *ucontrol)
1965 return alc_cap_getput_caller(kcontrol, ucontrol,
1966 snd_hda_mixer_amp_volume_get);
1969 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1970 struct snd_ctl_elem_value *ucontrol)
1972 return alc_cap_getput_caller(kcontrol, ucontrol,
1973 snd_hda_mixer_amp_volume_put);
1976 /* capture mixer elements */
1977 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1979 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1980 struct snd_ctl_elem_value *ucontrol)
1982 return alc_cap_getput_caller(kcontrol, ucontrol,
1983 snd_hda_mixer_amp_switch_get);
1986 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1987 struct snd_ctl_elem_value *ucontrol)
1989 return alc_cap_getput_caller(kcontrol, ucontrol,
1990 snd_hda_mixer_amp_switch_put);
1993 #define _DEFINE_CAPMIX(num) \
1995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1996 .name = "Capture Switch", \
1997 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1998 .count = num, \
1999 .info = alc_cap_sw_info, \
2000 .get = alc_cap_sw_get, \
2001 .put = alc_cap_sw_put, \
2002 }, \
2004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2005 .name = "Capture Volume", \
2006 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2007 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2008 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2009 .count = num, \
2010 .info = alc_cap_vol_info, \
2011 .get = alc_cap_vol_get, \
2012 .put = alc_cap_vol_put, \
2013 .tlv = { .c = alc_cap_vol_tlv }, \
2016 #define _DEFINE_CAPSRC(num) \
2018 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2019 /* .name = "Capture Source", */ \
2020 .name = "Input Source", \
2021 .count = num, \
2022 .info = alc_mux_enum_info, \
2023 .get = alc_mux_enum_get, \
2024 .put = alc_mux_enum_put, \
2027 #define DEFINE_CAPMIX(num) \
2028 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2029 _DEFINE_CAPMIX(num), \
2030 _DEFINE_CAPSRC(num), \
2031 { } /* end */ \
2034 #define DEFINE_CAPMIX_NOSRC(num) \
2035 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2036 _DEFINE_CAPMIX(num), \
2037 { } /* end */ \
2040 /* up to three ADCs */
2041 DEFINE_CAPMIX(1);
2042 DEFINE_CAPMIX(2);
2043 DEFINE_CAPMIX(3);
2044 DEFINE_CAPMIX_NOSRC(1);
2045 DEFINE_CAPMIX_NOSRC(2);
2046 DEFINE_CAPMIX_NOSRC(3);
2049 * ALC880 5-stack model
2051 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2052 * Side = 0x02 (0xd)
2053 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2054 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2057 /* additional mixers to alc880_three_stack_mixer */
2058 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2059 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2060 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2061 { } /* end */
2064 /* channel source setting (6/8 channel selection for 5-stack) */
2065 /* 6ch mode */
2066 static struct hda_verb alc880_fivestack_ch6_init[] = {
2067 /* set line-in to input, mute it */
2068 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2069 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2070 { } /* end */
2073 /* 8ch mode */
2074 static struct hda_verb alc880_fivestack_ch8_init[] = {
2075 /* set line-in to output, unmute it */
2076 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2077 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2078 { } /* end */
2081 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2082 { 6, alc880_fivestack_ch6_init },
2083 { 8, alc880_fivestack_ch8_init },
2088 * ALC880 6-stack model
2090 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2091 * Side = 0x05 (0x0f)
2092 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2093 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2096 static hda_nid_t alc880_6st_dac_nids[4] = {
2097 /* front, rear, clfe, rear_surr */
2098 0x02, 0x03, 0x04, 0x05
2101 static struct hda_input_mux alc880_6stack_capture_source = {
2102 .num_items = 4,
2103 .items = {
2104 { "Mic", 0x0 },
2105 { "Front Mic", 0x1 },
2106 { "Line", 0x2 },
2107 { "CD", 0x4 },
2111 /* fixed 8-channels */
2112 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2113 { 8, NULL },
2116 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2117 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2118 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2119 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2120 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2121 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2122 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2123 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2124 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2126 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2133 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2136 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2137 .name = "Channel Mode",
2138 .info = alc_ch_mode_info,
2139 .get = alc_ch_mode_get,
2140 .put = alc_ch_mode_put,
2142 { } /* end */
2147 * ALC880 W810 model
2149 * W810 has rear IO for:
2150 * Front (DAC 02)
2151 * Surround (DAC 03)
2152 * Center/LFE (DAC 04)
2153 * Digital out (06)
2155 * The system also has a pair of internal speakers, and a headphone jack.
2156 * These are both connected to Line2 on the codec, hence to DAC 02.
2158 * There is a variable resistor to control the speaker or headphone
2159 * volume. This is a hardware-only device without a software API.
2161 * Plugging headphones in will disable the internal speakers. This is
2162 * implemented in hardware, not via the driver using jack sense. In
2163 * a similar fashion, plugging into the rear socket marked "front" will
2164 * disable both the speakers and headphones.
2166 * For input, there's a microphone jack, and an "audio in" jack.
2167 * These may not do anything useful with this driver yet, because I
2168 * haven't setup any initialization verbs for these yet...
2171 static hda_nid_t alc880_w810_dac_nids[3] = {
2172 /* front, rear/surround, clfe */
2173 0x02, 0x03, 0x04
2176 /* fixed 6 channels */
2177 static struct hda_channel_mode alc880_w810_modes[1] = {
2178 { 6, NULL }
2181 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2182 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2184 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2185 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2186 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2187 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2188 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2189 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2190 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2191 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2192 { } /* end */
2197 * Z710V model
2199 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2200 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2201 * Line = 0x1a
2204 static hda_nid_t alc880_z71v_dac_nids[1] = {
2205 0x02
2207 #define ALC880_Z71V_HP_DAC 0x03
2209 /* fixed 2 channels */
2210 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2211 { 2, NULL }
2214 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2215 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2216 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2217 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2218 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2221 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2223 { } /* end */
2228 * ALC880 F1734 model
2230 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2231 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2234 static hda_nid_t alc880_f1734_dac_nids[1] = {
2235 0x03
2237 #define ALC880_F1734_HP_DAC 0x02
2239 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2241 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2242 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2243 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2244 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2245 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2247 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2248 { } /* end */
2251 static struct hda_input_mux alc880_f1734_capture_source = {
2252 .num_items = 2,
2253 .items = {
2254 { "Mic", 0x1 },
2255 { "CD", 0x4 },
2261 * ALC880 ASUS model
2263 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2264 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2265 * Mic = 0x18, Line = 0x1a
2268 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2269 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2271 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2273 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2275 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2276 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2277 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2278 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2279 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2288 .name = "Channel Mode",
2289 .info = alc_ch_mode_info,
2290 .get = alc_ch_mode_get,
2291 .put = alc_ch_mode_put,
2293 { } /* end */
2297 * ALC880 ASUS W1V model
2299 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2300 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2301 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2304 /* additional mixers to alc880_asus_mixer */
2305 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2306 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2307 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2308 { } /* end */
2311 /* TCL S700 */
2312 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2313 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2314 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2315 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2317 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2320 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2321 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2322 { } /* end */
2325 /* Uniwill */
2326 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2327 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2328 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2330 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2331 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2332 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2333 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2334 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2335 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2336 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2337 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2338 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2339 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2340 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2341 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2342 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2345 .name = "Channel Mode",
2346 .info = alc_ch_mode_info,
2347 .get = alc_ch_mode_get,
2348 .put = alc_ch_mode_put,
2350 { } /* end */
2353 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2354 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2357 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2358 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2359 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2360 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2361 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2362 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2363 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2364 { } /* end */
2367 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2368 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2369 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2370 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2371 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2373 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2374 { } /* end */
2378 * virtual master controls
2382 * slave controls for virtual master
2384 static const char *alc_slave_vols[] = {
2385 "Front Playback Volume",
2386 "Surround Playback Volume",
2387 "Center Playback Volume",
2388 "LFE Playback Volume",
2389 "Side Playback Volume",
2390 "Headphone Playback Volume",
2391 "Speaker Playback Volume",
2392 "Mono Playback Volume",
2393 "Line-Out Playback Volume",
2394 "PCM Playback Volume",
2395 NULL,
2398 static const char *alc_slave_sws[] = {
2399 "Front Playback Switch",
2400 "Surround Playback Switch",
2401 "Center Playback Switch",
2402 "LFE Playback Switch",
2403 "Side Playback Switch",
2404 "Headphone Playback Switch",
2405 "Speaker Playback Switch",
2406 "Mono Playback Switch",
2407 "IEC958 Playback Switch",
2408 "Line-Out Playback Switch",
2409 "PCM Playback Switch",
2410 NULL,
2414 * build control elements
2417 static void alc_free_kctls(struct hda_codec *codec);
2419 /* additional beep mixers; the actual parameters are overwritten at build */
2420 static struct snd_kcontrol_new alc_beep_mixer[] = {
2421 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2422 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2423 { } /* end */
2426 static int alc_build_controls(struct hda_codec *codec)
2428 struct alc_spec *spec = codec->spec;
2429 int err;
2430 int i;
2432 for (i = 0; i < spec->num_mixers; i++) {
2433 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2434 if (err < 0)
2435 return err;
2437 if (spec->cap_mixer) {
2438 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2439 if (err < 0)
2440 return err;
2442 if (spec->multiout.dig_out_nid) {
2443 err = snd_hda_create_spdif_out_ctls(codec,
2444 spec->multiout.dig_out_nid);
2445 if (err < 0)
2446 return err;
2447 if (!spec->no_analog) {
2448 err = snd_hda_create_spdif_share_sw(codec,
2449 &spec->multiout);
2450 if (err < 0)
2451 return err;
2452 spec->multiout.share_spdif = 1;
2455 if (spec->dig_in_nid) {
2456 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2457 if (err < 0)
2458 return err;
2461 /* create beep controls if needed */
2462 if (spec->beep_amp) {
2463 struct snd_kcontrol_new *knew;
2464 for (knew = alc_beep_mixer; knew->name; knew++) {
2465 struct snd_kcontrol *kctl;
2466 kctl = snd_ctl_new1(knew, codec);
2467 if (!kctl)
2468 return -ENOMEM;
2469 kctl->private_value = spec->beep_amp;
2470 err = snd_hda_ctl_add(codec, kctl);
2471 if (err < 0)
2472 return err;
2476 /* if we have no master control, let's create it */
2477 if (!spec->no_analog &&
2478 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2479 unsigned int vmaster_tlv[4];
2480 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2481 HDA_OUTPUT, vmaster_tlv);
2482 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2483 vmaster_tlv, alc_slave_vols);
2484 if (err < 0)
2485 return err;
2487 if (!spec->no_analog &&
2488 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2489 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2490 NULL, alc_slave_sws);
2491 if (err < 0)
2492 return err;
2495 alc_free_kctls(codec); /* no longer needed */
2496 return 0;
2501 * initialize the codec volumes, etc
2505 * generic initialization of ADC, input mixers and output mixers
2507 static struct hda_verb alc880_volume_init_verbs[] = {
2509 * Unmute ADC0-2 and set the default input to mic-in
2511 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2513 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2514 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2515 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2516 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2518 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2519 * mixer widget
2520 * Note: PASD motherboards uses the Line In 2 as the input for front
2521 * panel mic (mic 2)
2523 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2524 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2525 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2526 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2527 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2528 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2529 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2530 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2533 * Set up output mixers (0x0c - 0x0f)
2535 /* set vol=0 to output mixers */
2536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2539 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2540 /* set up input amps for analog loopback */
2541 /* Amp Indices: DAC = 0, mixer = 1 */
2542 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2543 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2545 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2548 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2549 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2555 * 3-stack pin configuration:
2556 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2558 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2560 * preset connection lists of input pins
2561 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2563 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2564 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2565 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2568 * Set pin mode and muting
2570 /* set front pin widgets 0x14 for output */
2571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2573 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2574 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2575 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2576 /* Mic2 (as headphone out) for HP output */
2577 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2578 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2579 /* Line In pin widget for input */
2580 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2581 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2582 /* Line2 (as front mic) pin widget for input and vref at 80% */
2583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2585 /* CD pin widget for input */
2586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2592 * 5-stack pin configuration:
2593 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2594 * line-in/side = 0x1a, f-mic = 0x1b
2596 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2598 * preset connection lists of input pins
2599 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2601 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2602 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2605 * Set pin mode and muting
2607 /* set pin widgets 0x14-0x17 for output */
2608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2610 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2611 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2612 /* unmute pins for output (no gain on this amp) */
2613 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2616 {0x17, 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 * W810 pin configuration:
2638 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2640 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2641 /* hphone/speaker input selector: front DAC */
2642 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2646 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2648 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2649 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2651 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2652 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2658 * Z71V pin configuration:
2659 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2661 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2665 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2669 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2670 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2676 * 6-stack pin configuration:
2677 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2678 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2680 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2681 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2685 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2686 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2687 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2688 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2689 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2690 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2692 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2696 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2700 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2706 * Uniwill pin configuration:
2707 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2708 * line = 0x1a
2710 static struct hda_verb alc880_uniwill_init_verbs[] = {
2711 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2715 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2716 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2717 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2718 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2719 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2720 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2724 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2726 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2728 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2729 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2730 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2731 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2732 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2733 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2734 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2735 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2736 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2738 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2739 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2745 * Uniwill P53
2746 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2748 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2749 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2751 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2752 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2755 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2756 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2760 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2761 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2764 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2766 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2767 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2768 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2771 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2772 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2777 static struct hda_verb alc880_beep_init_verbs[] = {
2778 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2782 /* auto-toggle front mic */
2783 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2785 unsigned int present;
2786 unsigned char bits;
2788 present = snd_hda_codec_read(codec, 0x18, 0,
2789 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2790 bits = present ? HDA_AMP_MUTE : 0;
2791 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2794 static void alc880_uniwill_setup(struct hda_codec *codec)
2796 struct alc_spec *spec = codec->spec;
2798 spec->autocfg.hp_pins[0] = 0x14;
2799 spec->autocfg.speaker_pins[0] = 0x15;
2800 spec->autocfg.speaker_pins[0] = 0x16;
2803 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2805 alc_automute_amp(codec);
2806 alc880_uniwill_mic_automute(codec);
2809 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2810 unsigned int res)
2812 /* Looks like the unsol event is incompatible with the standard
2813 * definition. 4bit tag is placed at 28 bit!
2815 switch (res >> 28) {
2816 case ALC880_MIC_EVENT:
2817 alc880_uniwill_mic_automute(codec);
2818 break;
2819 default:
2820 alc_automute_amp_unsol_event(codec, res);
2821 break;
2825 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2827 struct alc_spec *spec = codec->spec;
2829 spec->autocfg.hp_pins[0] = 0x14;
2830 spec->autocfg.speaker_pins[0] = 0x15;
2833 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2835 unsigned int present;
2837 present = snd_hda_codec_read(codec, 0x21, 0,
2838 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2839 present &= HDA_AMP_VOLMASK;
2840 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2841 HDA_AMP_VOLMASK, present);
2842 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2843 HDA_AMP_VOLMASK, present);
2846 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2847 unsigned int res)
2849 /* Looks like the unsol event is incompatible with the standard
2850 * definition. 4bit tag is placed at 28 bit!
2852 if ((res >> 28) == ALC880_DCVOL_EVENT)
2853 alc880_uniwill_p53_dcvol_automute(codec);
2854 else
2855 alc_automute_amp_unsol_event(codec, res);
2859 * F1734 pin configuration:
2860 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2862 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2863 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2864 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2865 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2866 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2867 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2874 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2876 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2878 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2879 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2880 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2881 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2882 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2884 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2885 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2891 * ASUS pin configuration:
2892 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2894 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2895 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2896 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2897 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2898 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2900 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2901 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2902 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2904 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2906 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2907 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2909 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2910 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2911 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2912 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2914 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2915 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2916 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2917 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2922 /* Enable GPIO mask and set output */
2923 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2924 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2925 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2927 /* Clevo m520g init */
2928 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2929 /* headphone output */
2930 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2931 /* line-out */
2932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2933 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934 /* Line-in */
2935 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2937 /* CD */
2938 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2939 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2940 /* Mic1 (rear panel) */
2941 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2942 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2943 /* Mic2 (front panel) */
2944 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2945 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2946 /* headphone */
2947 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2948 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2949 /* change to EAPD mode */
2950 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2951 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2956 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2957 /* change to EAPD mode */
2958 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2959 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2961 /* Headphone output */
2962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2963 /* Front output*/
2964 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2965 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2967 /* Line In pin widget for input */
2968 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2969 /* CD pin widget for input */
2970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2971 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2974 /* change to EAPD mode */
2975 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2976 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2982 * LG m1 express dual
2984 * Pin assignment:
2985 * Rear Line-In/Out (blue): 0x14
2986 * Build-in Mic-In: 0x15
2987 * Speaker-out: 0x17
2988 * HP-Out (green): 0x1b
2989 * Mic-In/Out (red): 0x19
2990 * SPDIF-Out: 0x1e
2993 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2994 static hda_nid_t alc880_lg_dac_nids[3] = {
2995 0x05, 0x02, 0x03
2998 /* seems analog CD is not working */
2999 static struct hda_input_mux alc880_lg_capture_source = {
3000 .num_items = 3,
3001 .items = {
3002 { "Mic", 0x1 },
3003 { "Line", 0x5 },
3004 { "Internal Mic", 0x6 },
3008 /* 2,4,6 channel modes */
3009 static struct hda_verb alc880_lg_ch2_init[] = {
3010 /* set line-in and mic-in to input */
3011 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3012 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3016 static struct hda_verb alc880_lg_ch4_init[] = {
3017 /* set line-in to out and mic-in to input */
3018 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3019 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3023 static struct hda_verb alc880_lg_ch6_init[] = {
3024 /* set line-in and mic-in to output */
3025 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3026 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3030 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3031 { 2, alc880_lg_ch2_init },
3032 { 4, alc880_lg_ch4_init },
3033 { 6, alc880_lg_ch6_init },
3036 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3037 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3038 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3039 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3040 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3041 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3042 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3043 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3044 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3047 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3048 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3049 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3050 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3052 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3053 .name = "Channel Mode",
3054 .info = alc_ch_mode_info,
3055 .get = alc_ch_mode_get,
3056 .put = alc_ch_mode_put,
3058 { } /* end */
3061 static struct hda_verb alc880_lg_init_verbs[] = {
3062 /* set capture source to mic-in */
3063 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3064 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3065 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3066 /* mute all amp mixer inputs */
3067 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3068 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3070 /* line-in to input */
3071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3073 /* built-in mic */
3074 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3075 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3076 /* speaker-out */
3077 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3078 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3079 /* mic-in to input */
3080 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3081 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3082 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3083 /* HP-out */
3084 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3085 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3086 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3087 /* jack sense */
3088 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3092 /* toggle speaker-output according to the hp-jack state */
3093 static void alc880_lg_setup(struct hda_codec *codec)
3095 struct alc_spec *spec = codec->spec;
3097 spec->autocfg.hp_pins[0] = 0x1b;
3098 spec->autocfg.speaker_pins[0] = 0x17;
3102 * LG LW20
3104 * Pin assignment:
3105 * Speaker-out: 0x14
3106 * Mic-In: 0x18
3107 * Built-in Mic-In: 0x19
3108 * Line-In: 0x1b
3109 * HP-Out: 0x1a
3110 * SPDIF-Out: 0x1e
3113 static struct hda_input_mux alc880_lg_lw_capture_source = {
3114 .num_items = 3,
3115 .items = {
3116 { "Mic", 0x0 },
3117 { "Internal Mic", 0x1 },
3118 { "Line In", 0x2 },
3122 #define alc880_lg_lw_modes alc880_threestack_modes
3124 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3125 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3126 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3127 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3130 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3131 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3132 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3133 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3134 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3135 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3136 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3137 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3138 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3141 .name = "Channel Mode",
3142 .info = alc_ch_mode_info,
3143 .get = alc_ch_mode_get,
3144 .put = alc_ch_mode_put,
3146 { } /* end */
3149 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3150 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3151 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3152 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3154 /* set capture source to mic-in */
3155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3156 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3159 /* speaker-out */
3160 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3161 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3162 /* HP-out */
3163 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3164 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3165 /* mic-in to input */
3166 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3167 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3168 /* built-in mic */
3169 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3170 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3171 /* jack sense */
3172 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3176 /* toggle speaker-output according to the hp-jack state */
3177 static void alc880_lg_lw_setup(struct hda_codec *codec)
3179 struct alc_spec *spec = codec->spec;
3181 spec->autocfg.hp_pins[0] = 0x1b;
3182 spec->autocfg.speaker_pins[0] = 0x14;
3185 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3186 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3187 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3190 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3191 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3192 { } /* end */
3195 static struct hda_input_mux alc880_medion_rim_capture_source = {
3196 .num_items = 2,
3197 .items = {
3198 { "Mic", 0x0 },
3199 { "Internal Mic", 0x1 },
3203 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3204 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3206 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3207 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3209 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3212 /* Mic2 (as headphone out) for HP output */
3213 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3214 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3215 /* Internal Speaker */
3216 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3217 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3219 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3220 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3222 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3226 /* toggle speaker-output according to the hp-jack state */
3227 static void alc880_medion_rim_automute(struct hda_codec *codec)
3229 struct alc_spec *spec = codec->spec;
3230 alc_automute_amp(codec);
3231 /* toggle EAPD */
3232 if (spec->jack_present)
3233 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3234 else
3235 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3238 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3239 unsigned int res)
3241 /* Looks like the unsol event is incompatible with the standard
3242 * definition. 4bit tag is placed at 28 bit!
3244 if ((res >> 28) == ALC880_HP_EVENT)
3245 alc880_medion_rim_automute(codec);
3248 static void alc880_medion_rim_setup(struct hda_codec *codec)
3250 struct alc_spec *spec = codec->spec;
3252 spec->autocfg.hp_pins[0] = 0x14;
3253 spec->autocfg.speaker_pins[0] = 0x1b;
3256 #ifdef CONFIG_SND_HDA_POWER_SAVE
3257 static struct hda_amp_list alc880_loopbacks[] = {
3258 { 0x0b, HDA_INPUT, 0 },
3259 { 0x0b, HDA_INPUT, 1 },
3260 { 0x0b, HDA_INPUT, 2 },
3261 { 0x0b, HDA_INPUT, 3 },
3262 { 0x0b, HDA_INPUT, 4 },
3263 { } /* end */
3266 static struct hda_amp_list alc880_lg_loopbacks[] = {
3267 { 0x0b, HDA_INPUT, 1 },
3268 { 0x0b, HDA_INPUT, 6 },
3269 { 0x0b, HDA_INPUT, 7 },
3270 { } /* end */
3272 #endif
3275 * Common callbacks
3278 static int alc_init(struct hda_codec *codec)
3280 struct alc_spec *spec = codec->spec;
3281 unsigned int i;
3283 alc_fix_pll(codec);
3284 alc_auto_init_amp(codec, spec->init_amp);
3286 for (i = 0; i < spec->num_init_verbs; i++)
3287 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3289 if (spec->init_hook)
3290 spec->init_hook(codec);
3292 return 0;
3295 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3297 struct alc_spec *spec = codec->spec;
3299 if (spec->unsol_event)
3300 spec->unsol_event(codec, res);
3303 #ifdef CONFIG_SND_HDA_POWER_SAVE
3304 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3306 struct alc_spec *spec = codec->spec;
3307 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3309 #endif
3312 * Analog playback callbacks
3314 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3315 struct hda_codec *codec,
3316 struct snd_pcm_substream *substream)
3318 struct alc_spec *spec = codec->spec;
3319 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3320 hinfo);
3323 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3324 struct hda_codec *codec,
3325 unsigned int stream_tag,
3326 unsigned int format,
3327 struct snd_pcm_substream *substream)
3329 struct alc_spec *spec = codec->spec;
3330 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3331 stream_tag, format, substream);
3334 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3335 struct hda_codec *codec,
3336 struct snd_pcm_substream *substream)
3338 struct alc_spec *spec = codec->spec;
3339 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3343 * Digital out
3345 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3346 struct hda_codec *codec,
3347 struct snd_pcm_substream *substream)
3349 struct alc_spec *spec = codec->spec;
3350 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3353 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3354 struct hda_codec *codec,
3355 unsigned int stream_tag,
3356 unsigned int format,
3357 struct snd_pcm_substream *substream)
3359 struct alc_spec *spec = codec->spec;
3360 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3361 stream_tag, format, substream);
3364 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3365 struct hda_codec *codec,
3366 struct snd_pcm_substream *substream)
3368 struct alc_spec *spec = codec->spec;
3369 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3372 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3373 struct hda_codec *codec,
3374 struct snd_pcm_substream *substream)
3376 struct alc_spec *spec = codec->spec;
3377 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3381 * Analog capture
3383 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3384 struct hda_codec *codec,
3385 unsigned int stream_tag,
3386 unsigned int format,
3387 struct snd_pcm_substream *substream)
3389 struct alc_spec *spec = codec->spec;
3391 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3392 stream_tag, 0, format);
3393 return 0;
3396 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3397 struct hda_codec *codec,
3398 struct snd_pcm_substream *substream)
3400 struct alc_spec *spec = codec->spec;
3402 snd_hda_codec_cleanup_stream(codec,
3403 spec->adc_nids[substream->number + 1]);
3404 return 0;
3410 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3411 .substreams = 1,
3412 .channels_min = 2,
3413 .channels_max = 8,
3414 /* NID is set in alc_build_pcms */
3415 .ops = {
3416 .open = alc880_playback_pcm_open,
3417 .prepare = alc880_playback_pcm_prepare,
3418 .cleanup = alc880_playback_pcm_cleanup
3422 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3423 .substreams = 1,
3424 .channels_min = 2,
3425 .channels_max = 2,
3426 /* NID is set in alc_build_pcms */
3429 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3430 .substreams = 1,
3431 .channels_min = 2,
3432 .channels_max = 2,
3433 /* NID is set in alc_build_pcms */
3436 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3437 .substreams = 2, /* can be overridden */
3438 .channels_min = 2,
3439 .channels_max = 2,
3440 /* NID is set in alc_build_pcms */
3441 .ops = {
3442 .prepare = alc880_alt_capture_pcm_prepare,
3443 .cleanup = alc880_alt_capture_pcm_cleanup
3447 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3448 .substreams = 1,
3449 .channels_min = 2,
3450 .channels_max = 2,
3451 /* NID is set in alc_build_pcms */
3452 .ops = {
3453 .open = alc880_dig_playback_pcm_open,
3454 .close = alc880_dig_playback_pcm_close,
3455 .prepare = alc880_dig_playback_pcm_prepare,
3456 .cleanup = alc880_dig_playback_pcm_cleanup
3460 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3461 .substreams = 1,
3462 .channels_min = 2,
3463 .channels_max = 2,
3464 /* NID is set in alc_build_pcms */
3467 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3468 static struct hda_pcm_stream alc_pcm_null_stream = {
3469 .substreams = 0,
3470 .channels_min = 0,
3471 .channels_max = 0,
3474 static int alc_build_pcms(struct hda_codec *codec)
3476 struct alc_spec *spec = codec->spec;
3477 struct hda_pcm *info = spec->pcm_rec;
3478 int i;
3480 codec->num_pcms = 1;
3481 codec->pcm_info = info;
3483 if (spec->no_analog)
3484 goto skip_analog;
3486 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3487 "%s Analog", codec->chip_name);
3488 info->name = spec->stream_name_analog;
3490 if (spec->stream_analog_playback) {
3491 if (snd_BUG_ON(!spec->multiout.dac_nids))
3492 return -EINVAL;
3493 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3494 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3496 if (spec->stream_analog_capture) {
3497 if (snd_BUG_ON(!spec->adc_nids))
3498 return -EINVAL;
3499 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3500 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3503 if (spec->channel_mode) {
3504 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3505 for (i = 0; i < spec->num_channel_mode; i++) {
3506 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3507 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3512 skip_analog:
3513 /* SPDIF for stream index #1 */
3514 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3515 snprintf(spec->stream_name_digital,
3516 sizeof(spec->stream_name_digital),
3517 "%s Digital", codec->chip_name);
3518 codec->num_pcms = 2;
3519 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3520 info = spec->pcm_rec + 1;
3521 info->name = spec->stream_name_digital;
3522 if (spec->dig_out_type)
3523 info->pcm_type = spec->dig_out_type;
3524 else
3525 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3526 if (spec->multiout.dig_out_nid &&
3527 spec->stream_digital_playback) {
3528 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3529 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3531 if (spec->dig_in_nid &&
3532 spec->stream_digital_capture) {
3533 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3534 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3536 /* FIXME: do we need this for all Realtek codec models? */
3537 codec->spdif_status_reset = 1;
3540 if (spec->no_analog)
3541 return 0;
3543 /* If the use of more than one ADC is requested for the current
3544 * model, configure a second analog capture-only PCM.
3546 /* Additional Analaog capture for index #2 */
3547 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3548 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3549 codec->num_pcms = 3;
3550 info = spec->pcm_rec + 2;
3551 info->name = spec->stream_name_analog;
3552 if (spec->alt_dac_nid) {
3553 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3554 *spec->stream_analog_alt_playback;
3555 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3556 spec->alt_dac_nid;
3557 } else {
3558 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3559 alc_pcm_null_stream;
3560 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3562 if (spec->num_adc_nids > 1) {
3563 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3564 *spec->stream_analog_alt_capture;
3565 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3566 spec->adc_nids[1];
3567 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3568 spec->num_adc_nids - 1;
3569 } else {
3570 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3571 alc_pcm_null_stream;
3572 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3576 return 0;
3579 static void alc_free_kctls(struct hda_codec *codec)
3581 struct alc_spec *spec = codec->spec;
3583 if (spec->kctls.list) {
3584 struct snd_kcontrol_new *kctl = spec->kctls.list;
3585 int i;
3586 for (i = 0; i < spec->kctls.used; i++)
3587 kfree(kctl[i].name);
3589 snd_array_free(&spec->kctls);
3592 static void alc_free(struct hda_codec *codec)
3594 struct alc_spec *spec = codec->spec;
3596 if (!spec)
3597 return;
3599 alc_free_kctls(codec);
3600 kfree(spec);
3601 snd_hda_detach_beep_device(codec);
3604 #ifdef SND_HDA_NEEDS_RESUME
3605 static int alc_resume(struct hda_codec *codec)
3607 codec->patch_ops.init(codec);
3608 snd_hda_codec_resume_amp(codec);
3609 snd_hda_codec_resume_cache(codec);
3610 return 0;
3612 #endif
3616 static struct hda_codec_ops alc_patch_ops = {
3617 .build_controls = alc_build_controls,
3618 .build_pcms = alc_build_pcms,
3619 .init = alc_init,
3620 .free = alc_free,
3621 .unsol_event = alc_unsol_event,
3622 #ifdef SND_HDA_NEEDS_RESUME
3623 .resume = alc_resume,
3624 #endif
3625 #ifdef CONFIG_SND_HDA_POWER_SAVE
3626 .check_power_status = alc_check_power_status,
3627 #endif
3632 * Test configuration for debugging
3634 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3635 * enum controls.
3637 #ifdef CONFIG_SND_DEBUG
3638 static hda_nid_t alc880_test_dac_nids[4] = {
3639 0x02, 0x03, 0x04, 0x05
3642 static struct hda_input_mux alc880_test_capture_source = {
3643 .num_items = 7,
3644 .items = {
3645 { "In-1", 0x0 },
3646 { "In-2", 0x1 },
3647 { "In-3", 0x2 },
3648 { "In-4", 0x3 },
3649 { "CD", 0x4 },
3650 { "Front", 0x5 },
3651 { "Surround", 0x6 },
3655 static struct hda_channel_mode alc880_test_modes[4] = {
3656 { 2, NULL },
3657 { 4, NULL },
3658 { 6, NULL },
3659 { 8, NULL },
3662 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3663 struct snd_ctl_elem_info *uinfo)
3665 static char *texts[] = {
3666 "N/A", "Line Out", "HP Out",
3667 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3669 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3670 uinfo->count = 1;
3671 uinfo->value.enumerated.items = 8;
3672 if (uinfo->value.enumerated.item >= 8)
3673 uinfo->value.enumerated.item = 7;
3674 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3675 return 0;
3678 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3679 struct snd_ctl_elem_value *ucontrol)
3681 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3682 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3683 unsigned int pin_ctl, item = 0;
3685 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3686 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3687 if (pin_ctl & AC_PINCTL_OUT_EN) {
3688 if (pin_ctl & AC_PINCTL_HP_EN)
3689 item = 2;
3690 else
3691 item = 1;
3692 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3693 switch (pin_ctl & AC_PINCTL_VREFEN) {
3694 case AC_PINCTL_VREF_HIZ: item = 3; break;
3695 case AC_PINCTL_VREF_50: item = 4; break;
3696 case AC_PINCTL_VREF_GRD: item = 5; break;
3697 case AC_PINCTL_VREF_80: item = 6; break;
3698 case AC_PINCTL_VREF_100: item = 7; break;
3701 ucontrol->value.enumerated.item[0] = item;
3702 return 0;
3705 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3706 struct snd_ctl_elem_value *ucontrol)
3708 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3709 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3710 static unsigned int ctls[] = {
3711 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3712 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3713 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3714 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3715 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3716 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3718 unsigned int old_ctl, new_ctl;
3720 old_ctl = snd_hda_codec_read(codec, nid, 0,
3721 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3722 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3723 if (old_ctl != new_ctl) {
3724 int val;
3725 snd_hda_codec_write_cache(codec, nid, 0,
3726 AC_VERB_SET_PIN_WIDGET_CONTROL,
3727 new_ctl);
3728 val = ucontrol->value.enumerated.item[0] >= 3 ?
3729 HDA_AMP_MUTE : 0;
3730 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3731 HDA_AMP_MUTE, val);
3732 return 1;
3734 return 0;
3737 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3738 struct snd_ctl_elem_info *uinfo)
3740 static char *texts[] = {
3741 "Front", "Surround", "CLFE", "Side"
3743 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3744 uinfo->count = 1;
3745 uinfo->value.enumerated.items = 4;
3746 if (uinfo->value.enumerated.item >= 4)
3747 uinfo->value.enumerated.item = 3;
3748 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3749 return 0;
3752 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3753 struct snd_ctl_elem_value *ucontrol)
3755 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3756 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3757 unsigned int sel;
3759 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3760 ucontrol->value.enumerated.item[0] = sel & 3;
3761 return 0;
3764 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3765 struct snd_ctl_elem_value *ucontrol)
3767 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3768 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3769 unsigned int sel;
3771 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3772 if (ucontrol->value.enumerated.item[0] != sel) {
3773 sel = ucontrol->value.enumerated.item[0] & 3;
3774 snd_hda_codec_write_cache(codec, nid, 0,
3775 AC_VERB_SET_CONNECT_SEL, sel);
3776 return 1;
3778 return 0;
3781 #define PIN_CTL_TEST(xname,nid) { \
3782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3783 .name = xname, \
3784 .info = alc_test_pin_ctl_info, \
3785 .get = alc_test_pin_ctl_get, \
3786 .put = alc_test_pin_ctl_put, \
3787 .private_value = nid \
3790 #define PIN_SRC_TEST(xname,nid) { \
3791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3792 .name = xname, \
3793 .info = alc_test_pin_src_info, \
3794 .get = alc_test_pin_src_get, \
3795 .put = alc_test_pin_src_put, \
3796 .private_value = nid \
3799 static struct snd_kcontrol_new alc880_test_mixer[] = {
3800 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3801 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3802 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3803 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3804 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3805 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3806 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3807 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3808 PIN_CTL_TEST("Front Pin Mode", 0x14),
3809 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3810 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3811 PIN_CTL_TEST("Side Pin Mode", 0x17),
3812 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3813 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3814 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3815 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3816 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3817 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3818 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3819 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3820 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3821 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3822 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3823 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3824 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3825 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3826 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3827 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3828 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3829 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3831 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3832 .name = "Channel Mode",
3833 .info = alc_ch_mode_info,
3834 .get = alc_ch_mode_get,
3835 .put = alc_ch_mode_put,
3837 { } /* end */
3840 static struct hda_verb alc880_test_init_verbs[] = {
3841 /* Unmute inputs of 0x0c - 0x0f */
3842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3843 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3844 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3845 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3850 /* Vol output for 0x0c-0x0f */
3851 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3852 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3853 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3854 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3855 /* Set output pins 0x14-0x17 */
3856 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3858 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3859 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3860 /* Unmute output pins 0x14-0x17 */
3861 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3862 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3865 /* Set input pins 0x18-0x1c */
3866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3867 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3869 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3870 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3871 /* Mute input pins 0x18-0x1b */
3872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3873 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3874 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3876 /* ADC set up */
3877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3878 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3879 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3880 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3882 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3883 /* Analog input/passthru */
3884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3886 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3887 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3888 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3891 #endif
3896 static const char *alc880_models[ALC880_MODEL_LAST] = {
3897 [ALC880_3ST] = "3stack",
3898 [ALC880_TCL_S700] = "tcl",
3899 [ALC880_3ST_DIG] = "3stack-digout",
3900 [ALC880_CLEVO] = "clevo",
3901 [ALC880_5ST] = "5stack",
3902 [ALC880_5ST_DIG] = "5stack-digout",
3903 [ALC880_W810] = "w810",
3904 [ALC880_Z71V] = "z71v",
3905 [ALC880_6ST] = "6stack",
3906 [ALC880_6ST_DIG] = "6stack-digout",
3907 [ALC880_ASUS] = "asus",
3908 [ALC880_ASUS_W1V] = "asus-w1v",
3909 [ALC880_ASUS_DIG] = "asus-dig",
3910 [ALC880_ASUS_DIG2] = "asus-dig2",
3911 [ALC880_UNIWILL_DIG] = "uniwill",
3912 [ALC880_UNIWILL_P53] = "uniwill-p53",
3913 [ALC880_FUJITSU] = "fujitsu",
3914 [ALC880_F1734] = "F1734",
3915 [ALC880_LG] = "lg",
3916 [ALC880_LG_LW] = "lg-lw",
3917 [ALC880_MEDION_RIM] = "medion",
3918 #ifdef CONFIG_SND_DEBUG
3919 [ALC880_TEST] = "test",
3920 #endif
3921 [ALC880_AUTO] = "auto",
3924 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3925 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3926 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3927 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3928 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3929 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3930 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3931 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3932 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3933 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3934 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3935 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3936 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3937 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3938 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3939 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3940 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3941 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3942 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3943 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3944 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3945 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3946 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3947 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3948 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3949 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3950 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3951 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3952 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3953 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3954 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3955 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3956 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3957 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3958 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3959 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3960 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3961 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3962 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3963 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3964 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3965 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3966 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3967 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3968 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3969 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3970 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3971 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3972 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3973 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3974 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3975 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3976 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3977 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3978 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3979 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3980 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3981 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3982 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3983 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3984 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3985 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3986 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3987 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3988 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3989 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3990 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3991 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3992 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3993 /* default Intel */
3994 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3995 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3996 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4001 * ALC880 codec presets
4003 static struct alc_config_preset alc880_presets[] = {
4004 [ALC880_3ST] = {
4005 .mixers = { alc880_three_stack_mixer },
4006 .init_verbs = { alc880_volume_init_verbs,
4007 alc880_pin_3stack_init_verbs },
4008 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4009 .dac_nids = alc880_dac_nids,
4010 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4011 .channel_mode = alc880_threestack_modes,
4012 .need_dac_fix = 1,
4013 .input_mux = &alc880_capture_source,
4015 [ALC880_3ST_DIG] = {
4016 .mixers = { alc880_three_stack_mixer },
4017 .init_verbs = { alc880_volume_init_verbs,
4018 alc880_pin_3stack_init_verbs },
4019 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4020 .dac_nids = alc880_dac_nids,
4021 .dig_out_nid = ALC880_DIGOUT_NID,
4022 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4023 .channel_mode = alc880_threestack_modes,
4024 .need_dac_fix = 1,
4025 .input_mux = &alc880_capture_source,
4027 [ALC880_TCL_S700] = {
4028 .mixers = { alc880_tcl_s700_mixer },
4029 .init_verbs = { alc880_volume_init_verbs,
4030 alc880_pin_tcl_S700_init_verbs,
4031 alc880_gpio2_init_verbs },
4032 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4033 .dac_nids = alc880_dac_nids,
4034 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4035 .num_adc_nids = 1, /* single ADC */
4036 .hp_nid = 0x03,
4037 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4038 .channel_mode = alc880_2_jack_modes,
4039 .input_mux = &alc880_capture_source,
4041 [ALC880_5ST] = {
4042 .mixers = { alc880_three_stack_mixer,
4043 alc880_five_stack_mixer},
4044 .init_verbs = { alc880_volume_init_verbs,
4045 alc880_pin_5stack_init_verbs },
4046 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4047 .dac_nids = alc880_dac_nids,
4048 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4049 .channel_mode = alc880_fivestack_modes,
4050 .input_mux = &alc880_capture_source,
4052 [ALC880_5ST_DIG] = {
4053 .mixers = { alc880_three_stack_mixer,
4054 alc880_five_stack_mixer },
4055 .init_verbs = { alc880_volume_init_verbs,
4056 alc880_pin_5stack_init_verbs },
4057 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4058 .dac_nids = alc880_dac_nids,
4059 .dig_out_nid = ALC880_DIGOUT_NID,
4060 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4061 .channel_mode = alc880_fivestack_modes,
4062 .input_mux = &alc880_capture_source,
4064 [ALC880_6ST] = {
4065 .mixers = { alc880_six_stack_mixer },
4066 .init_verbs = { alc880_volume_init_verbs,
4067 alc880_pin_6stack_init_verbs },
4068 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4069 .dac_nids = alc880_6st_dac_nids,
4070 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4071 .channel_mode = alc880_sixstack_modes,
4072 .input_mux = &alc880_6stack_capture_source,
4074 [ALC880_6ST_DIG] = {
4075 .mixers = { alc880_six_stack_mixer },
4076 .init_verbs = { alc880_volume_init_verbs,
4077 alc880_pin_6stack_init_verbs },
4078 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4079 .dac_nids = alc880_6st_dac_nids,
4080 .dig_out_nid = ALC880_DIGOUT_NID,
4081 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4082 .channel_mode = alc880_sixstack_modes,
4083 .input_mux = &alc880_6stack_capture_source,
4085 [ALC880_W810] = {
4086 .mixers = { alc880_w810_base_mixer },
4087 .init_verbs = { alc880_volume_init_verbs,
4088 alc880_pin_w810_init_verbs,
4089 alc880_gpio2_init_verbs },
4090 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4091 .dac_nids = alc880_w810_dac_nids,
4092 .dig_out_nid = ALC880_DIGOUT_NID,
4093 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4094 .channel_mode = alc880_w810_modes,
4095 .input_mux = &alc880_capture_source,
4097 [ALC880_Z71V] = {
4098 .mixers = { alc880_z71v_mixer },
4099 .init_verbs = { alc880_volume_init_verbs,
4100 alc880_pin_z71v_init_verbs },
4101 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4102 .dac_nids = alc880_z71v_dac_nids,
4103 .dig_out_nid = ALC880_DIGOUT_NID,
4104 .hp_nid = 0x03,
4105 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4106 .channel_mode = alc880_2_jack_modes,
4107 .input_mux = &alc880_capture_source,
4109 [ALC880_F1734] = {
4110 .mixers = { alc880_f1734_mixer },
4111 .init_verbs = { alc880_volume_init_verbs,
4112 alc880_pin_f1734_init_verbs },
4113 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4114 .dac_nids = alc880_f1734_dac_nids,
4115 .hp_nid = 0x02,
4116 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4117 .channel_mode = alc880_2_jack_modes,
4118 .input_mux = &alc880_f1734_capture_source,
4119 .unsol_event = alc880_uniwill_p53_unsol_event,
4120 .setup = alc880_uniwill_p53_setup,
4121 .init_hook = alc_automute_amp,
4123 [ALC880_ASUS] = {
4124 .mixers = { alc880_asus_mixer },
4125 .init_verbs = { alc880_volume_init_verbs,
4126 alc880_pin_asus_init_verbs,
4127 alc880_gpio1_init_verbs },
4128 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4129 .dac_nids = alc880_asus_dac_nids,
4130 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4131 .channel_mode = alc880_asus_modes,
4132 .need_dac_fix = 1,
4133 .input_mux = &alc880_capture_source,
4135 [ALC880_ASUS_DIG] = {
4136 .mixers = { alc880_asus_mixer },
4137 .init_verbs = { alc880_volume_init_verbs,
4138 alc880_pin_asus_init_verbs,
4139 alc880_gpio1_init_verbs },
4140 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4141 .dac_nids = alc880_asus_dac_nids,
4142 .dig_out_nid = ALC880_DIGOUT_NID,
4143 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4144 .channel_mode = alc880_asus_modes,
4145 .need_dac_fix = 1,
4146 .input_mux = &alc880_capture_source,
4148 [ALC880_ASUS_DIG2] = {
4149 .mixers = { alc880_asus_mixer },
4150 .init_verbs = { alc880_volume_init_verbs,
4151 alc880_pin_asus_init_verbs,
4152 alc880_gpio2_init_verbs }, /* use GPIO2 */
4153 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4154 .dac_nids = alc880_asus_dac_nids,
4155 .dig_out_nid = ALC880_DIGOUT_NID,
4156 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4157 .channel_mode = alc880_asus_modes,
4158 .need_dac_fix = 1,
4159 .input_mux = &alc880_capture_source,
4161 [ALC880_ASUS_W1V] = {
4162 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4163 .init_verbs = { alc880_volume_init_verbs,
4164 alc880_pin_asus_init_verbs,
4165 alc880_gpio1_init_verbs },
4166 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4167 .dac_nids = alc880_asus_dac_nids,
4168 .dig_out_nid = ALC880_DIGOUT_NID,
4169 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4170 .channel_mode = alc880_asus_modes,
4171 .need_dac_fix = 1,
4172 .input_mux = &alc880_capture_source,
4174 [ALC880_UNIWILL_DIG] = {
4175 .mixers = { alc880_asus_mixer },
4176 .init_verbs = { alc880_volume_init_verbs,
4177 alc880_pin_asus_init_verbs },
4178 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4179 .dac_nids = alc880_asus_dac_nids,
4180 .dig_out_nid = ALC880_DIGOUT_NID,
4181 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4182 .channel_mode = alc880_asus_modes,
4183 .need_dac_fix = 1,
4184 .input_mux = &alc880_capture_source,
4186 [ALC880_UNIWILL] = {
4187 .mixers = { alc880_uniwill_mixer },
4188 .init_verbs = { alc880_volume_init_verbs,
4189 alc880_uniwill_init_verbs },
4190 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4191 .dac_nids = alc880_asus_dac_nids,
4192 .dig_out_nid = ALC880_DIGOUT_NID,
4193 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4194 .channel_mode = alc880_threestack_modes,
4195 .need_dac_fix = 1,
4196 .input_mux = &alc880_capture_source,
4197 .unsol_event = alc880_uniwill_unsol_event,
4198 .setup = alc880_uniwill_setup,
4199 .init_hook = alc880_uniwill_init_hook,
4201 [ALC880_UNIWILL_P53] = {
4202 .mixers = { alc880_uniwill_p53_mixer },
4203 .init_verbs = { alc880_volume_init_verbs,
4204 alc880_uniwill_p53_init_verbs },
4205 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4206 .dac_nids = alc880_asus_dac_nids,
4207 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4208 .channel_mode = alc880_threestack_modes,
4209 .input_mux = &alc880_capture_source,
4210 .unsol_event = alc880_uniwill_p53_unsol_event,
4211 .setup = alc880_uniwill_p53_setup,
4212 .init_hook = alc_automute_amp,
4214 [ALC880_FUJITSU] = {
4215 .mixers = { alc880_fujitsu_mixer },
4216 .init_verbs = { alc880_volume_init_verbs,
4217 alc880_uniwill_p53_init_verbs,
4218 alc880_beep_init_verbs },
4219 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4220 .dac_nids = alc880_dac_nids,
4221 .dig_out_nid = ALC880_DIGOUT_NID,
4222 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4223 .channel_mode = alc880_2_jack_modes,
4224 .input_mux = &alc880_capture_source,
4225 .unsol_event = alc880_uniwill_p53_unsol_event,
4226 .setup = alc880_uniwill_p53_setup,
4227 .init_hook = alc_automute_amp,
4229 [ALC880_CLEVO] = {
4230 .mixers = { alc880_three_stack_mixer },
4231 .init_verbs = { alc880_volume_init_verbs,
4232 alc880_pin_clevo_init_verbs },
4233 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4234 .dac_nids = alc880_dac_nids,
4235 .hp_nid = 0x03,
4236 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4237 .channel_mode = alc880_threestack_modes,
4238 .need_dac_fix = 1,
4239 .input_mux = &alc880_capture_source,
4241 [ALC880_LG] = {
4242 .mixers = { alc880_lg_mixer },
4243 .init_verbs = { alc880_volume_init_verbs,
4244 alc880_lg_init_verbs },
4245 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4246 .dac_nids = alc880_lg_dac_nids,
4247 .dig_out_nid = ALC880_DIGOUT_NID,
4248 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4249 .channel_mode = alc880_lg_ch_modes,
4250 .need_dac_fix = 1,
4251 .input_mux = &alc880_lg_capture_source,
4252 .unsol_event = alc_automute_amp_unsol_event,
4253 .setup = alc880_lg_setup,
4254 .init_hook = alc_automute_amp,
4255 #ifdef CONFIG_SND_HDA_POWER_SAVE
4256 .loopbacks = alc880_lg_loopbacks,
4257 #endif
4259 [ALC880_LG_LW] = {
4260 .mixers = { alc880_lg_lw_mixer },
4261 .init_verbs = { alc880_volume_init_verbs,
4262 alc880_lg_lw_init_verbs },
4263 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4264 .dac_nids = alc880_dac_nids,
4265 .dig_out_nid = ALC880_DIGOUT_NID,
4266 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4267 .channel_mode = alc880_lg_lw_modes,
4268 .input_mux = &alc880_lg_lw_capture_source,
4269 .unsol_event = alc_automute_amp_unsol_event,
4270 .setup = alc880_lg_lw_setup,
4271 .init_hook = alc_automute_amp,
4273 [ALC880_MEDION_RIM] = {
4274 .mixers = { alc880_medion_rim_mixer },
4275 .init_verbs = { alc880_volume_init_verbs,
4276 alc880_medion_rim_init_verbs,
4277 alc_gpio2_init_verbs },
4278 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4279 .dac_nids = alc880_dac_nids,
4280 .dig_out_nid = ALC880_DIGOUT_NID,
4281 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4282 .channel_mode = alc880_2_jack_modes,
4283 .input_mux = &alc880_medion_rim_capture_source,
4284 .unsol_event = alc880_medion_rim_unsol_event,
4285 .setup = alc880_medion_rim_setup,
4286 .init_hook = alc880_medion_rim_automute,
4288 #ifdef CONFIG_SND_DEBUG
4289 [ALC880_TEST] = {
4290 .mixers = { alc880_test_mixer },
4291 .init_verbs = { alc880_test_init_verbs },
4292 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4293 .dac_nids = alc880_test_dac_nids,
4294 .dig_out_nid = ALC880_DIGOUT_NID,
4295 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4296 .channel_mode = alc880_test_modes,
4297 .input_mux = &alc880_test_capture_source,
4299 #endif
4303 * Automatic parse of I/O pins from the BIOS configuration
4306 enum {
4307 ALC_CTL_WIDGET_VOL,
4308 ALC_CTL_WIDGET_MUTE,
4309 ALC_CTL_BIND_MUTE,
4311 static struct snd_kcontrol_new alc880_control_templates[] = {
4312 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4313 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4314 HDA_BIND_MUTE(NULL, 0, 0, 0),
4317 /* add dynamic controls */
4318 static int add_control(struct alc_spec *spec, int type, const char *name,
4319 unsigned long val)
4321 struct snd_kcontrol_new *knew;
4323 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4324 knew = snd_array_new(&spec->kctls);
4325 if (!knew)
4326 return -ENOMEM;
4327 *knew = alc880_control_templates[type];
4328 knew->name = kstrdup(name, GFP_KERNEL);
4329 if (!knew->name)
4330 return -ENOMEM;
4331 knew->private_value = val;
4332 return 0;
4335 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4336 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4337 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4338 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4339 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4340 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4341 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4342 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4343 #define ALC880_PIN_CD_NID 0x1c
4345 /* fill in the dac_nids table from the parsed pin configuration */
4346 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4347 const struct auto_pin_cfg *cfg)
4349 hda_nid_t nid;
4350 int assigned[4];
4351 int i, j;
4353 memset(assigned, 0, sizeof(assigned));
4354 spec->multiout.dac_nids = spec->private_dac_nids;
4356 /* check the pins hardwired to audio widget */
4357 for (i = 0; i < cfg->line_outs; i++) {
4358 nid = cfg->line_out_pins[i];
4359 if (alc880_is_fixed_pin(nid)) {
4360 int idx = alc880_fixed_pin_idx(nid);
4361 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4362 assigned[idx] = 1;
4365 /* left pins can be connect to any audio widget */
4366 for (i = 0; i < cfg->line_outs; i++) {
4367 nid = cfg->line_out_pins[i];
4368 if (alc880_is_fixed_pin(nid))
4369 continue;
4370 /* search for an empty channel */
4371 for (j = 0; j < cfg->line_outs; j++) {
4372 if (!assigned[j]) {
4373 spec->multiout.dac_nids[i] =
4374 alc880_idx_to_dac(j);
4375 assigned[j] = 1;
4376 break;
4380 spec->multiout.num_dacs = cfg->line_outs;
4381 return 0;
4384 /* add playback controls from the parsed DAC table */
4385 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4386 const struct auto_pin_cfg *cfg)
4388 char name[32];
4389 static const char *chname[4] = {
4390 "Front", "Surround", NULL /*CLFE*/, "Side"
4392 hda_nid_t nid;
4393 int i, err;
4395 for (i = 0; i < cfg->line_outs; i++) {
4396 if (!spec->multiout.dac_nids[i])
4397 continue;
4398 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4399 if (i == 2) {
4400 /* Center/LFE */
4401 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4402 "Center Playback Volume",
4403 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4404 HDA_OUTPUT));
4405 if (err < 0)
4406 return err;
4407 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4408 "LFE Playback Volume",
4409 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4410 HDA_OUTPUT));
4411 if (err < 0)
4412 return err;
4413 err = add_control(spec, ALC_CTL_BIND_MUTE,
4414 "Center Playback Switch",
4415 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4416 HDA_INPUT));
4417 if (err < 0)
4418 return err;
4419 err = add_control(spec, ALC_CTL_BIND_MUTE,
4420 "LFE Playback Switch",
4421 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4422 HDA_INPUT));
4423 if (err < 0)
4424 return err;
4425 } else {
4426 const char *pfx;
4427 if (cfg->line_outs == 1 &&
4428 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4429 pfx = "Speaker";
4430 else
4431 pfx = chname[i];
4432 sprintf(name, "%s Playback Volume", pfx);
4433 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4434 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4435 HDA_OUTPUT));
4436 if (err < 0)
4437 return err;
4438 sprintf(name, "%s Playback Switch", pfx);
4439 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4440 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4441 HDA_INPUT));
4442 if (err < 0)
4443 return err;
4446 return 0;
4449 /* add playback controls for speaker and HP outputs */
4450 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4451 const char *pfx)
4453 hda_nid_t nid;
4454 int err;
4455 char name[32];
4457 if (!pin)
4458 return 0;
4460 if (alc880_is_fixed_pin(pin)) {
4461 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4462 /* specify the DAC as the extra output */
4463 if (!spec->multiout.hp_nid)
4464 spec->multiout.hp_nid = nid;
4465 else
4466 spec->multiout.extra_out_nid[0] = nid;
4467 /* control HP volume/switch on the output mixer amp */
4468 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4469 sprintf(name, "%s Playback Volume", pfx);
4470 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4471 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4472 if (err < 0)
4473 return err;
4474 sprintf(name, "%s Playback Switch", pfx);
4475 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4476 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4477 if (err < 0)
4478 return err;
4479 } else if (alc880_is_multi_pin(pin)) {
4480 /* set manual connection */
4481 /* we have only a switch on HP-out PIN */
4482 sprintf(name, "%s Playback Switch", pfx);
4483 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4484 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4485 if (err < 0)
4486 return err;
4488 return 0;
4491 /* create input playback/capture controls for the given pin */
4492 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4493 const char *ctlname,
4494 int idx, hda_nid_t mix_nid)
4496 char name[32];
4497 int err;
4499 sprintf(name, "%s Playback Volume", ctlname);
4500 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4501 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4502 if (err < 0)
4503 return err;
4504 sprintf(name, "%s Playback Switch", ctlname);
4505 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4506 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4507 if (err < 0)
4508 return err;
4509 return 0;
4512 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4514 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4515 return (pincap & AC_PINCAP_IN) != 0;
4518 /* create playback/capture controls for input pins */
4519 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4520 const struct auto_pin_cfg *cfg,
4521 hda_nid_t mixer,
4522 hda_nid_t cap1, hda_nid_t cap2)
4524 struct alc_spec *spec = codec->spec;
4525 struct hda_input_mux *imux = &spec->private_imux[0];
4526 int i, err, idx;
4528 for (i = 0; i < AUTO_PIN_LAST; i++) {
4529 hda_nid_t pin;
4531 pin = cfg->input_pins[i];
4532 if (!alc_is_input_pin(codec, pin))
4533 continue;
4535 if (mixer) {
4536 idx = get_connection_index(codec, mixer, pin);
4537 if (idx >= 0) {
4538 err = new_analog_input(spec, pin,
4539 auto_pin_cfg_labels[i],
4540 idx, mixer);
4541 if (err < 0)
4542 return err;
4546 if (!cap1)
4547 continue;
4548 idx = get_connection_index(codec, cap1, pin);
4549 if (idx < 0 && cap2)
4550 idx = get_connection_index(codec, cap2, pin);
4551 if (idx >= 0) {
4552 imux->items[imux->num_items].label =
4553 auto_pin_cfg_labels[i];
4554 imux->items[imux->num_items].index = idx;
4555 imux->num_items++;
4558 return 0;
4561 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4562 const struct auto_pin_cfg *cfg)
4564 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4567 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4568 unsigned int pin_type)
4570 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4571 pin_type);
4572 /* unmute pin */
4573 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4574 AMP_OUT_UNMUTE);
4577 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4578 hda_nid_t nid, int pin_type,
4579 int dac_idx)
4581 alc_set_pin_output(codec, nid, pin_type);
4582 /* need the manual connection? */
4583 if (alc880_is_multi_pin(nid)) {
4584 struct alc_spec *spec = codec->spec;
4585 int idx = alc880_multi_pin_idx(nid);
4586 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4587 AC_VERB_SET_CONNECT_SEL,
4588 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4592 static int get_pin_type(int line_out_type)
4594 if (line_out_type == AUTO_PIN_HP_OUT)
4595 return PIN_HP;
4596 else
4597 return PIN_OUT;
4600 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4602 struct alc_spec *spec = codec->spec;
4603 int i;
4605 for (i = 0; i < spec->autocfg.line_outs; i++) {
4606 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4607 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4608 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4612 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4614 struct alc_spec *spec = codec->spec;
4615 hda_nid_t pin;
4617 pin = spec->autocfg.speaker_pins[0];
4618 if (pin) /* connect to front */
4619 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4620 pin = spec->autocfg.hp_pins[0];
4621 if (pin) /* connect to front */
4622 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4625 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4627 struct alc_spec *spec = codec->spec;
4628 int i;
4630 for (i = 0; i < AUTO_PIN_LAST; i++) {
4631 hda_nid_t nid = spec->autocfg.input_pins[i];
4632 if (alc_is_input_pin(codec, nid)) {
4633 alc_set_input_pin(codec, nid, i);
4634 if (nid != ALC880_PIN_CD_NID &&
4635 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4636 snd_hda_codec_write(codec, nid, 0,
4637 AC_VERB_SET_AMP_GAIN_MUTE,
4638 AMP_OUT_MUTE);
4643 /* parse the BIOS configuration and set up the alc_spec */
4644 /* return 1 if successful, 0 if the proper config is not found,
4645 * or a negative error code
4647 static int alc880_parse_auto_config(struct hda_codec *codec)
4649 struct alc_spec *spec = codec->spec;
4650 int i, err;
4651 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4653 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4654 alc880_ignore);
4655 if (err < 0)
4656 return err;
4657 if (!spec->autocfg.line_outs)
4658 return 0; /* can't find valid BIOS pin config */
4660 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4661 if (err < 0)
4662 return err;
4663 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4664 if (err < 0)
4665 return err;
4666 err = alc880_auto_create_extra_out(spec,
4667 spec->autocfg.speaker_pins[0],
4668 "Speaker");
4669 if (err < 0)
4670 return err;
4671 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4672 "Headphone");
4673 if (err < 0)
4674 return err;
4675 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4676 if (err < 0)
4677 return err;
4679 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4681 /* check multiple SPDIF-out (for recent codecs) */
4682 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4683 hda_nid_t dig_nid;
4684 err = snd_hda_get_connections(codec,
4685 spec->autocfg.dig_out_pins[i],
4686 &dig_nid, 1);
4687 if (err < 0)
4688 continue;
4689 if (!i)
4690 spec->multiout.dig_out_nid = dig_nid;
4691 else {
4692 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4693 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4694 break;
4695 spec->slave_dig_outs[i - 1] = dig_nid;
4698 if (spec->autocfg.dig_in_pin)
4699 spec->dig_in_nid = ALC880_DIGIN_NID;
4701 if (spec->kctls.list)
4702 add_mixer(spec, spec->kctls.list);
4704 add_verb(spec, alc880_volume_init_verbs);
4706 spec->num_mux_defs = 1;
4707 spec->input_mux = &spec->private_imux[0];
4709 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4711 return 1;
4714 /* additional initialization for auto-configuration model */
4715 static void alc880_auto_init(struct hda_codec *codec)
4717 struct alc_spec *spec = codec->spec;
4718 alc880_auto_init_multi_out(codec);
4719 alc880_auto_init_extra_out(codec);
4720 alc880_auto_init_analog_input(codec);
4721 if (spec->unsol_event)
4722 alc_inithook(codec);
4725 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4726 * one of two digital mic pins, e.g. on ALC272
4728 static void fixup_automic_adc(struct hda_codec *codec)
4730 struct alc_spec *spec = codec->spec;
4731 int i;
4733 for (i = 0; i < spec->num_adc_nids; i++) {
4734 hda_nid_t cap = spec->capsrc_nids ?
4735 spec->capsrc_nids[i] : spec->adc_nids[i];
4736 int iidx, eidx;
4738 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4739 if (iidx < 0)
4740 continue;
4741 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4742 if (eidx < 0)
4743 continue;
4744 spec->int_mic.mux_idx = iidx;
4745 spec->ext_mic.mux_idx = eidx;
4746 if (spec->capsrc_nids)
4747 spec->capsrc_nids += i;
4748 spec->adc_nids += i;
4749 spec->num_adc_nids = 1;
4750 return;
4752 snd_printd(KERN_INFO "hda_codec: %s: "
4753 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4754 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4755 spec->auto_mic = 0; /* disable auto-mic to be sure */
4758 static void set_capture_mixer(struct hda_codec *codec)
4760 struct alc_spec *spec = codec->spec;
4761 static struct snd_kcontrol_new *caps[2][3] = {
4762 { alc_capture_mixer_nosrc1,
4763 alc_capture_mixer_nosrc2,
4764 alc_capture_mixer_nosrc3 },
4765 { alc_capture_mixer1,
4766 alc_capture_mixer2,
4767 alc_capture_mixer3 },
4769 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4770 int mux;
4771 if (spec->auto_mic) {
4772 mux = 0;
4773 fixup_automic_adc(codec);
4774 } else if (spec->input_mux && spec->input_mux->num_items > 1)
4775 mux = 1;
4776 else
4777 mux = 0;
4778 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4782 #define set_beep_amp(spec, nid, idx, dir) \
4783 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4786 * OK, here we have finally the patch for ALC880
4789 static int patch_alc880(struct hda_codec *codec)
4791 struct alc_spec *spec;
4792 int board_config;
4793 int err;
4795 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4796 if (spec == NULL)
4797 return -ENOMEM;
4799 codec->spec = spec;
4801 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4802 alc880_models,
4803 alc880_cfg_tbl);
4804 if (board_config < 0) {
4805 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4806 codec->chip_name);
4807 board_config = ALC880_AUTO;
4810 if (board_config == ALC880_AUTO) {
4811 /* automatic parse from the BIOS config */
4812 err = alc880_parse_auto_config(codec);
4813 if (err < 0) {
4814 alc_free(codec);
4815 return err;
4816 } else if (!err) {
4817 printk(KERN_INFO
4818 "hda_codec: Cannot set up configuration "
4819 "from BIOS. Using 3-stack mode...\n");
4820 board_config = ALC880_3ST;
4824 err = snd_hda_attach_beep_device(codec, 0x1);
4825 if (err < 0) {
4826 alc_free(codec);
4827 return err;
4830 if (board_config != ALC880_AUTO)
4831 setup_preset(codec, &alc880_presets[board_config]);
4833 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4834 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4835 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4837 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4838 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4840 if (!spec->adc_nids && spec->input_mux) {
4841 /* check whether NID 0x07 is valid */
4842 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4843 /* get type */
4844 wcap = get_wcaps_type(wcap);
4845 if (wcap != AC_WID_AUD_IN) {
4846 spec->adc_nids = alc880_adc_nids_alt;
4847 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4848 } else {
4849 spec->adc_nids = alc880_adc_nids;
4850 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4853 set_capture_mixer(codec);
4854 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4856 spec->vmaster_nid = 0x0c;
4858 codec->patch_ops = alc_patch_ops;
4859 if (board_config == ALC880_AUTO)
4860 spec->init_hook = alc880_auto_init;
4861 #ifdef CONFIG_SND_HDA_POWER_SAVE
4862 if (!spec->loopback.amplist)
4863 spec->loopback.amplist = alc880_loopbacks;
4864 #endif
4865 codec->proc_widget_hook = print_realtek_coef;
4867 return 0;
4872 * ALC260 support
4875 static hda_nid_t alc260_dac_nids[1] = {
4876 /* front */
4877 0x02,
4880 static hda_nid_t alc260_adc_nids[1] = {
4881 /* ADC0 */
4882 0x04,
4885 static hda_nid_t alc260_adc_nids_alt[1] = {
4886 /* ADC1 */
4887 0x05,
4890 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4891 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4893 static hda_nid_t alc260_dual_adc_nids[2] = {
4894 /* ADC0, ADC1 */
4895 0x04, 0x05
4898 #define ALC260_DIGOUT_NID 0x03
4899 #define ALC260_DIGIN_NID 0x06
4901 static struct hda_input_mux alc260_capture_source = {
4902 .num_items = 4,
4903 .items = {
4904 { "Mic", 0x0 },
4905 { "Front Mic", 0x1 },
4906 { "Line", 0x2 },
4907 { "CD", 0x4 },
4911 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4912 * headphone jack and the internal CD lines since these are the only pins at
4913 * which audio can appear. For flexibility, also allow the option of
4914 * recording the mixer output on the second ADC (ADC0 doesn't have a
4915 * connection to the mixer output).
4917 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4919 .num_items = 3,
4920 .items = {
4921 { "Mic/Line", 0x0 },
4922 { "CD", 0x4 },
4923 { "Headphone", 0x2 },
4927 .num_items = 4,
4928 .items = {
4929 { "Mic/Line", 0x0 },
4930 { "CD", 0x4 },
4931 { "Headphone", 0x2 },
4932 { "Mixer", 0x5 },
4938 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4939 * the Fujitsu S702x, but jacks are marked differently.
4941 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4943 .num_items = 4,
4944 .items = {
4945 { "Mic", 0x0 },
4946 { "Line", 0x2 },
4947 { "CD", 0x4 },
4948 { "Headphone", 0x5 },
4952 .num_items = 5,
4953 .items = {
4954 { "Mic", 0x0 },
4955 { "Line", 0x2 },
4956 { "CD", 0x4 },
4957 { "Headphone", 0x6 },
4958 { "Mixer", 0x5 },
4963 /* Maxdata Favorit 100XS */
4964 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4966 .num_items = 2,
4967 .items = {
4968 { "Line/Mic", 0x0 },
4969 { "CD", 0x4 },
4973 .num_items = 3,
4974 .items = {
4975 { "Line/Mic", 0x0 },
4976 { "CD", 0x4 },
4977 { "Mixer", 0x5 },
4983 * This is just place-holder, so there's something for alc_build_pcms to look
4984 * at when it calculates the maximum number of channels. ALC260 has no mixer
4985 * element which allows changing the channel mode, so the verb list is
4986 * never used.
4988 static struct hda_channel_mode alc260_modes[1] = {
4989 { 2, NULL },
4993 /* Mixer combinations
4995 * basic: base_output + input + pc_beep + capture
4996 * HP: base_output + input + capture_alt
4997 * HP_3013: hp_3013 + input + capture
4998 * fujitsu: fujitsu + capture
4999 * acer: acer + capture
5002 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5003 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5004 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5005 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5006 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5007 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5008 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5009 { } /* end */
5012 static struct snd_kcontrol_new alc260_input_mixer[] = {
5013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5015 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5016 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5018 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5020 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5021 { } /* end */
5024 /* update HP, line and mono out pins according to the master switch */
5025 static void alc260_hp_master_update(struct hda_codec *codec,
5026 hda_nid_t hp, hda_nid_t line,
5027 hda_nid_t mono)
5029 struct alc_spec *spec = codec->spec;
5030 unsigned int val = spec->master_sw ? PIN_HP : 0;
5031 /* change HP and line-out pins */
5032 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5033 val);
5034 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5035 val);
5036 /* mono (speaker) depending on the HP jack sense */
5037 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5038 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5039 val);
5042 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5043 struct snd_ctl_elem_value *ucontrol)
5045 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5046 struct alc_spec *spec = codec->spec;
5047 *ucontrol->value.integer.value = spec->master_sw;
5048 return 0;
5051 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5052 struct snd_ctl_elem_value *ucontrol)
5054 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5055 struct alc_spec *spec = codec->spec;
5056 int val = !!*ucontrol->value.integer.value;
5057 hda_nid_t hp, line, mono;
5059 if (val == spec->master_sw)
5060 return 0;
5061 spec->master_sw = val;
5062 hp = (kcontrol->private_value >> 16) & 0xff;
5063 line = (kcontrol->private_value >> 8) & 0xff;
5064 mono = kcontrol->private_value & 0xff;
5065 alc260_hp_master_update(codec, hp, line, mono);
5066 return 1;
5069 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5072 .name = "Master Playback Switch",
5073 .info = snd_ctl_boolean_mono_info,
5074 .get = alc260_hp_master_sw_get,
5075 .put = alc260_hp_master_sw_put,
5076 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5078 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5079 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5081 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5082 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5083 HDA_OUTPUT),
5084 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5085 { } /* end */
5088 static struct hda_verb alc260_hp_unsol_verbs[] = {
5089 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5093 static void alc260_hp_automute(struct hda_codec *codec)
5095 struct alc_spec *spec = codec->spec;
5096 unsigned int present;
5098 present = snd_hda_codec_read(codec, 0x10, 0,
5099 AC_VERB_GET_PIN_SENSE, 0);
5100 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5101 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5104 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5106 if ((res >> 26) == ALC880_HP_EVENT)
5107 alc260_hp_automute(codec);
5110 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5112 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5113 .name = "Master Playback Switch",
5114 .info = snd_ctl_boolean_mono_info,
5115 .get = alc260_hp_master_sw_get,
5116 .put = alc260_hp_master_sw_put,
5117 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5119 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5120 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5121 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5122 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5123 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5125 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5126 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5127 { } /* end */
5130 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5131 .ops = &snd_hda_bind_vol,
5132 .values = {
5133 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5134 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5135 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5140 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5141 .ops = &snd_hda_bind_sw,
5142 .values = {
5143 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5144 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5149 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5150 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5151 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5152 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5154 { } /* end */
5157 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5158 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5162 static void alc260_hp_3013_automute(struct hda_codec *codec)
5164 struct alc_spec *spec = codec->spec;
5165 unsigned int present;
5167 present = snd_hda_codec_read(codec, 0x15, 0,
5168 AC_VERB_GET_PIN_SENSE, 0);
5169 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
5170 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5173 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5174 unsigned int res)
5176 if ((res >> 26) == ALC880_HP_EVENT)
5177 alc260_hp_3013_automute(codec);
5180 static void alc260_hp_3012_automute(struct hda_codec *codec)
5182 unsigned int present, bits;
5184 present = snd_hda_codec_read(codec, 0x10, 0,
5185 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
5187 bits = present ? 0 : PIN_OUT;
5188 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5189 bits);
5190 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5191 bits);
5192 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5193 bits);
5196 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5197 unsigned int res)
5199 if ((res >> 26) == ALC880_HP_EVENT)
5200 alc260_hp_3012_automute(codec);
5203 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5204 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5206 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5208 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5209 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5210 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5211 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5212 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5213 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5214 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5215 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5216 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5217 { } /* end */
5220 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5221 * versions of the ALC260 don't act on requests to enable mic bias from NID
5222 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5223 * datasheet doesn't mention this restriction. At this stage it's not clear
5224 * whether this behaviour is intentional or is a hardware bug in chip
5225 * revisions available in early 2006. Therefore for now allow the
5226 * "Headphone Jack Mode" control to span all choices, but if it turns out
5227 * that the lack of mic bias for this NID is intentional we could change the
5228 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5230 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5231 * don't appear to make the mic bias available from the "line" jack, even
5232 * though the NID used for this jack (0x14) can supply it. The theory is
5233 * that perhaps Acer have included blocking capacitors between the ALC260
5234 * and the output jack. If this turns out to be the case for all such
5235 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5236 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5238 * The C20x Tablet series have a mono internal speaker which is controlled
5239 * via the chip's Mono sum widget and pin complex, so include the necessary
5240 * controls for such models. On models without a "mono speaker" the control
5241 * won't do anything.
5243 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5244 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5245 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5246 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5247 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5248 HDA_OUTPUT),
5249 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5250 HDA_INPUT),
5251 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5252 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5254 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5255 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5256 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5257 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5258 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5259 { } /* end */
5262 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5264 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5265 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5266 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5267 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5268 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5269 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5270 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5271 { } /* end */
5274 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5275 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5277 static struct snd_kcontrol_new alc260_will_mixer[] = {
5278 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5279 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5281 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5282 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5283 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5284 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5285 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5286 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5287 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5288 { } /* end */
5291 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5292 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5294 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5295 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5296 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5297 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5298 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5299 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5300 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5301 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5302 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5303 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5304 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5305 { } /* end */
5309 * initialization verbs
5311 static struct hda_verb alc260_init_verbs[] = {
5312 /* Line In pin widget for input */
5313 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5314 /* CD pin widget for input */
5315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5316 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5317 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5318 /* Mic2 (front panel) pin widget for input and vref at 80% */
5319 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5320 /* LINE-2 is used for line-out in rear */
5321 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5322 /* select line-out */
5323 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5324 /* LINE-OUT pin */
5325 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5326 /* enable HP */
5327 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5328 /* enable Mono */
5329 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5330 /* mute capture amp left and right */
5331 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5332 /* set connection select to line in (default select for this ADC) */
5333 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5334 /* mute capture amp left and right */
5335 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5336 /* set connection select to line in (default select for this ADC) */
5337 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5338 /* set vol=0 Line-Out mixer amp left and right */
5339 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5340 /* unmute pin widget amp left and right (no gain on this amp) */
5341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5342 /* set vol=0 HP mixer amp left and right */
5343 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5344 /* unmute pin widget amp left and right (no gain on this amp) */
5345 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5346 /* set vol=0 Mono mixer amp left and right */
5347 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5348 /* unmute pin widget amp left and right (no gain on this amp) */
5349 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5350 /* unmute LINE-2 out pin */
5351 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5352 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5353 * Line In 2 = 0x03
5355 /* mute analog inputs */
5356 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5359 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5360 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5361 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5362 /* mute Front out path */
5363 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5365 /* mute Headphone out path */
5366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5367 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5368 /* mute Mono out path */
5369 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5370 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5374 #if 0 /* should be identical with alc260_init_verbs? */
5375 static struct hda_verb alc260_hp_init_verbs[] = {
5376 /* Headphone and output */
5377 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5378 /* mono output */
5379 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5380 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5381 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5382 /* Mic2 (front panel) pin widget for input and vref at 80% */
5383 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5384 /* Line In pin widget for input */
5385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5386 /* Line-2 pin widget for output */
5387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5388 /* CD pin widget for input */
5389 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5390 /* unmute amp left and right */
5391 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5392 /* set connection select to line in (default select for this ADC) */
5393 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5394 /* unmute Line-Out mixer amp left and right (volume = 0) */
5395 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5396 /* mute pin widget amp left and right (no gain on this amp) */
5397 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5398 /* unmute HP mixer amp left and right (volume = 0) */
5399 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5400 /* mute pin widget amp left and right (no gain on this amp) */
5401 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5402 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5403 * Line In 2 = 0x03
5405 /* mute analog inputs */
5406 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5408 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5409 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5410 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5411 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5412 /* Unmute Front out path */
5413 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5414 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5415 /* Unmute Headphone out path */
5416 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5418 /* Unmute Mono out path */
5419 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5420 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5423 #endif
5425 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5426 /* Line out and output */
5427 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5428 /* mono output */
5429 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5430 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5432 /* Mic2 (front panel) pin widget for input and vref at 80% */
5433 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5434 /* Line In pin widget for input */
5435 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5436 /* Headphone pin widget for output */
5437 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5438 /* CD pin widget for input */
5439 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5440 /* unmute amp left and right */
5441 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5442 /* set connection select to line in (default select for this ADC) */
5443 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5444 /* unmute Line-Out mixer amp left and right (volume = 0) */
5445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5446 /* mute pin widget amp left and right (no gain on this amp) */
5447 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5448 /* unmute HP mixer amp left and right (volume = 0) */
5449 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5450 /* mute pin widget amp left and right (no gain on this amp) */
5451 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5452 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5453 * Line In 2 = 0x03
5455 /* mute analog inputs */
5456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5458 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5459 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5460 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5461 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5462 /* Unmute Front out path */
5463 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5464 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5465 /* Unmute Headphone out path */
5466 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5468 /* Unmute Mono out path */
5469 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5470 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5474 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5475 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5476 * audio = 0x16, internal speaker = 0x10.
5478 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5479 /* Disable all GPIOs */
5480 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5481 /* Internal speaker is connected to headphone pin */
5482 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5483 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5484 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5485 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5486 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5487 /* Ensure all other unused pins are disabled and muted. */
5488 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5489 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5490 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5491 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5493 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5495 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5497 /* Disable digital (SPDIF) pins */
5498 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5499 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5501 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5502 * when acting as an output.
5504 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5506 /* Start with output sum widgets muted and their output gains at min */
5507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5508 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5512 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5514 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5515 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5517 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5518 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5519 /* Unmute Line1 pin widget output buffer since it starts as an output.
5520 * If the pin mode is changed by the user the pin mode control will
5521 * take care of enabling the pin's input/output buffers as needed.
5522 * Therefore there's no need to enable the input buffer at this
5523 * stage.
5525 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5526 /* Unmute input buffer of pin widget used for Line-in (no equiv
5527 * mixer ctrl)
5529 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5531 /* Mute capture amp left and right */
5532 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5533 /* Set ADC connection select to match default mixer setting - line
5534 * in (on mic1 pin)
5536 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5538 /* Do the same for the second ADC: mute capture input amp and
5539 * set ADC connection to line in (on mic1 pin)
5541 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5542 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5544 /* Mute all inputs to mixer widget (even unconnected ones) */
5545 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5546 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5547 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5557 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5558 * similar laptops (adapted from Fujitsu init verbs).
5560 static struct hda_verb alc260_acer_init_verbs[] = {
5561 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5562 * the headphone jack. Turn this on and rely on the standard mute
5563 * methods whenever the user wants to turn these outputs off.
5565 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5566 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5567 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5568 /* Internal speaker/Headphone jack is connected to Line-out pin */
5569 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5570 /* Internal microphone/Mic jack is connected to Mic1 pin */
5571 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5572 /* Line In jack is connected to Line1 pin */
5573 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5574 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5575 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5576 /* Ensure all other unused pins are disabled and muted. */
5577 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5578 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5579 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5580 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5583 /* Disable digital (SPDIF) pins */
5584 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5585 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5587 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5588 * bus when acting as outputs.
5590 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5591 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5593 /* Start with output sum widgets muted and their output gains at min */
5594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5595 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5596 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5598 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5599 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5600 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5601 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5602 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5604 /* Unmute Line-out pin widget amp left and right
5605 * (no equiv mixer ctrl)
5607 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5608 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5609 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5610 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5611 * inputs. If the pin mode is changed by the user the pin mode control
5612 * will take care of enabling the pin's input/output buffers as needed.
5613 * Therefore there's no need to enable the input buffer at this
5614 * stage.
5616 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5619 /* Mute capture amp left and right */
5620 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5621 /* Set ADC connection select to match default mixer setting - mic
5622 * (on mic1 pin)
5624 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5626 /* Do similar with the second ADC: mute capture input amp and
5627 * set ADC connection to mic to match ALSA's default state.
5629 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5630 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5632 /* Mute all inputs to mixer widget (even unconnected ones) */
5633 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5634 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5635 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5636 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5637 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5638 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5639 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5640 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5645 /* Initialisation sequence for Maxdata Favorit 100XS
5646 * (adapted from Acer init verbs).
5648 static struct hda_verb alc260_favorit100_init_verbs[] = {
5649 /* GPIO 0 enables the output jack.
5650 * Turn this on and rely on the standard mute
5651 * methods whenever the user wants to turn these outputs off.
5653 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5654 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5655 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5656 /* Line/Mic input jack is connected to Mic1 pin */
5657 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5658 /* Ensure all other unused pins are disabled and muted. */
5659 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5660 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5661 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5662 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5663 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5664 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5665 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5666 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5668 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5669 /* Disable digital (SPDIF) pins */
5670 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5671 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5673 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5674 * bus when acting as outputs.
5676 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5677 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5679 /* Start with output sum widgets muted and their output gains at min */
5680 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5682 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5683 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5685 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5686 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5687 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5688 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5690 /* Unmute Line-out pin widget amp left and right
5691 * (no equiv mixer ctrl)
5693 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5694 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5695 * inputs. If the pin mode is changed by the user the pin mode control
5696 * will take care of enabling the pin's input/output buffers as needed.
5697 * Therefore there's no need to enable the input buffer at this
5698 * stage.
5700 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5702 /* Mute capture amp left and right */
5703 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5704 /* Set ADC connection select to match default mixer setting - mic
5705 * (on mic1 pin)
5707 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5709 /* Do similar with the second ADC: mute capture input amp and
5710 * set ADC connection to mic to match ALSA's default state.
5712 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5713 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5715 /* Mute all inputs to mixer widget (even unconnected ones) */
5716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5720 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5721 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5722 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5723 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5728 static struct hda_verb alc260_will_verbs[] = {
5729 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5730 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5731 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5732 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5733 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5734 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5738 static struct hda_verb alc260_replacer_672v_verbs[] = {
5739 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5740 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5741 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5743 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5744 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5745 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5747 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5751 /* toggle speaker-output according to the hp-jack state */
5752 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5754 unsigned int present;
5756 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5757 present = snd_hda_codec_read(codec, 0x0f, 0,
5758 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5759 if (present) {
5760 snd_hda_codec_write_cache(codec, 0x01, 0,
5761 AC_VERB_SET_GPIO_DATA, 1);
5762 snd_hda_codec_write_cache(codec, 0x0f, 0,
5763 AC_VERB_SET_PIN_WIDGET_CONTROL,
5764 PIN_HP);
5765 } else {
5766 snd_hda_codec_write_cache(codec, 0x01, 0,
5767 AC_VERB_SET_GPIO_DATA, 0);
5768 snd_hda_codec_write_cache(codec, 0x0f, 0,
5769 AC_VERB_SET_PIN_WIDGET_CONTROL,
5770 PIN_OUT);
5774 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5775 unsigned int res)
5777 if ((res >> 26) == ALC880_HP_EVENT)
5778 alc260_replacer_672v_automute(codec);
5781 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5782 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5783 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5784 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5785 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5786 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5787 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5788 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5789 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5790 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5791 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5795 /* Test configuration for debugging, modelled after the ALC880 test
5796 * configuration.
5798 #ifdef CONFIG_SND_DEBUG
5799 static hda_nid_t alc260_test_dac_nids[1] = {
5800 0x02,
5802 static hda_nid_t alc260_test_adc_nids[2] = {
5803 0x04, 0x05,
5805 /* For testing the ALC260, each input MUX needs its own definition since
5806 * the signal assignments are different. This assumes that the first ADC
5807 * is NID 0x04.
5809 static struct hda_input_mux alc260_test_capture_sources[2] = {
5811 .num_items = 7,
5812 .items = {
5813 { "MIC1 pin", 0x0 },
5814 { "MIC2 pin", 0x1 },
5815 { "LINE1 pin", 0x2 },
5816 { "LINE2 pin", 0x3 },
5817 { "CD pin", 0x4 },
5818 { "LINE-OUT pin", 0x5 },
5819 { "HP-OUT pin", 0x6 },
5823 .num_items = 8,
5824 .items = {
5825 { "MIC1 pin", 0x0 },
5826 { "MIC2 pin", 0x1 },
5827 { "LINE1 pin", 0x2 },
5828 { "LINE2 pin", 0x3 },
5829 { "CD pin", 0x4 },
5830 { "Mixer", 0x5 },
5831 { "LINE-OUT pin", 0x6 },
5832 { "HP-OUT pin", 0x7 },
5836 static struct snd_kcontrol_new alc260_test_mixer[] = {
5837 /* Output driver widgets */
5838 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5839 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5840 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5841 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5842 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5843 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5845 /* Modes for retasking pin widgets
5846 * Note: the ALC260 doesn't seem to act on requests to enable mic
5847 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5848 * mention this restriction. At this stage it's not clear whether
5849 * this behaviour is intentional or is a hardware bug in chip
5850 * revisions available at least up until early 2006. Therefore for
5851 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5852 * choices, but if it turns out that the lack of mic bias for these
5853 * NIDs is intentional we could change their modes from
5854 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5856 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5857 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5858 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5859 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5860 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5861 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5863 /* Loopback mixer controls */
5864 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5865 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5866 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5867 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5868 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5869 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5870 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5871 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5872 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5873 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5874 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5875 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5876 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5877 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5879 /* Controls for GPIO pins, assuming they are configured as outputs */
5880 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5881 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5882 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5883 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5885 /* Switches to allow the digital IO pins to be enabled. The datasheet
5886 * is ambigious as to which NID is which; testing on laptops which
5887 * make this output available should provide clarification.
5889 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5890 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5892 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5893 * this output to turn on an external amplifier.
5895 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5896 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5898 { } /* end */
5900 static struct hda_verb alc260_test_init_verbs[] = {
5901 /* Enable all GPIOs as outputs with an initial value of 0 */
5902 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5903 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5904 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5906 /* Enable retasking pins as output, initially without power amp */
5907 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5908 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5909 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5910 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5911 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5912 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5914 /* Disable digital (SPDIF) pins initially, but users can enable
5915 * them via a mixer switch. In the case of SPDIF-out, this initverb
5916 * payload also sets the generation to 0, output to be in "consumer"
5917 * PCM format, copyright asserted, no pre-emphasis and no validity
5918 * control.
5920 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5921 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5923 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5924 * OUT1 sum bus when acting as an output.
5926 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5927 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5928 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5929 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5931 /* Start with output sum widgets muted and their output gains at min */
5932 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5934 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5935 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5936 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5937 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5938 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5939 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5940 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5942 /* Unmute retasking pin widget output buffers since the default
5943 * state appears to be output. As the pin mode is changed by the
5944 * user the pin mode control will take care of enabling the pin's
5945 * input/output buffers as needed.
5947 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5948 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5950 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5951 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5952 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5953 /* Also unmute the mono-out pin widget */
5954 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5956 /* Mute capture amp left and right */
5957 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5958 /* Set ADC connection select to match default mixer setting (mic1
5959 * pin)
5961 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5963 /* Do the same for the second ADC: mute capture input amp and
5964 * set ADC connection to mic1 pin
5966 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5967 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5969 /* Mute all inputs to mixer widget (even unconnected ones) */
5970 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5972 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5974 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5976 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5977 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5981 #endif
5983 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5984 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5986 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5987 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5990 * for BIOS auto-configuration
5993 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5994 const char *pfx, int *vol_bits)
5996 hda_nid_t nid_vol;
5997 unsigned long vol_val, sw_val;
5998 char name[32];
5999 int err;
6001 if (nid >= 0x0f && nid < 0x11) {
6002 nid_vol = nid - 0x7;
6003 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6004 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6005 } else if (nid == 0x11) {
6006 nid_vol = nid - 0x7;
6007 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6008 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6009 } else if (nid >= 0x12 && nid <= 0x15) {
6010 nid_vol = 0x08;
6011 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6012 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6013 } else
6014 return 0; /* N/A */
6016 if (!(*vol_bits & (1 << nid_vol))) {
6017 /* first control for the volume widget */
6018 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
6019 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
6020 if (err < 0)
6021 return err;
6022 *vol_bits |= (1 << nid_vol);
6024 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
6025 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
6026 if (err < 0)
6027 return err;
6028 return 1;
6031 /* add playback controls from the parsed DAC table */
6032 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6033 const struct auto_pin_cfg *cfg)
6035 hda_nid_t nid;
6036 int err;
6037 int vols = 0;
6039 spec->multiout.num_dacs = 1;
6040 spec->multiout.dac_nids = spec->private_dac_nids;
6041 spec->multiout.dac_nids[0] = 0x02;
6043 nid = cfg->line_out_pins[0];
6044 if (nid) {
6045 const char *pfx;
6046 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6047 pfx = "Master";
6048 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6049 pfx = "Speaker";
6050 else
6051 pfx = "Front";
6052 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6053 if (err < 0)
6054 return err;
6057 nid = cfg->speaker_pins[0];
6058 if (nid) {
6059 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6060 if (err < 0)
6061 return err;
6064 nid = cfg->hp_pins[0];
6065 if (nid) {
6066 err = alc260_add_playback_controls(spec, nid, "Headphone",
6067 &vols);
6068 if (err < 0)
6069 return err;
6071 return 0;
6074 /* create playback/capture controls for input pins */
6075 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6076 const struct auto_pin_cfg *cfg)
6078 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6081 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6082 hda_nid_t nid, int pin_type,
6083 int sel_idx)
6085 alc_set_pin_output(codec, nid, pin_type);
6086 /* need the manual connection? */
6087 if (nid >= 0x12) {
6088 int idx = nid - 0x12;
6089 snd_hda_codec_write(codec, idx + 0x0b, 0,
6090 AC_VERB_SET_CONNECT_SEL, sel_idx);
6094 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6096 struct alc_spec *spec = codec->spec;
6097 hda_nid_t nid;
6099 nid = spec->autocfg.line_out_pins[0];
6100 if (nid) {
6101 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6102 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6105 nid = spec->autocfg.speaker_pins[0];
6106 if (nid)
6107 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6109 nid = spec->autocfg.hp_pins[0];
6110 if (nid)
6111 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6114 #define ALC260_PIN_CD_NID 0x16
6115 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6117 struct alc_spec *spec = codec->spec;
6118 int i;
6120 for (i = 0; i < AUTO_PIN_LAST; i++) {
6121 hda_nid_t nid = spec->autocfg.input_pins[i];
6122 if (nid >= 0x12) {
6123 alc_set_input_pin(codec, nid, i);
6124 if (nid != ALC260_PIN_CD_NID &&
6125 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6126 snd_hda_codec_write(codec, nid, 0,
6127 AC_VERB_SET_AMP_GAIN_MUTE,
6128 AMP_OUT_MUTE);
6134 * generic initialization of ADC, input mixers and output mixers
6136 static struct hda_verb alc260_volume_init_verbs[] = {
6138 * Unmute ADC0-1 and set the default input to mic-in
6140 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6141 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6142 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6143 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6145 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6146 * mixer widget
6147 * Note: PASD motherboards uses the Line In 2 as the input for
6148 * front panel mic (mic 2)
6150 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6151 /* mute analog inputs */
6152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6154 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6156 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6159 * Set up output mixers (0x08 - 0x0a)
6161 /* set vol=0 to output mixers */
6162 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6163 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6164 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6165 /* set up input amps for analog loopback */
6166 /* Amp Indices: DAC = 0, mixer = 1 */
6167 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6168 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6169 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6170 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6171 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6172 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6177 static int alc260_parse_auto_config(struct hda_codec *codec)
6179 struct alc_spec *spec = codec->spec;
6180 int err;
6181 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6183 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6184 alc260_ignore);
6185 if (err < 0)
6186 return err;
6187 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6188 if (err < 0)
6189 return err;
6190 if (!spec->kctls.list)
6191 return 0; /* can't find valid BIOS pin config */
6192 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6193 if (err < 0)
6194 return err;
6196 spec->multiout.max_channels = 2;
6198 if (spec->autocfg.dig_outs)
6199 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6200 if (spec->kctls.list)
6201 add_mixer(spec, spec->kctls.list);
6203 add_verb(spec, alc260_volume_init_verbs);
6205 spec->num_mux_defs = 1;
6206 spec->input_mux = &spec->private_imux[0];
6208 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
6210 return 1;
6213 /* additional initialization for auto-configuration model */
6214 static void alc260_auto_init(struct hda_codec *codec)
6216 struct alc_spec *spec = codec->spec;
6217 alc260_auto_init_multi_out(codec);
6218 alc260_auto_init_analog_input(codec);
6219 if (spec->unsol_event)
6220 alc_inithook(codec);
6223 #ifdef CONFIG_SND_HDA_POWER_SAVE
6224 static struct hda_amp_list alc260_loopbacks[] = {
6225 { 0x07, HDA_INPUT, 0 },
6226 { 0x07, HDA_INPUT, 1 },
6227 { 0x07, HDA_INPUT, 2 },
6228 { 0x07, HDA_INPUT, 3 },
6229 { 0x07, HDA_INPUT, 4 },
6230 { } /* end */
6232 #endif
6235 * ALC260 configurations
6237 static const char *alc260_models[ALC260_MODEL_LAST] = {
6238 [ALC260_BASIC] = "basic",
6239 [ALC260_HP] = "hp",
6240 [ALC260_HP_3013] = "hp-3013",
6241 [ALC260_HP_DC7600] = "hp-dc7600",
6242 [ALC260_FUJITSU_S702X] = "fujitsu",
6243 [ALC260_ACER] = "acer",
6244 [ALC260_WILL] = "will",
6245 [ALC260_REPLACER_672V] = "replacer",
6246 [ALC260_FAVORIT100] = "favorit100",
6247 #ifdef CONFIG_SND_DEBUG
6248 [ALC260_TEST] = "test",
6249 #endif
6250 [ALC260_AUTO] = "auto",
6253 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6254 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6255 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6256 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6257 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6258 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6259 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6260 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6261 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6262 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6263 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6264 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6265 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6266 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6267 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6268 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6269 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6270 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6271 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6272 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6276 static struct alc_config_preset alc260_presets[] = {
6277 [ALC260_BASIC] = {
6278 .mixers = { alc260_base_output_mixer,
6279 alc260_input_mixer },
6280 .init_verbs = { alc260_init_verbs },
6281 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6282 .dac_nids = alc260_dac_nids,
6283 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6284 .adc_nids = alc260_adc_nids,
6285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6286 .channel_mode = alc260_modes,
6287 .input_mux = &alc260_capture_source,
6289 [ALC260_HP] = {
6290 .mixers = { alc260_hp_output_mixer,
6291 alc260_input_mixer },
6292 .init_verbs = { alc260_init_verbs,
6293 alc260_hp_unsol_verbs },
6294 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6295 .dac_nids = alc260_dac_nids,
6296 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6297 .adc_nids = alc260_adc_nids_alt,
6298 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6299 .channel_mode = alc260_modes,
6300 .input_mux = &alc260_capture_source,
6301 .unsol_event = alc260_hp_unsol_event,
6302 .init_hook = alc260_hp_automute,
6304 [ALC260_HP_DC7600] = {
6305 .mixers = { alc260_hp_dc7600_mixer,
6306 alc260_input_mixer },
6307 .init_verbs = { alc260_init_verbs,
6308 alc260_hp_dc7600_verbs },
6309 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6310 .dac_nids = alc260_dac_nids,
6311 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6312 .adc_nids = alc260_adc_nids_alt,
6313 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6314 .channel_mode = alc260_modes,
6315 .input_mux = &alc260_capture_source,
6316 .unsol_event = alc260_hp_3012_unsol_event,
6317 .init_hook = alc260_hp_3012_automute,
6319 [ALC260_HP_3013] = {
6320 .mixers = { alc260_hp_3013_mixer,
6321 alc260_input_mixer },
6322 .init_verbs = { alc260_hp_3013_init_verbs,
6323 alc260_hp_3013_unsol_verbs },
6324 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6325 .dac_nids = alc260_dac_nids,
6326 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6327 .adc_nids = alc260_adc_nids_alt,
6328 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6329 .channel_mode = alc260_modes,
6330 .input_mux = &alc260_capture_source,
6331 .unsol_event = alc260_hp_3013_unsol_event,
6332 .init_hook = alc260_hp_3013_automute,
6334 [ALC260_FUJITSU_S702X] = {
6335 .mixers = { alc260_fujitsu_mixer },
6336 .init_verbs = { alc260_fujitsu_init_verbs },
6337 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6338 .dac_nids = alc260_dac_nids,
6339 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6340 .adc_nids = alc260_dual_adc_nids,
6341 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6342 .channel_mode = alc260_modes,
6343 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6344 .input_mux = alc260_fujitsu_capture_sources,
6346 [ALC260_ACER] = {
6347 .mixers = { alc260_acer_mixer },
6348 .init_verbs = { alc260_acer_init_verbs },
6349 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6350 .dac_nids = alc260_dac_nids,
6351 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6352 .adc_nids = alc260_dual_adc_nids,
6353 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6354 .channel_mode = alc260_modes,
6355 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6356 .input_mux = alc260_acer_capture_sources,
6358 [ALC260_FAVORIT100] = {
6359 .mixers = { alc260_favorit100_mixer },
6360 .init_verbs = { alc260_favorit100_init_verbs },
6361 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6362 .dac_nids = alc260_dac_nids,
6363 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6364 .adc_nids = alc260_dual_adc_nids,
6365 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6366 .channel_mode = alc260_modes,
6367 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6368 .input_mux = alc260_favorit100_capture_sources,
6370 [ALC260_WILL] = {
6371 .mixers = { alc260_will_mixer },
6372 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6373 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6374 .dac_nids = alc260_dac_nids,
6375 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6376 .adc_nids = alc260_adc_nids,
6377 .dig_out_nid = ALC260_DIGOUT_NID,
6378 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6379 .channel_mode = alc260_modes,
6380 .input_mux = &alc260_capture_source,
6382 [ALC260_REPLACER_672V] = {
6383 .mixers = { alc260_replacer_672v_mixer },
6384 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6385 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6386 .dac_nids = alc260_dac_nids,
6387 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6388 .adc_nids = alc260_adc_nids,
6389 .dig_out_nid = ALC260_DIGOUT_NID,
6390 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6391 .channel_mode = alc260_modes,
6392 .input_mux = &alc260_capture_source,
6393 .unsol_event = alc260_replacer_672v_unsol_event,
6394 .init_hook = alc260_replacer_672v_automute,
6396 #ifdef CONFIG_SND_DEBUG
6397 [ALC260_TEST] = {
6398 .mixers = { alc260_test_mixer },
6399 .init_verbs = { alc260_test_init_verbs },
6400 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6401 .dac_nids = alc260_test_dac_nids,
6402 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6403 .adc_nids = alc260_test_adc_nids,
6404 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6405 .channel_mode = alc260_modes,
6406 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6407 .input_mux = alc260_test_capture_sources,
6409 #endif
6412 static int patch_alc260(struct hda_codec *codec)
6414 struct alc_spec *spec;
6415 int err, board_config;
6417 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6418 if (spec == NULL)
6419 return -ENOMEM;
6421 codec->spec = spec;
6423 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6424 alc260_models,
6425 alc260_cfg_tbl);
6426 if (board_config < 0) {
6427 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6428 codec->chip_name);
6429 board_config = ALC260_AUTO;
6432 if (board_config == ALC260_AUTO) {
6433 /* automatic parse from the BIOS config */
6434 err = alc260_parse_auto_config(codec);
6435 if (err < 0) {
6436 alc_free(codec);
6437 return err;
6438 } else if (!err) {
6439 printk(KERN_INFO
6440 "hda_codec: Cannot set up configuration "
6441 "from BIOS. Using base mode...\n");
6442 board_config = ALC260_BASIC;
6446 err = snd_hda_attach_beep_device(codec, 0x1);
6447 if (err < 0) {
6448 alc_free(codec);
6449 return err;
6452 if (board_config != ALC260_AUTO)
6453 setup_preset(codec, &alc260_presets[board_config]);
6455 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6456 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6458 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6459 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6461 if (!spec->adc_nids && spec->input_mux) {
6462 /* check whether NID 0x04 is valid */
6463 unsigned int wcap = get_wcaps(codec, 0x04);
6464 wcap = get_wcaps_type(wcap);
6465 /* get type */
6466 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6467 spec->adc_nids = alc260_adc_nids_alt;
6468 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6469 } else {
6470 spec->adc_nids = alc260_adc_nids;
6471 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6474 set_capture_mixer(codec);
6475 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6477 spec->vmaster_nid = 0x08;
6479 codec->patch_ops = alc_patch_ops;
6480 if (board_config == ALC260_AUTO)
6481 spec->init_hook = alc260_auto_init;
6482 #ifdef CONFIG_SND_HDA_POWER_SAVE
6483 if (!spec->loopback.amplist)
6484 spec->loopback.amplist = alc260_loopbacks;
6485 #endif
6486 codec->proc_widget_hook = print_realtek_coef;
6488 return 0;
6493 * ALC882/883/885/888/889 support
6495 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6496 * configuration. Each pin widget can choose any input DACs and a mixer.
6497 * Each ADC is connected from a mixer of all inputs. This makes possible
6498 * 6-channel independent captures.
6500 * In addition, an independent DAC for the multi-playback (not used in this
6501 * driver yet).
6503 #define ALC882_DIGOUT_NID 0x06
6504 #define ALC882_DIGIN_NID 0x0a
6505 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6506 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6507 #define ALC1200_DIGOUT_NID 0x10
6510 static struct hda_channel_mode alc882_ch_modes[1] = {
6511 { 8, NULL }
6514 /* DACs */
6515 static hda_nid_t alc882_dac_nids[4] = {
6516 /* front, rear, clfe, rear_surr */
6517 0x02, 0x03, 0x04, 0x05
6519 #define alc883_dac_nids alc882_dac_nids
6521 /* ADCs */
6522 #define alc882_adc_nids alc880_adc_nids
6523 #define alc882_adc_nids_alt alc880_adc_nids_alt
6524 #define alc883_adc_nids alc882_adc_nids_alt
6525 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6526 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6527 #define alc889_adc_nids alc880_adc_nids
6529 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6530 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6531 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6532 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6533 #define alc889_capsrc_nids alc882_capsrc_nids
6535 /* input MUX */
6536 /* FIXME: should be a matrix-type input source selection */
6538 static struct hda_input_mux alc882_capture_source = {
6539 .num_items = 4,
6540 .items = {
6541 { "Mic", 0x0 },
6542 { "Front Mic", 0x1 },
6543 { "Line", 0x2 },
6544 { "CD", 0x4 },
6548 #define alc883_capture_source alc882_capture_source
6550 static struct hda_input_mux alc889_capture_source = {
6551 .num_items = 3,
6552 .items = {
6553 { "Front Mic", 0x0 },
6554 { "Mic", 0x3 },
6555 { "Line", 0x2 },
6559 static struct hda_input_mux mb5_capture_source = {
6560 .num_items = 3,
6561 .items = {
6562 { "Mic", 0x1 },
6563 { "Line", 0x2 },
6564 { "CD", 0x4 },
6568 static struct hda_input_mux alc883_3stack_6ch_intel = {
6569 .num_items = 4,
6570 .items = {
6571 { "Mic", 0x1 },
6572 { "Front Mic", 0x0 },
6573 { "Line", 0x2 },
6574 { "CD", 0x4 },
6578 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6579 .num_items = 2,
6580 .items = {
6581 { "Mic", 0x1 },
6582 { "Line", 0x2 },
6586 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6587 .num_items = 4,
6588 .items = {
6589 { "Mic", 0x0 },
6590 { "iMic", 0x1 },
6591 { "Line", 0x2 },
6592 { "CD", 0x4 },
6596 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6597 .num_items = 2,
6598 .items = {
6599 { "Mic", 0x0 },
6600 { "Int Mic", 0x1 },
6604 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6605 .num_items = 3,
6606 .items = {
6607 { "Mic", 0x0 },
6608 { "Front Mic", 0x1 },
6609 { "Line", 0x4 },
6613 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6614 .num_items = 2,
6615 .items = {
6616 { "Mic", 0x0 },
6617 { "Line", 0x2 },
6621 static struct hda_input_mux alc889A_mb31_capture_source = {
6622 .num_items = 2,
6623 .items = {
6624 { "Mic", 0x0 },
6625 /* Front Mic (0x01) unused */
6626 { "Line", 0x2 },
6627 /* Line 2 (0x03) unused */
6628 /* CD (0x04) unsused? */
6633 * 2ch mode
6635 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6636 { 2, NULL }
6640 * 2ch mode
6642 static struct hda_verb alc882_3ST_ch2_init[] = {
6643 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6644 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6645 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6646 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6647 { } /* end */
6651 * 4ch mode
6653 static struct hda_verb alc882_3ST_ch4_init[] = {
6654 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6655 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6656 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6657 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6658 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6659 { } /* end */
6663 * 6ch mode
6665 static struct hda_verb alc882_3ST_ch6_init[] = {
6666 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6667 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6668 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6669 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6670 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6671 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6672 { } /* end */
6675 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6676 { 2, alc882_3ST_ch2_init },
6677 { 4, alc882_3ST_ch4_init },
6678 { 6, alc882_3ST_ch6_init },
6681 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6684 * 2ch mode
6686 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6687 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6688 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6689 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6690 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6691 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6692 { } /* end */
6696 * 4ch mode
6698 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6699 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6700 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6701 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6702 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6703 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6704 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6705 { } /* end */
6709 * 6ch mode
6711 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6712 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6713 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6714 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6715 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6716 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6717 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6718 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6719 { } /* end */
6722 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6723 { 2, alc883_3ST_ch2_clevo_init },
6724 { 4, alc883_3ST_ch4_clevo_init },
6725 { 6, alc883_3ST_ch6_clevo_init },
6730 * 6ch mode
6732 static struct hda_verb alc882_sixstack_ch6_init[] = {
6733 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6734 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6735 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6736 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6737 { } /* end */
6741 * 8ch mode
6743 static struct hda_verb alc882_sixstack_ch8_init[] = {
6744 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6745 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6746 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6747 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6748 { } /* end */
6751 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6752 { 6, alc882_sixstack_ch6_init },
6753 { 8, alc882_sixstack_ch8_init },
6757 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6761 * 2ch mode
6763 static struct hda_verb alc885_mbp_ch2_init[] = {
6764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6765 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6766 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6767 { } /* end */
6771 * 4ch mode
6773 static struct hda_verb alc885_mbp_ch4_init[] = {
6774 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6775 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6776 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6777 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6778 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6779 { } /* end */
6782 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6783 { 2, alc885_mbp_ch2_init },
6784 { 4, alc885_mbp_ch4_init },
6788 * 2ch
6789 * Speakers/Woofer/HP = Front
6790 * LineIn = Input
6792 static struct hda_verb alc885_mb5_ch2_init[] = {
6793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6794 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6795 { } /* end */
6799 * 6ch mode
6800 * Speakers/HP = Front
6801 * Woofer = LFE
6802 * LineIn = Surround
6804 static struct hda_verb alc885_mb5_ch6_init[] = {
6805 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6807 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6808 { } /* end */
6811 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6812 { 2, alc885_mb5_ch2_init },
6813 { 6, alc885_mb5_ch6_init },
6818 * 2ch mode
6820 static struct hda_verb alc883_4ST_ch2_init[] = {
6821 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6822 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6823 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6824 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6825 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6826 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6827 { } /* end */
6831 * 4ch mode
6833 static struct hda_verb alc883_4ST_ch4_init[] = {
6834 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6835 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6840 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6841 { } /* end */
6845 * 6ch mode
6847 static struct hda_verb alc883_4ST_ch6_init[] = {
6848 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6849 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6850 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6851 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6852 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6853 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6854 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6855 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6856 { } /* end */
6860 * 8ch mode
6862 static struct hda_verb alc883_4ST_ch8_init[] = {
6863 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6864 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6865 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6866 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6867 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6868 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6869 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6870 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6871 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6872 { } /* end */
6875 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6876 { 2, alc883_4ST_ch2_init },
6877 { 4, alc883_4ST_ch4_init },
6878 { 6, alc883_4ST_ch6_init },
6879 { 8, alc883_4ST_ch8_init },
6884 * 2ch mode
6886 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6887 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6888 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6889 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6890 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6891 { } /* end */
6895 * 4ch mode
6897 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6898 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6899 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6900 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6901 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6902 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6903 { } /* end */
6907 * 6ch mode
6909 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6910 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6911 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6912 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6913 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6914 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6915 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6916 { } /* end */
6919 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6920 { 2, alc883_3ST_ch2_intel_init },
6921 { 4, alc883_3ST_ch4_intel_init },
6922 { 6, alc883_3ST_ch6_intel_init },
6926 * 2ch mode
6928 static struct hda_verb alc889_ch2_intel_init[] = {
6929 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6930 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6931 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6932 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6933 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6934 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6935 { } /* end */
6939 * 6ch mode
6941 static struct hda_verb alc889_ch6_intel_init[] = {
6942 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6943 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6944 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6945 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6946 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6947 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6948 { } /* end */
6952 * 8ch mode
6954 static struct hda_verb alc889_ch8_intel_init[] = {
6955 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6956 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6957 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6958 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6959 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6960 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6961 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6962 { } /* end */
6965 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6966 { 2, alc889_ch2_intel_init },
6967 { 6, alc889_ch6_intel_init },
6968 { 8, alc889_ch8_intel_init },
6972 * 6ch mode
6974 static struct hda_verb alc883_sixstack_ch6_init[] = {
6975 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6976 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6977 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6978 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6979 { } /* end */
6983 * 8ch mode
6985 static struct hda_verb alc883_sixstack_ch8_init[] = {
6986 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6987 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6988 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6989 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6990 { } /* end */
6993 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6994 { 6, alc883_sixstack_ch6_init },
6995 { 8, alc883_sixstack_ch8_init },
6999 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7000 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7002 static struct snd_kcontrol_new alc882_base_mixer[] = {
7003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7004 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7006 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7009 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7010 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7011 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7012 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7013 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7014 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7015 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7016 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7017 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7018 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7021 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7022 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7023 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7024 { } /* end */
7027 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7028 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7029 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7030 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7031 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7032 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7033 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7034 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7035 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7036 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7037 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7038 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7039 { } /* end */
7042 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7044 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7045 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7046 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7047 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7048 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7049 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7050 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7051 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7052 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7054 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7055 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7056 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7057 { } /* end */
7060 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7061 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7062 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7063 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7064 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7068 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7070 { } /* end */
7073 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7075 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7076 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7077 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7078 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7079 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7080 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7081 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7082 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7083 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7084 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7085 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7086 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7087 { } /* end */
7090 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7091 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7093 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7094 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7095 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7096 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7097 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7098 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7100 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7101 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7102 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7103 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7105 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7106 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7107 { } /* end */
7110 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7111 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7112 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7114 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7115 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7116 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7117 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7121 { } /* end */
7124 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7126 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7127 .name = "Channel Mode",
7128 .info = alc_ch_mode_info,
7129 .get = alc_ch_mode_get,
7130 .put = alc_ch_mode_put,
7132 { } /* end */
7135 static struct hda_verb alc882_base_init_verbs[] = {
7136 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7137 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7138 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7140 /* Rear mixer */
7141 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7143 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7144 /* CLFE mixer */
7145 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7146 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7147 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7148 /* Side mixer */
7149 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7150 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7153 /* mute analog input loopbacks */
7154 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7155 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7160 /* Front Pin: output 0 (0x0c) */
7161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7162 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7163 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7164 /* Rear Pin: output 1 (0x0d) */
7165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7166 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7168 /* CLFE Pin: output 2 (0x0e) */
7169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7170 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7171 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7172 /* Side Pin: output 3 (0x0f) */
7173 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7174 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7175 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7176 /* Mic (rear) pin: input vref at 80% */
7177 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7178 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7179 /* Front Mic pin: input vref at 80% */
7180 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7181 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7182 /* Line In pin: input */
7183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7184 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7185 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7186 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7187 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7189 /* CD pin widget for input */
7190 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7192 /* FIXME: use matrix-type input source selection */
7193 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7194 /* Input mixer2 */
7195 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7196 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7197 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7198 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7199 /* Input mixer3 */
7200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7204 /* ADC2: mute amp left and right */
7205 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7206 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7207 /* ADC3: mute amp left and right */
7208 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7209 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7214 static struct hda_verb alc882_adc1_init_verbs[] = {
7215 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7216 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7217 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7218 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7220 /* ADC1: mute amp left and right */
7221 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7222 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7226 static struct hda_verb alc882_eapd_verbs[] = {
7227 /* change to EAPD mode */
7228 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7229 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7233 static struct hda_verb alc889_eapd_verbs[] = {
7234 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7235 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7239 static struct hda_verb alc_hp15_unsol_verbs[] = {
7240 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7241 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7245 static struct hda_verb alc885_init_verbs[] = {
7246 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7247 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7248 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7250 /* Rear mixer */
7251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7252 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7253 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7254 /* CLFE mixer */
7255 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7256 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7257 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7258 /* Side mixer */
7259 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7260 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7261 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7263 /* mute analog input loopbacks */
7264 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7265 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7266 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7268 /* Front HP Pin: output 0 (0x0c) */
7269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7272 /* Front Pin: output 0 (0x0c) */
7273 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7274 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7275 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7276 /* Rear Pin: output 1 (0x0d) */
7277 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7278 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7279 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7280 /* CLFE Pin: output 2 (0x0e) */
7281 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7282 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7283 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7284 /* Side Pin: output 3 (0x0f) */
7285 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7286 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7287 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7288 /* Mic (rear) pin: input vref at 80% */
7289 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7290 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7291 /* Front Mic pin: input vref at 80% */
7292 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7293 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7294 /* Line In pin: input */
7295 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7296 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7298 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7299 /* Input mixer1 */
7300 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7302 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7303 /* Input mixer2 */
7304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7307 /* Input mixer3 */
7308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7309 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7310 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7311 /* ADC2: mute amp left and right */
7312 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7313 /* ADC3: mute amp left and right */
7314 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7319 static struct hda_verb alc885_init_input_verbs[] = {
7320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7327 /* Unmute Selector 24h and set the default input to front mic */
7328 static struct hda_verb alc889_init_input_verbs[] = {
7329 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7335 #define alc883_init_verbs alc882_base_init_verbs
7337 /* Mac Pro test */
7338 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7339 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7340 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7342 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7343 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7344 /* FIXME: this looks suspicious...
7345 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
7346 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
7348 { } /* end */
7351 static struct hda_verb alc882_macpro_init_verbs[] = {
7352 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7354 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7356 /* Front Pin: output 0 (0x0c) */
7357 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7358 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7359 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7360 /* Front Mic pin: input vref at 80% */
7361 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7362 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7363 /* Speaker: output */
7364 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7365 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7366 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7367 /* Headphone output (output 0 - 0x0c) */
7368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7370 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7372 /* FIXME: use matrix-type input source selection */
7373 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7374 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7379 /* Input mixer2 */
7380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7384 /* Input mixer3 */
7385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7389 /* ADC1: mute amp left and right */
7390 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7391 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7392 /* ADC2: mute amp left and right */
7393 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7394 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7395 /* ADC3: mute amp left and right */
7396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7397 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7402 /* Macbook 5,1 */
7403 static struct hda_verb alc885_mb5_init_verbs[] = {
7404 /* DACs */
7405 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7406 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7407 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7408 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7409 /* Front mixer */
7410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7411 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7413 /* Surround mixer */
7414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7417 /* LFE mixer */
7418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7421 /* HP mixer */
7422 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7423 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7425 /* Front Pin (0x0c) */
7426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7427 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7428 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7429 /* LFE Pin (0x0e) */
7430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7432 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7433 /* HP Pin (0x0f) */
7434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7437 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7438 /* Front Mic pin: input vref at 80% */
7439 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7441 /* Line In pin */
7442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7443 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7452 /* Macbook Pro rev3 */
7453 static struct hda_verb alc885_mbp3_init_verbs[] = {
7454 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7455 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7458 /* Rear mixer */
7459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7461 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7462 /* HP mixer */
7463 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7464 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7466 /* Front Pin: output 0 (0x0c) */
7467 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7468 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7469 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7470 /* HP Pin: output 0 (0x0e) */
7471 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7472 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7473 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7474 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7475 /* Mic (rear) pin: input vref at 80% */
7476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7477 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7478 /* Front Mic pin: input vref at 80% */
7479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7481 /* Line In pin: use output 1 when in LineOut mode */
7482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7484 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7486 /* FIXME: use matrix-type input source selection */
7487 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7488 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7491 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7492 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7493 /* Input mixer2 */
7494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7495 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7496 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7497 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7498 /* Input mixer3 */
7499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7501 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7502 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7503 /* ADC1: mute amp left and right */
7504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7505 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7506 /* ADC2: mute amp left and right */
7507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7508 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7509 /* ADC3: mute amp left and right */
7510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7511 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7516 /* iMac 24 mixer. */
7517 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
7518 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7519 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
7520 { } /* end */
7523 /* iMac 24 init verbs. */
7524 static struct hda_verb alc885_imac24_init_verbs[] = {
7525 /* Internal speakers: output 0 (0x0c) */
7526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7527 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7528 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7529 /* Internal speakers: output 0 (0x0c) */
7530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7531 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7532 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7533 /* Headphone: output 0 (0x0c) */
7534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7536 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7537 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7538 /* Front Mic: input vref at 80% */
7539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7540 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7544 /* Toggle speaker-output according to the hp-jack state */
7545 static void alc885_imac24_setup(struct hda_codec *codec)
7547 struct alc_spec *spec = codec->spec;
7549 spec->autocfg.hp_pins[0] = 0x14;
7550 spec->autocfg.speaker_pins[0] = 0x18;
7551 spec->autocfg.speaker_pins[1] = 0x1a;
7554 static void alc885_mbp3_setup(struct hda_codec *codec)
7556 struct alc_spec *spec = codec->spec;
7558 spec->autocfg.hp_pins[0] = 0x15;
7559 spec->autocfg.speaker_pins[0] = 0x14;
7562 static void alc885_mb5_automute(struct hda_codec *codec)
7564 unsigned int present;
7566 present = snd_hda_codec_read(codec, 0x14, 0,
7567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7568 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7569 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7570 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7571 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7575 static void alc885_mb5_unsol_event(struct hda_codec *codec,
7576 unsigned int res)
7578 /* Headphone insertion or removal. */
7579 if ((res >> 26) == ALC880_HP_EVENT)
7580 alc885_mb5_automute(codec);
7584 static struct hda_verb alc882_targa_verbs[] = {
7585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7588 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7591 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7592 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7596 { } /* end */
7599 /* toggle speaker-output according to the hp-jack state */
7600 static void alc882_targa_automute(struct hda_codec *codec)
7602 struct alc_spec *spec = codec->spec;
7603 alc_automute_amp(codec);
7604 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7605 spec->jack_present ? 1 : 3);
7608 static void alc882_targa_setup(struct hda_codec *codec)
7610 struct alc_spec *spec = codec->spec;
7612 spec->autocfg.hp_pins[0] = 0x14;
7613 spec->autocfg.speaker_pins[0] = 0x1b;
7616 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
7618 if ((res >> 26) == ALC880_HP_EVENT)
7619 alc882_targa_automute(codec);
7622 static struct hda_verb alc882_asus_a7j_verbs[] = {
7623 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7626 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7628 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7630 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7631 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7632 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7634 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7635 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7636 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7637 { } /* end */
7640 static struct hda_verb alc882_asus_a7m_verbs[] = {
7641 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7642 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7644 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7645 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7646 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7648 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7650 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
7652 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7653 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7654 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7655 { } /* end */
7658 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
7660 unsigned int gpiostate, gpiomask, gpiodir;
7662 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
7663 AC_VERB_GET_GPIO_DATA, 0);
7665 if (!muted)
7666 gpiostate |= (1 << pin);
7667 else
7668 gpiostate &= ~(1 << pin);
7670 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
7671 AC_VERB_GET_GPIO_MASK, 0);
7672 gpiomask |= (1 << pin);
7674 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
7675 AC_VERB_GET_GPIO_DIRECTION, 0);
7676 gpiodir |= (1 << pin);
7679 snd_hda_codec_write(codec, codec->afg, 0,
7680 AC_VERB_SET_GPIO_MASK, gpiomask);
7681 snd_hda_codec_write(codec, codec->afg, 0,
7682 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
7684 msleep(1);
7686 snd_hda_codec_write(codec, codec->afg, 0,
7687 AC_VERB_SET_GPIO_DATA, gpiostate);
7690 /* set up GPIO at initialization */
7691 static void alc885_macpro_init_hook(struct hda_codec *codec)
7693 alc882_gpio_mute(codec, 0, 0);
7694 alc882_gpio_mute(codec, 1, 0);
7697 /* set up GPIO and update auto-muting at initialization */
7698 static void alc885_imac24_init_hook(struct hda_codec *codec)
7700 alc885_macpro_init_hook(codec);
7701 alc_automute_amp(codec);
7705 * generic initialization of ADC, input mixers and output mixers
7707 static struct hda_verb alc883_auto_init_verbs[] = {
7709 * Unmute ADC0-2 and set the default input to mic-in
7711 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7712 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7713 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7714 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7716 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7717 * mixer widget
7718 * Note: PASD motherboards uses the Line In 2 as the input for
7719 * front panel mic (mic 2)
7721 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7729 * Set up output mixers (0x0c - 0x0f)
7731 /* set vol=0 to output mixers */
7732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7733 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7735 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7736 /* set up input amps for analog loopback */
7737 /* Amp Indices: DAC = 0, mixer = 1 */
7738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7742 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7743 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7745 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7746 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7747 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7749 /* FIXME: use matrix-type input source selection */
7750 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7751 /* Input mixer2 */
7752 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7753 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7754 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7755 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7756 /* Input mixer3 */
7757 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7765 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7766 static struct hda_verb alc889A_mb31_ch2_init[] = {
7767 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7769 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7770 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7771 { } /* end */
7774 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7775 static struct hda_verb alc889A_mb31_ch4_init[] = {
7776 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7778 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7779 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7780 { } /* end */
7783 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7784 static struct hda_verb alc889A_mb31_ch5_init[] = {
7785 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7786 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7787 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7788 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7789 { } /* end */
7792 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7793 static struct hda_verb alc889A_mb31_ch6_init[] = {
7794 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7795 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7796 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7797 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7798 { } /* end */
7801 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7802 { 2, alc889A_mb31_ch2_init },
7803 { 4, alc889A_mb31_ch4_init },
7804 { 5, alc889A_mb31_ch5_init },
7805 { 6, alc889A_mb31_ch6_init },
7808 static struct hda_verb alc883_medion_eapd_verbs[] = {
7809 /* eanable EAPD on medion laptop */
7810 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7811 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7815 #define alc883_base_mixer alc882_base_mixer
7817 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7818 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7819 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7820 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7821 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7822 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7823 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7824 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7825 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7826 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7828 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7829 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7830 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7831 { } /* end */
7834 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7835 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7836 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7837 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7838 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7840 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7841 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7842 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7843 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7844 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7845 { } /* end */
7848 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7849 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7850 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7852 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7856 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7857 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7858 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7859 { } /* end */
7862 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7863 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7864 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7865 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7866 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7867 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7868 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7869 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7870 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7871 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7873 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7874 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7875 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7876 { } /* end */
7879 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7880 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7881 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7883 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7884 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7885 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7886 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7887 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7888 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7889 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7890 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7891 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7892 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7893 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7894 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7895 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7896 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7897 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7899 { } /* end */
7902 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7903 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7904 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7905 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7906 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7907 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7908 HDA_OUTPUT),
7909 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7910 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7911 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7913 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7914 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7915 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7916 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7917 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7918 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7920 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7921 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7922 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7923 { } /* end */
7926 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7927 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7928 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7929 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7930 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7931 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7932 HDA_OUTPUT),
7933 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7934 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7935 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7936 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7937 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7938 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7939 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7940 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7942 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7944 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7945 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7946 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7947 { } /* end */
7950 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7951 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7952 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7953 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7954 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7955 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7956 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7957 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7958 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7959 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7960 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7961 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7962 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7963 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7965 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7967 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7968 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7969 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7970 { } /* end */
7973 static struct snd_kcontrol_new alc883_targa_mixer[] = {
7974 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7975 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7977 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7978 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7979 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7980 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7981 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7982 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7983 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7984 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7985 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7986 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7987 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7988 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7989 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7991 { } /* end */
7994 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
7995 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7996 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7997 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7998 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7999 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8000 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8001 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8004 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8005 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8006 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8007 { } /* end */
8010 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8011 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8012 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8013 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8014 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8015 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8016 { } /* end */
8019 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8020 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8021 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8022 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8023 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8025 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8027 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8028 { } /* end */
8031 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8032 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8033 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8034 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8035 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8036 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8039 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8040 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8041 { } /* end */
8044 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8046 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8047 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8050 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8051 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8052 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8053 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8054 { } /* end */
8057 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8058 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8059 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8060 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8061 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8062 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8064 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8065 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8066 { } /* end */
8069 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8070 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8071 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8072 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8073 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8076 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8077 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8078 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8079 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8080 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8081 { } /* end */
8084 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8085 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8086 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8087 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8088 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8089 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8090 0x0d, 1, 0x0, HDA_OUTPUT),
8091 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8092 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8093 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8094 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8095 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8101 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8106 { } /* end */
8109 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8110 /* Output mixers */
8111 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8112 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8113 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8114 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8115 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8116 HDA_OUTPUT),
8117 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8118 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8119 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8120 /* Output switches */
8121 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8122 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8123 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8124 /* Boost mixers */
8125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8127 /* Input mixers */
8128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8129 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8130 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8131 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8132 { } /* end */
8135 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8138 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8140 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8141 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8142 { } /* end */
8145 static struct hda_bind_ctls alc883_bind_cap_vol = {
8146 .ops = &snd_hda_bind_vol,
8147 .values = {
8148 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8149 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8154 static struct hda_bind_ctls alc883_bind_cap_switch = {
8155 .ops = &snd_hda_bind_sw,
8156 .values = {
8157 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8158 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8163 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8170 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8172 { } /* end */
8175 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8176 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8177 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8180 /* .name = "Capture Source", */
8181 .name = "Input Source",
8182 .count = 1,
8183 .info = alc_mux_enum_info,
8184 .get = alc_mux_enum_get,
8185 .put = alc_mux_enum_put,
8187 { } /* end */
8190 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8193 .name = "Channel Mode",
8194 .info = alc_ch_mode_info,
8195 .get = alc_ch_mode_get,
8196 .put = alc_ch_mode_put,
8198 { } /* end */
8201 /* toggle speaker-output according to the hp-jack state */
8202 static void alc883_mitac_setup(struct hda_codec *codec)
8204 struct alc_spec *spec = codec->spec;
8206 spec->autocfg.hp_pins[0] = 0x15;
8207 spec->autocfg.speaker_pins[0] = 0x14;
8208 spec->autocfg.speaker_pins[1] = 0x17;
8211 /* auto-toggle front mic */
8213 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8215 unsigned int present;
8216 unsigned char bits;
8218 present = snd_hda_codec_read(codec, 0x18, 0,
8219 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8220 bits = present ? HDA_AMP_MUTE : 0;
8221 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8225 static struct hda_verb alc883_mitac_verbs[] = {
8226 /* HP */
8227 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8228 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8229 /* Subwoofer */
8230 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8231 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8233 /* enable unsolicited event */
8234 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8235 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8237 { } /* end */
8240 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8241 /* HP */
8242 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8244 /* Int speaker */
8245 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8247 /* enable unsolicited event */
8249 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8250 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8253 { } /* end */
8256 static struct hda_verb alc883_clevo_m720_verbs[] = {
8257 /* HP */
8258 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8260 /* Int speaker */
8261 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8264 /* enable unsolicited event */
8265 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8266 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8268 { } /* end */
8271 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8272 /* HP */
8273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8274 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8275 /* Subwoofer */
8276 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8277 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8279 /* enable unsolicited event */
8280 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8282 { } /* end */
8285 static struct hda_verb alc883_targa_verbs[] = {
8286 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8287 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8290 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8292 /* Connect Line-Out side jack (SPDIF) to Side */
8293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8296 /* Connect Mic jack to CLFE */
8297 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8300 /* Connect Line-in jack to Surround */
8301 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8302 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8303 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8304 /* Connect HP out jack to Front */
8305 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8306 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8309 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8311 { } /* end */
8314 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8316 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8317 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8318 { } /* end */
8321 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8322 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8324 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8326 { } /* end */
8329 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8330 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8333 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8334 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8335 { } /* end */
8338 static struct hda_verb alc883_haier_w66_verbs[] = {
8339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8340 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8344 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8345 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8346 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8347 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8348 { } /* end */
8351 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8356 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8357 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8358 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8359 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8360 { } /* end */
8363 static struct hda_verb alc888_6st_dell_verbs[] = {
8364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8368 static struct hda_verb alc883_vaiott_verbs[] = {
8369 /* HP */
8370 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8373 /* enable unsolicited event */
8374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8376 { } /* end */
8379 static void alc888_3st_hp_setup(struct hda_codec *codec)
8381 struct alc_spec *spec = codec->spec;
8383 spec->autocfg.hp_pins[0] = 0x1b;
8384 spec->autocfg.speaker_pins[0] = 0x14;
8385 spec->autocfg.speaker_pins[1] = 0x16;
8386 spec->autocfg.speaker_pins[2] = 0x18;
8389 static struct hda_verb alc888_3st_hp_verbs[] = {
8390 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8391 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8392 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8393 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8394 { } /* end */
8398 * 2ch mode
8400 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8401 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8402 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8403 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8404 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8405 { } /* end */
8409 * 4ch mode
8411 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8412 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8413 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8414 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8415 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8416 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8417 { } /* end */
8421 * 6ch mode
8423 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8424 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8425 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8426 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8427 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8428 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8429 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8430 { } /* end */
8433 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8434 { 2, alc888_3st_hp_2ch_init },
8435 { 4, alc888_3st_hp_4ch_init },
8436 { 6, alc888_3st_hp_6ch_init },
8439 /* toggle front-jack and RCA according to the hp-jack state */
8440 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8442 unsigned int present;
8444 present = snd_hda_codec_read(codec, 0x1b, 0,
8445 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8446 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8447 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8448 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8449 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8452 /* toggle RCA according to the front-jack state */
8453 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8455 unsigned int present;
8457 present = snd_hda_codec_read(codec, 0x14, 0,
8458 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8459 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8460 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8463 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8464 unsigned int res)
8466 if ((res >> 26) == ALC880_HP_EVENT)
8467 alc888_lenovo_ms7195_front_automute(codec);
8468 if ((res >> 26) == ALC880_FRONT_EVENT)
8469 alc888_lenovo_ms7195_rca_automute(codec);
8472 static struct hda_verb alc883_medion_md2_verbs[] = {
8473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8478 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8479 { } /* end */
8482 /* toggle speaker-output according to the hp-jack state */
8483 static void alc883_medion_md2_setup(struct hda_codec *codec)
8485 struct alc_spec *spec = codec->spec;
8487 spec->autocfg.hp_pins[0] = 0x14;
8488 spec->autocfg.speaker_pins[0] = 0x15;
8491 /* toggle speaker-output according to the hp-jack state */
8492 #define alc883_targa_init_hook alc882_targa_init_hook
8493 #define alc883_targa_unsol_event alc882_targa_unsol_event
8495 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8497 unsigned int present;
8499 present = snd_hda_codec_read(codec, 0x18, 0,
8500 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8501 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8502 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8505 static void alc883_clevo_m720_setup(struct hda_codec *codec)
8507 struct alc_spec *spec = codec->spec;
8509 spec->autocfg.hp_pins[0] = 0x15;
8510 spec->autocfg.speaker_pins[0] = 0x14;
8513 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8515 alc_automute_amp(codec);
8516 alc883_clevo_m720_mic_automute(codec);
8519 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8520 unsigned int res)
8522 switch (res >> 26) {
8523 case ALC880_MIC_EVENT:
8524 alc883_clevo_m720_mic_automute(codec);
8525 break;
8526 default:
8527 alc_automute_amp_unsol_event(codec, res);
8528 break;
8532 /* toggle speaker-output according to the hp-jack state */
8533 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8535 struct alc_spec *spec = codec->spec;
8537 spec->autocfg.hp_pins[0] = 0x14;
8538 spec->autocfg.speaker_pins[0] = 0x15;
8541 static void alc883_haier_w66_setup(struct hda_codec *codec)
8543 struct alc_spec *spec = codec->spec;
8545 spec->autocfg.hp_pins[0] = 0x1b;
8546 spec->autocfg.speaker_pins[0] = 0x14;
8549 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8551 unsigned int present;
8552 unsigned char bits;
8554 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8555 & AC_PINSENSE_PRESENCE;
8556 bits = present ? HDA_AMP_MUTE : 0;
8557 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8558 HDA_AMP_MUTE, bits);
8561 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8563 unsigned int present;
8564 unsigned char bits;
8566 present = snd_hda_codec_read(codec, 0x1b, 0,
8567 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8568 bits = present ? HDA_AMP_MUTE : 0;
8569 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8570 HDA_AMP_MUTE, bits);
8571 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8572 HDA_AMP_MUTE, bits);
8575 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8576 unsigned int res)
8578 if ((res >> 26) == ALC880_HP_EVENT)
8579 alc883_lenovo_101e_all_automute(codec);
8580 if ((res >> 26) == ALC880_FRONT_EVENT)
8581 alc883_lenovo_101e_ispeaker_automute(codec);
8584 /* toggle speaker-output according to the hp-jack state */
8585 static void alc883_acer_aspire_setup(struct hda_codec *codec)
8587 struct alc_spec *spec = codec->spec;
8589 spec->autocfg.hp_pins[0] = 0x14;
8590 spec->autocfg.speaker_pins[0] = 0x15;
8591 spec->autocfg.speaker_pins[1] = 0x16;
8594 static struct hda_verb alc883_acer_eapd_verbs[] = {
8595 /* HP Pin: output 0 (0x0c) */
8596 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8597 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8598 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8599 /* Front Pin: output 0 (0x0c) */
8600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8602 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8603 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8604 /* eanable EAPD on medion laptop */
8605 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8606 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8607 /* enable unsolicited event */
8608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8612 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8613 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8614 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8615 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8616 { } /* end */
8619 static void alc888_6st_dell_setup(struct hda_codec *codec)
8621 struct alc_spec *spec = codec->spec;
8623 spec->autocfg.hp_pins[0] = 0x1b;
8624 spec->autocfg.speaker_pins[0] = 0x14;
8625 spec->autocfg.speaker_pins[1] = 0x15;
8626 spec->autocfg.speaker_pins[2] = 0x16;
8627 spec->autocfg.speaker_pins[3] = 0x17;
8630 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8632 struct alc_spec *spec = codec->spec;
8634 spec->autocfg.hp_pins[0] = 0x1b;
8635 spec->autocfg.speaker_pins[0] = 0x14;
8636 spec->autocfg.speaker_pins[1] = 0x15;
8637 spec->autocfg.speaker_pins[2] = 0x16;
8638 spec->autocfg.speaker_pins[3] = 0x17;
8639 spec->autocfg.speaker_pins[4] = 0x1a;
8642 static void alc883_vaiott_setup(struct hda_codec *codec)
8644 struct alc_spec *spec = codec->spec;
8646 spec->autocfg.hp_pins[0] = 0x15;
8647 spec->autocfg.speaker_pins[0] = 0x14;
8648 spec->autocfg.speaker_pins[1] = 0x17;
8651 static struct hda_verb alc888_asus_m90v_verbs[] = {
8652 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8653 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8654 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8655 /* enable unsolicited event */
8656 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8657 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8658 { } /* end */
8661 static void alc883_mode2_setup(struct hda_codec *codec)
8663 struct alc_spec *spec = codec->spec;
8665 spec->autocfg.hp_pins[0] = 0x1b;
8666 spec->autocfg.speaker_pins[0] = 0x14;
8667 spec->autocfg.speaker_pins[1] = 0x15;
8668 spec->autocfg.speaker_pins[2] = 0x16;
8669 spec->ext_mic.pin = 0x18;
8670 spec->int_mic.pin = 0x19;
8671 spec->ext_mic.mux_idx = 0;
8672 spec->int_mic.mux_idx = 1;
8673 spec->auto_mic = 1;
8676 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8677 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8678 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8680 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8681 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8682 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8683 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8684 /* enable unsolicited event */
8685 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8686 { } /* end */
8689 static void alc883_eee1601_inithook(struct hda_codec *codec)
8691 struct alc_spec *spec = codec->spec;
8693 spec->autocfg.hp_pins[0] = 0x14;
8694 spec->autocfg.speaker_pins[0] = 0x1b;
8695 alc_automute_pin(codec);
8698 static struct hda_verb alc889A_mb31_verbs[] = {
8699 /* Init rear pin (used as headphone output) */
8700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8703 /* Init line pin (used as output in 4ch and 6ch mode) */
8704 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8705 /* Init line 2 pin (used as headphone out by default) */
8706 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8707 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8708 { } /* end */
8711 /* Mute speakers according to the headphone jack state */
8712 static void alc889A_mb31_automute(struct hda_codec *codec)
8714 unsigned int present;
8716 /* Mute only in 2ch or 4ch mode */
8717 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8718 == 0x00) {
8719 present = snd_hda_codec_read(codec, 0x15, 0,
8720 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8721 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8722 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8723 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8724 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8728 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8730 if ((res >> 26) == ALC880_HP_EVENT)
8731 alc889A_mb31_automute(codec);
8735 #ifdef CONFIG_SND_HDA_POWER_SAVE
8736 #define alc882_loopbacks alc880_loopbacks
8737 #endif
8739 /* pcm configuration: identical with ALC880 */
8740 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
8741 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
8742 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
8743 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
8745 static hda_nid_t alc883_slave_dig_outs[] = {
8746 ALC1200_DIGOUT_NID, 0,
8749 static hda_nid_t alc1200_slave_dig_outs[] = {
8750 ALC883_DIGOUT_NID, 0,
8754 * configuration and preset
8756 static const char *alc882_models[ALC882_MODEL_LAST] = {
8757 [ALC882_3ST_DIG] = "3stack-dig",
8758 [ALC882_6ST_DIG] = "6stack-dig",
8759 [ALC882_ARIMA] = "arima",
8760 [ALC882_W2JC] = "w2jc",
8761 [ALC882_TARGA] = "targa",
8762 [ALC882_ASUS_A7J] = "asus-a7j",
8763 [ALC882_ASUS_A7M] = "asus-a7m",
8764 [ALC885_MACPRO] = "macpro",
8765 [ALC885_MB5] = "mb5",
8766 [ALC885_MBP3] = "mbp3",
8767 [ALC885_IMAC24] = "imac24",
8768 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
8769 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8770 [ALC883_3ST_6ch] = "3stack-6ch",
8771 [ALC883_6ST_DIG] = "alc883-6stack-dig",
8772 [ALC883_TARGA_DIG] = "targa-dig",
8773 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8774 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
8775 [ALC883_ACER] = "acer",
8776 [ALC883_ACER_ASPIRE] = "acer-aspire",
8777 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8778 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
8779 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8780 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
8781 [ALC883_MEDION] = "medion",
8782 [ALC883_MEDION_MD2] = "medion-md2",
8783 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8784 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8785 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8786 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8787 [ALC888_LENOVO_SKY] = "lenovo-sky",
8788 [ALC883_HAIER_W66] = "haier-w66",
8789 [ALC888_3ST_HP] = "3stack-hp",
8790 [ALC888_6ST_DELL] = "6stack-dell",
8791 [ALC883_MITAC] = "mitac",
8792 [ALC883_CLEVO_M540R] = "clevo-m540r",
8793 [ALC883_CLEVO_M720] = "clevo-m720",
8794 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8795 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8796 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8797 [ALC889A_INTEL] = "intel-alc889a",
8798 [ALC889_INTEL] = "intel-x58",
8799 [ALC1200_ASUS_P5Q] = "asus-p5q",
8800 [ALC889A_MB31] = "mb31",
8801 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
8802 [ALC882_AUTO] = "auto",
8805 static struct snd_pci_quirk alc882_cfg_tbl[] = {
8806 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8808 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8809 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
8810 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
8811 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8812 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8813 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8814 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8815 ALC888_ACER_ASPIRE_4930G),
8816 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8817 ALC888_ACER_ASPIRE_4930G),
8818 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
8819 ALC888_ACER_ASPIRE_8930G),
8820 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
8821 ALC888_ACER_ASPIRE_8930G),
8822 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
8823 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
8824 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8825 ALC888_ACER_ASPIRE_6530G),
8826 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
8827 ALC888_ACER_ASPIRE_6530G),
8828 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8829 ALC888_ACER_ASPIRE_7730G),
8830 /* default Acer -- disabled as it causes more problems.
8831 * model=auto should work fine now
8833 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8835 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8837 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8838 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8839 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8840 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8841 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8842 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8844 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8845 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8846 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
8847 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8848 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8849 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8850 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
8851 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8852 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
8853 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8854 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8856 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
8857 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8858 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
8859 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
8860 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8861 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8862 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8863 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8864 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8866 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8867 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8868 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8869 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
8870 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
8871 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
8872 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8873 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8874 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8875 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8876 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8877 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8878 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8879 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8880 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
8881 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8882 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8883 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8884 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
8885 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8886 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8887 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8888 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8889 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8890 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8891 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8892 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
8893 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8894 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8896 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8897 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8898 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8899 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
8900 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
8901 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8902 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
8903 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8904 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
8905 ALC883_FUJITSU_PI2515),
8906 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
8907 ALC888_FUJITSU_XA3530),
8908 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8909 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8910 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8911 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8912 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8913 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8914 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
8915 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8916 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8918 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8919 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8920 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
8921 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8922 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8923 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
8924 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
8929 /* codec SSID table for Intel Mac */
8930 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8931 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8932 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8933 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8934 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8935 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8936 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8937 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8938 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8939 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8940 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8941 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8942 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
8943 * so apparently no perfect solution yet
8945 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8946 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
8947 {} /* terminator */
8950 static struct alc_config_preset alc882_presets[] = {
8951 [ALC882_3ST_DIG] = {
8952 .mixers = { alc882_base_mixer },
8953 .init_verbs = { alc882_base_init_verbs,
8954 alc882_adc1_init_verbs },
8955 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8956 .dac_nids = alc882_dac_nids,
8957 .dig_out_nid = ALC882_DIGOUT_NID,
8958 .dig_in_nid = ALC882_DIGIN_NID,
8959 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8960 .channel_mode = alc882_ch_modes,
8961 .need_dac_fix = 1,
8962 .input_mux = &alc882_capture_source,
8964 [ALC882_6ST_DIG] = {
8965 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8966 .init_verbs = { alc882_base_init_verbs,
8967 alc882_adc1_init_verbs },
8968 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8969 .dac_nids = alc882_dac_nids,
8970 .dig_out_nid = ALC882_DIGOUT_NID,
8971 .dig_in_nid = ALC882_DIGIN_NID,
8972 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8973 .channel_mode = alc882_sixstack_modes,
8974 .input_mux = &alc882_capture_source,
8976 [ALC882_ARIMA] = {
8977 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8978 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8979 alc882_eapd_verbs },
8980 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8981 .dac_nids = alc882_dac_nids,
8982 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8983 .channel_mode = alc882_sixstack_modes,
8984 .input_mux = &alc882_capture_source,
8986 [ALC882_W2JC] = {
8987 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8988 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8989 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8990 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8991 .dac_nids = alc882_dac_nids,
8992 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8993 .channel_mode = alc880_threestack_modes,
8994 .need_dac_fix = 1,
8995 .input_mux = &alc882_capture_source,
8996 .dig_out_nid = ALC882_DIGOUT_NID,
8998 [ALC885_MBP3] = {
8999 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9000 .init_verbs = { alc885_mbp3_init_verbs,
9001 alc880_gpio1_init_verbs },
9002 .num_dacs = 2,
9003 .dac_nids = alc882_dac_nids,
9004 .hp_nid = 0x04,
9005 .channel_mode = alc885_mbp_4ch_modes,
9006 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9007 .input_mux = &alc882_capture_source,
9008 .dig_out_nid = ALC882_DIGOUT_NID,
9009 .dig_in_nid = ALC882_DIGIN_NID,
9010 .unsol_event = alc_automute_amp_unsol_event,
9011 .setup = alc885_mbp3_setup,
9012 .init_hook = alc_automute_amp,
9014 [ALC885_MB5] = {
9015 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9016 .init_verbs = { alc885_mb5_init_verbs,
9017 alc880_gpio1_init_verbs },
9018 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9019 .dac_nids = alc882_dac_nids,
9020 .channel_mode = alc885_mb5_6ch_modes,
9021 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9022 .input_mux = &mb5_capture_source,
9023 .dig_out_nid = ALC882_DIGOUT_NID,
9024 .dig_in_nid = ALC882_DIGIN_NID,
9025 .unsol_event = alc885_mb5_unsol_event,
9026 .init_hook = alc885_mb5_automute,
9028 [ALC885_MACPRO] = {
9029 .mixers = { alc882_macpro_mixer },
9030 .init_verbs = { alc882_macpro_init_verbs },
9031 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9032 .dac_nids = alc882_dac_nids,
9033 .dig_out_nid = ALC882_DIGOUT_NID,
9034 .dig_in_nid = ALC882_DIGIN_NID,
9035 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9036 .channel_mode = alc882_ch_modes,
9037 .input_mux = &alc882_capture_source,
9038 .init_hook = alc885_macpro_init_hook,
9040 [ALC885_IMAC24] = {
9041 .mixers = { alc885_imac24_mixer },
9042 .init_verbs = { alc885_imac24_init_verbs },
9043 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9044 .dac_nids = alc882_dac_nids,
9045 .dig_out_nid = ALC882_DIGOUT_NID,
9046 .dig_in_nid = ALC882_DIGIN_NID,
9047 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9048 .channel_mode = alc882_ch_modes,
9049 .input_mux = &alc882_capture_source,
9050 .unsol_event = alc_automute_amp_unsol_event,
9051 .setup = alc885_imac24_setup,
9052 .init_hook = alc885_imac24_init_hook,
9054 [ALC882_TARGA] = {
9055 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9056 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9057 alc880_gpio3_init_verbs, alc882_targa_verbs},
9058 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9059 .dac_nids = alc882_dac_nids,
9060 .dig_out_nid = ALC882_DIGOUT_NID,
9061 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9062 .adc_nids = alc882_adc_nids,
9063 .capsrc_nids = alc882_capsrc_nids,
9064 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9065 .channel_mode = alc882_3ST_6ch_modes,
9066 .need_dac_fix = 1,
9067 .input_mux = &alc882_capture_source,
9068 .unsol_event = alc882_targa_unsol_event,
9069 .setup = alc882_targa_setup,
9070 .init_hook = alc882_targa_automute,
9072 [ALC882_ASUS_A7J] = {
9073 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9074 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9075 alc882_asus_a7j_verbs},
9076 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9077 .dac_nids = alc882_dac_nids,
9078 .dig_out_nid = ALC882_DIGOUT_NID,
9079 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9080 .adc_nids = alc882_adc_nids,
9081 .capsrc_nids = alc882_capsrc_nids,
9082 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9083 .channel_mode = alc882_3ST_6ch_modes,
9084 .need_dac_fix = 1,
9085 .input_mux = &alc882_capture_source,
9087 [ALC882_ASUS_A7M] = {
9088 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9089 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9090 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9091 alc882_asus_a7m_verbs },
9092 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9093 .dac_nids = alc882_dac_nids,
9094 .dig_out_nid = ALC882_DIGOUT_NID,
9095 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9096 .channel_mode = alc880_threestack_modes,
9097 .need_dac_fix = 1,
9098 .input_mux = &alc882_capture_source,
9100 [ALC883_3ST_2ch_DIG] = {
9101 .mixers = { alc883_3ST_2ch_mixer },
9102 .init_verbs = { alc883_init_verbs },
9103 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9104 .dac_nids = alc883_dac_nids,
9105 .dig_out_nid = ALC883_DIGOUT_NID,
9106 .dig_in_nid = ALC883_DIGIN_NID,
9107 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9108 .channel_mode = alc883_3ST_2ch_modes,
9109 .input_mux = &alc883_capture_source,
9111 [ALC883_3ST_6ch_DIG] = {
9112 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9113 .init_verbs = { alc883_init_verbs },
9114 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9115 .dac_nids = alc883_dac_nids,
9116 .dig_out_nid = ALC883_DIGOUT_NID,
9117 .dig_in_nid = ALC883_DIGIN_NID,
9118 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9119 .channel_mode = alc883_3ST_6ch_modes,
9120 .need_dac_fix = 1,
9121 .input_mux = &alc883_capture_source,
9123 [ALC883_3ST_6ch] = {
9124 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9125 .init_verbs = { alc883_init_verbs },
9126 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9127 .dac_nids = alc883_dac_nids,
9128 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9129 .channel_mode = alc883_3ST_6ch_modes,
9130 .need_dac_fix = 1,
9131 .input_mux = &alc883_capture_source,
9133 [ALC883_3ST_6ch_INTEL] = {
9134 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9135 .init_verbs = { alc883_init_verbs },
9136 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9137 .dac_nids = alc883_dac_nids,
9138 .dig_out_nid = ALC883_DIGOUT_NID,
9139 .dig_in_nid = ALC883_DIGIN_NID,
9140 .slave_dig_outs = alc883_slave_dig_outs,
9141 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9142 .channel_mode = alc883_3ST_6ch_intel_modes,
9143 .need_dac_fix = 1,
9144 .input_mux = &alc883_3stack_6ch_intel,
9146 [ALC889A_INTEL] = {
9147 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9148 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9149 alc_hp15_unsol_verbs },
9150 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9151 .dac_nids = alc883_dac_nids,
9152 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9153 .adc_nids = alc889_adc_nids,
9154 .dig_out_nid = ALC883_DIGOUT_NID,
9155 .dig_in_nid = ALC883_DIGIN_NID,
9156 .slave_dig_outs = alc883_slave_dig_outs,
9157 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9158 .channel_mode = alc889_8ch_intel_modes,
9159 .capsrc_nids = alc889_capsrc_nids,
9160 .input_mux = &alc889_capture_source,
9161 .setup = alc889_automute_setup,
9162 .init_hook = alc_automute_amp,
9163 .unsol_event = alc_automute_amp_unsol_event,
9164 .need_dac_fix = 1,
9166 [ALC889_INTEL] = {
9167 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9168 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9169 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9171 .dac_nids = alc883_dac_nids,
9172 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9173 .adc_nids = alc889_adc_nids,
9174 .capsrc_nids = alc889_capsrc_nids,
9175 .capsrc_nids = alc889_capsrc_nids,
9176 .dig_out_nid = ALC883_DIGOUT_NID,
9177 .dig_in_nid = ALC883_DIGIN_NID,
9178 .slave_dig_outs = alc883_slave_dig_outs,
9179 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9180 .channel_mode = alc889_8ch_intel_modes,
9181 .capsrc_nids = alc889_capsrc_nids,
9182 .input_mux = &alc889_capture_source,
9183 .setup = alc889_automute_setup,
9184 .init_hook = alc889_intel_init_hook,
9185 .unsol_event = alc_automute_amp_unsol_event,
9186 .need_dac_fix = 1,
9188 [ALC883_6ST_DIG] = {
9189 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9190 .init_verbs = { alc883_init_verbs },
9191 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9192 .dac_nids = alc883_dac_nids,
9193 .dig_out_nid = ALC883_DIGOUT_NID,
9194 .dig_in_nid = ALC883_DIGIN_NID,
9195 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9196 .channel_mode = alc883_sixstack_modes,
9197 .input_mux = &alc883_capture_source,
9199 [ALC883_TARGA_DIG] = {
9200 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9201 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9202 alc883_targa_verbs},
9203 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9204 .dac_nids = alc883_dac_nids,
9205 .dig_out_nid = ALC883_DIGOUT_NID,
9206 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9207 .channel_mode = alc883_3ST_6ch_modes,
9208 .need_dac_fix = 1,
9209 .input_mux = &alc883_capture_source,
9210 .unsol_event = alc883_targa_unsol_event,
9211 .setup = alc882_targa_setup,
9212 .init_hook = alc882_targa_automute,
9214 [ALC883_TARGA_2ch_DIG] = {
9215 .mixers = { alc883_targa_2ch_mixer},
9216 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9217 alc883_targa_verbs},
9218 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9219 .dac_nids = alc883_dac_nids,
9220 .adc_nids = alc883_adc_nids_alt,
9221 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9222 .capsrc_nids = alc883_capsrc_nids,
9223 .dig_out_nid = ALC883_DIGOUT_NID,
9224 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9225 .channel_mode = alc883_3ST_2ch_modes,
9226 .input_mux = &alc883_capture_source,
9227 .unsol_event = alc883_targa_unsol_event,
9228 .setup = alc882_targa_setup,
9229 .init_hook = alc882_targa_automute,
9231 [ALC883_TARGA_8ch_DIG] = {
9232 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9233 alc883_chmode_mixer },
9234 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9235 alc883_targa_verbs },
9236 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9237 .dac_nids = alc883_dac_nids,
9238 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9239 .adc_nids = alc883_adc_nids_rev,
9240 .capsrc_nids = alc883_capsrc_nids_rev,
9241 .dig_out_nid = ALC883_DIGOUT_NID,
9242 .dig_in_nid = ALC883_DIGIN_NID,
9243 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9244 .channel_mode = alc883_4ST_8ch_modes,
9245 .need_dac_fix = 1,
9246 .input_mux = &alc883_capture_source,
9247 .unsol_event = alc883_targa_unsol_event,
9248 .setup = alc882_targa_setup,
9249 .init_hook = alc882_targa_automute,
9251 [ALC883_ACER] = {
9252 .mixers = { alc883_base_mixer },
9253 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9254 * and the headphone jack. Turn this on and rely on the
9255 * standard mute methods whenever the user wants to turn
9256 * these outputs off.
9258 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9259 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9260 .dac_nids = alc883_dac_nids,
9261 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9262 .channel_mode = alc883_3ST_2ch_modes,
9263 .input_mux = &alc883_capture_source,
9265 [ALC883_ACER_ASPIRE] = {
9266 .mixers = { alc883_acer_aspire_mixer },
9267 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9268 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9269 .dac_nids = alc883_dac_nids,
9270 .dig_out_nid = ALC883_DIGOUT_NID,
9271 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9272 .channel_mode = alc883_3ST_2ch_modes,
9273 .input_mux = &alc883_capture_source,
9274 .unsol_event = alc_automute_amp_unsol_event,
9275 .setup = alc883_acer_aspire_setup,
9276 .init_hook = alc_automute_amp,
9278 [ALC888_ACER_ASPIRE_4930G] = {
9279 .mixers = { alc888_base_mixer,
9280 alc883_chmode_mixer },
9281 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9282 alc888_acer_aspire_4930g_verbs },
9283 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9284 .dac_nids = alc883_dac_nids,
9285 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9286 .adc_nids = alc883_adc_nids_rev,
9287 .capsrc_nids = alc883_capsrc_nids_rev,
9288 .dig_out_nid = ALC883_DIGOUT_NID,
9289 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9290 .channel_mode = alc883_3ST_6ch_modes,
9291 .need_dac_fix = 1,
9292 .num_mux_defs =
9293 ARRAY_SIZE(alc888_2_capture_sources),
9294 .input_mux = alc888_2_capture_sources,
9295 .unsol_event = alc_automute_amp_unsol_event,
9296 .setup = alc888_acer_aspire_4930g_setup,
9297 .init_hook = alc_automute_amp,
9299 [ALC888_ACER_ASPIRE_6530G] = {
9300 .mixers = { alc888_acer_aspire_6530_mixer },
9301 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9302 alc888_acer_aspire_6530g_verbs },
9303 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9304 .dac_nids = alc883_dac_nids,
9305 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9306 .adc_nids = alc883_adc_nids_rev,
9307 .capsrc_nids = alc883_capsrc_nids_rev,
9308 .dig_out_nid = ALC883_DIGOUT_NID,
9309 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9310 .channel_mode = alc883_3ST_2ch_modes,
9311 .num_mux_defs =
9312 ARRAY_SIZE(alc888_2_capture_sources),
9313 .input_mux = alc888_acer_aspire_6530_sources,
9314 .unsol_event = alc_automute_amp_unsol_event,
9315 .setup = alc888_acer_aspire_6530g_setup,
9316 .init_hook = alc_automute_amp,
9318 [ALC888_ACER_ASPIRE_8930G] = {
9319 .mixers = { alc888_base_mixer,
9320 alc883_chmode_mixer },
9321 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9322 alc889_acer_aspire_8930g_verbs },
9323 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9324 .dac_nids = alc883_dac_nids,
9325 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9326 .adc_nids = alc889_adc_nids,
9327 .capsrc_nids = alc889_capsrc_nids,
9328 .dig_out_nid = ALC883_DIGOUT_NID,
9329 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9330 .channel_mode = alc883_3ST_6ch_modes,
9331 .need_dac_fix = 1,
9332 .const_channel_count = 6,
9333 .num_mux_defs =
9334 ARRAY_SIZE(alc889_capture_sources),
9335 .input_mux = alc889_capture_sources,
9336 .unsol_event = alc_automute_amp_unsol_event,
9337 .setup = alc889_acer_aspire_8930g_setup,
9338 .init_hook = alc_automute_amp,
9340 [ALC888_ACER_ASPIRE_7730G] = {
9341 .mixers = { alc883_3ST_6ch_mixer,
9342 alc883_chmode_mixer },
9343 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9344 alc888_acer_aspire_7730G_verbs },
9345 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9346 .dac_nids = alc883_dac_nids,
9347 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9348 .adc_nids = alc883_adc_nids_rev,
9349 .capsrc_nids = alc883_capsrc_nids_rev,
9350 .dig_out_nid = ALC883_DIGOUT_NID,
9351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9352 .channel_mode = alc883_3ST_6ch_modes,
9353 .need_dac_fix = 1,
9354 .const_channel_count = 6,
9355 .input_mux = &alc883_capture_source,
9356 .unsol_event = alc_automute_amp_unsol_event,
9357 .setup = alc888_acer_aspire_6530g_setup,
9358 .init_hook = alc_automute_amp,
9360 [ALC883_MEDION] = {
9361 .mixers = { alc883_fivestack_mixer,
9362 alc883_chmode_mixer },
9363 .init_verbs = { alc883_init_verbs,
9364 alc883_medion_eapd_verbs },
9365 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9366 .dac_nids = alc883_dac_nids,
9367 .adc_nids = alc883_adc_nids_alt,
9368 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9369 .capsrc_nids = alc883_capsrc_nids,
9370 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9371 .channel_mode = alc883_sixstack_modes,
9372 .input_mux = &alc883_capture_source,
9374 [ALC883_MEDION_MD2] = {
9375 .mixers = { alc883_medion_md2_mixer},
9376 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9377 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9378 .dac_nids = alc883_dac_nids,
9379 .dig_out_nid = ALC883_DIGOUT_NID,
9380 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9381 .channel_mode = alc883_3ST_2ch_modes,
9382 .input_mux = &alc883_capture_source,
9383 .unsol_event = alc_automute_amp_unsol_event,
9384 .setup = alc883_medion_md2_setup,
9385 .init_hook = alc_automute_amp,
9387 [ALC883_LAPTOP_EAPD] = {
9388 .mixers = { alc883_base_mixer },
9389 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9390 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9391 .dac_nids = alc883_dac_nids,
9392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9393 .channel_mode = alc883_3ST_2ch_modes,
9394 .input_mux = &alc883_capture_source,
9396 [ALC883_CLEVO_M540R] = {
9397 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9398 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9400 .dac_nids = alc883_dac_nids,
9401 .dig_out_nid = ALC883_DIGOUT_NID,
9402 .dig_in_nid = ALC883_DIGIN_NID,
9403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9404 .channel_mode = alc883_3ST_6ch_clevo_modes,
9405 .need_dac_fix = 1,
9406 .input_mux = &alc883_capture_source,
9407 /* This machine has the hardware HP auto-muting, thus
9408 * we need no software mute via unsol event
9411 [ALC883_CLEVO_M720] = {
9412 .mixers = { alc883_clevo_m720_mixer },
9413 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9414 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9415 .dac_nids = alc883_dac_nids,
9416 .dig_out_nid = ALC883_DIGOUT_NID,
9417 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9418 .channel_mode = alc883_3ST_2ch_modes,
9419 .input_mux = &alc883_capture_source,
9420 .unsol_event = alc883_clevo_m720_unsol_event,
9421 .setup = alc883_clevo_m720_setup,
9422 .init_hook = alc883_clevo_m720_init_hook,
9424 [ALC883_LENOVO_101E_2ch] = {
9425 .mixers = { alc883_lenovo_101e_2ch_mixer},
9426 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9427 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9428 .dac_nids = alc883_dac_nids,
9429 .adc_nids = alc883_adc_nids_alt,
9430 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9431 .capsrc_nids = alc883_capsrc_nids,
9432 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9433 .channel_mode = alc883_3ST_2ch_modes,
9434 .input_mux = &alc883_lenovo_101e_capture_source,
9435 .unsol_event = alc883_lenovo_101e_unsol_event,
9436 .init_hook = alc883_lenovo_101e_all_automute,
9438 [ALC883_LENOVO_NB0763] = {
9439 .mixers = { alc883_lenovo_nb0763_mixer },
9440 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9441 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9442 .dac_nids = alc883_dac_nids,
9443 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9444 .channel_mode = alc883_3ST_2ch_modes,
9445 .need_dac_fix = 1,
9446 .input_mux = &alc883_lenovo_nb0763_capture_source,
9447 .unsol_event = alc_automute_amp_unsol_event,
9448 .setup = alc883_medion_md2_setup,
9449 .init_hook = alc_automute_amp,
9451 [ALC888_LENOVO_MS7195_DIG] = {
9452 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9453 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9454 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9455 .dac_nids = alc883_dac_nids,
9456 .dig_out_nid = ALC883_DIGOUT_NID,
9457 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9458 .channel_mode = alc883_3ST_6ch_modes,
9459 .need_dac_fix = 1,
9460 .input_mux = &alc883_capture_source,
9461 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9462 .init_hook = alc888_lenovo_ms7195_front_automute,
9464 [ALC883_HAIER_W66] = {
9465 .mixers = { alc883_targa_2ch_mixer},
9466 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9468 .dac_nids = alc883_dac_nids,
9469 .dig_out_nid = ALC883_DIGOUT_NID,
9470 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9471 .channel_mode = alc883_3ST_2ch_modes,
9472 .input_mux = &alc883_capture_source,
9473 .unsol_event = alc_automute_amp_unsol_event,
9474 .setup = alc883_haier_w66_setup,
9475 .init_hook = alc_automute_amp,
9477 [ALC888_3ST_HP] = {
9478 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9479 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9481 .dac_nids = alc883_dac_nids,
9482 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9483 .channel_mode = alc888_3st_hp_modes,
9484 .need_dac_fix = 1,
9485 .input_mux = &alc883_capture_source,
9486 .unsol_event = alc_automute_amp_unsol_event,
9487 .setup = alc888_3st_hp_setup,
9488 .init_hook = alc_automute_amp,
9490 [ALC888_6ST_DELL] = {
9491 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9492 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9494 .dac_nids = alc883_dac_nids,
9495 .dig_out_nid = ALC883_DIGOUT_NID,
9496 .dig_in_nid = ALC883_DIGIN_NID,
9497 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9498 .channel_mode = alc883_sixstack_modes,
9499 .input_mux = &alc883_capture_source,
9500 .unsol_event = alc_automute_amp_unsol_event,
9501 .setup = alc888_6st_dell_setup,
9502 .init_hook = alc_automute_amp,
9504 [ALC883_MITAC] = {
9505 .mixers = { alc883_mitac_mixer },
9506 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9507 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9508 .dac_nids = alc883_dac_nids,
9509 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9510 .channel_mode = alc883_3ST_2ch_modes,
9511 .input_mux = &alc883_capture_source,
9512 .unsol_event = alc_automute_amp_unsol_event,
9513 .setup = alc883_mitac_setup,
9514 .init_hook = alc_automute_amp,
9516 [ALC883_FUJITSU_PI2515] = {
9517 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9518 .init_verbs = { alc883_init_verbs,
9519 alc883_2ch_fujitsu_pi2515_verbs},
9520 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9521 .dac_nids = alc883_dac_nids,
9522 .dig_out_nid = ALC883_DIGOUT_NID,
9523 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9524 .channel_mode = alc883_3ST_2ch_modes,
9525 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9526 .unsol_event = alc_automute_amp_unsol_event,
9527 .setup = alc883_2ch_fujitsu_pi2515_setup,
9528 .init_hook = alc_automute_amp,
9530 [ALC888_FUJITSU_XA3530] = {
9531 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9532 .init_verbs = { alc883_init_verbs,
9533 alc888_fujitsu_xa3530_verbs },
9534 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9535 .dac_nids = alc883_dac_nids,
9536 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9537 .adc_nids = alc883_adc_nids_rev,
9538 .capsrc_nids = alc883_capsrc_nids_rev,
9539 .dig_out_nid = ALC883_DIGOUT_NID,
9540 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9541 .channel_mode = alc888_4ST_8ch_intel_modes,
9542 .num_mux_defs =
9543 ARRAY_SIZE(alc888_2_capture_sources),
9544 .input_mux = alc888_2_capture_sources,
9545 .unsol_event = alc_automute_amp_unsol_event,
9546 .setup = alc888_fujitsu_xa3530_setup,
9547 .init_hook = alc_automute_amp,
9549 [ALC888_LENOVO_SKY] = {
9550 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9551 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9552 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9553 .dac_nids = alc883_dac_nids,
9554 .dig_out_nid = ALC883_DIGOUT_NID,
9555 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9556 .channel_mode = alc883_sixstack_modes,
9557 .need_dac_fix = 1,
9558 .input_mux = &alc883_lenovo_sky_capture_source,
9559 .unsol_event = alc_automute_amp_unsol_event,
9560 .setup = alc888_lenovo_sky_setup,
9561 .init_hook = alc_automute_amp,
9563 [ALC888_ASUS_M90V] = {
9564 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9565 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9566 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9567 .dac_nids = alc883_dac_nids,
9568 .dig_out_nid = ALC883_DIGOUT_NID,
9569 .dig_in_nid = ALC883_DIGIN_NID,
9570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9571 .channel_mode = alc883_3ST_6ch_modes,
9572 .need_dac_fix = 1,
9573 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9574 .unsol_event = alc_sku_unsol_event,
9575 .setup = alc883_mode2_setup,
9576 .init_hook = alc_inithook,
9578 [ALC888_ASUS_EEE1601] = {
9579 .mixers = { alc883_asus_eee1601_mixer },
9580 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9581 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9582 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9583 .dac_nids = alc883_dac_nids,
9584 .dig_out_nid = ALC883_DIGOUT_NID,
9585 .dig_in_nid = ALC883_DIGIN_NID,
9586 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9587 .channel_mode = alc883_3ST_2ch_modes,
9588 .need_dac_fix = 1,
9589 .input_mux = &alc883_asus_eee1601_capture_source,
9590 .unsol_event = alc_sku_unsol_event,
9591 .init_hook = alc883_eee1601_inithook,
9593 [ALC1200_ASUS_P5Q] = {
9594 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9595 .init_verbs = { alc883_init_verbs },
9596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9597 .dac_nids = alc883_dac_nids,
9598 .dig_out_nid = ALC1200_DIGOUT_NID,
9599 .dig_in_nid = ALC883_DIGIN_NID,
9600 .slave_dig_outs = alc1200_slave_dig_outs,
9601 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9602 .channel_mode = alc883_sixstack_modes,
9603 .input_mux = &alc883_capture_source,
9605 [ALC889A_MB31] = {
9606 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9607 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9608 alc880_gpio1_init_verbs },
9609 .adc_nids = alc883_adc_nids,
9610 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9611 .capsrc_nids = alc883_capsrc_nids,
9612 .dac_nids = alc883_dac_nids,
9613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9614 .channel_mode = alc889A_mb31_6ch_modes,
9615 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9616 .input_mux = &alc889A_mb31_capture_source,
9617 .dig_out_nid = ALC883_DIGOUT_NID,
9618 .unsol_event = alc889A_mb31_unsol_event,
9619 .init_hook = alc889A_mb31_automute,
9621 [ALC883_SONY_VAIO_TT] = {
9622 .mixers = { alc883_vaiott_mixer },
9623 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9624 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9625 .dac_nids = alc883_dac_nids,
9626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9627 .channel_mode = alc883_3ST_2ch_modes,
9628 .input_mux = &alc883_capture_source,
9629 .unsol_event = alc_automute_amp_unsol_event,
9630 .setup = alc883_vaiott_setup,
9631 .init_hook = alc_automute_amp,
9637 * Pin config fixes
9639 enum {
9640 PINFIX_ABIT_AW9D_MAX
9643 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9644 { 0x15, 0x01080104 }, /* side */
9645 { 0x16, 0x01011012 }, /* rear */
9646 { 0x17, 0x01016011 }, /* clfe */
9650 static const struct alc_fixup alc882_fixups[] = {
9651 [PINFIX_ABIT_AW9D_MAX] = {
9652 .pins = alc882_abit_aw9d_pinfix
9656 static struct snd_pci_quirk alc882_fixup_tbl[] = {
9657 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9662 * BIOS auto configuration
9664 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9665 const struct auto_pin_cfg *cfg)
9667 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9670 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9671 hda_nid_t nid, int pin_type,
9672 int dac_idx)
9674 /* set as output */
9675 struct alc_spec *spec = codec->spec;
9676 int idx;
9678 alc_set_pin_output(codec, nid, pin_type);
9679 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9680 idx = 4;
9681 else
9682 idx = spec->multiout.dac_nids[dac_idx] - 2;
9683 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9687 static void alc882_auto_init_multi_out(struct hda_codec *codec)
9689 struct alc_spec *spec = codec->spec;
9690 int i;
9692 for (i = 0; i <= HDA_SIDE; i++) {
9693 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9694 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9695 if (nid)
9696 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9701 static void alc882_auto_init_hp_out(struct hda_codec *codec)
9703 struct alc_spec *spec = codec->spec;
9704 hda_nid_t pin;
9706 pin = spec->autocfg.hp_pins[0];
9707 if (pin) /* connect to front */
9708 /* use dac 0 */
9709 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9710 pin = spec->autocfg.speaker_pins[0];
9711 if (pin)
9712 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9715 static void alc882_auto_init_analog_input(struct hda_codec *codec)
9717 struct alc_spec *spec = codec->spec;
9718 int i;
9720 for (i = 0; i < AUTO_PIN_LAST; i++) {
9721 hda_nid_t nid = spec->autocfg.input_pins[i];
9722 if (!nid)
9723 continue;
9724 alc_set_input_pin(codec, nid, i);
9725 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9726 snd_hda_codec_write(codec, nid, 0,
9727 AC_VERB_SET_AMP_GAIN_MUTE,
9728 AMP_OUT_MUTE);
9732 static void alc882_auto_init_input_src(struct hda_codec *codec)
9734 struct alc_spec *spec = codec->spec;
9735 int c;
9737 for (c = 0; c < spec->num_adc_nids; c++) {
9738 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9739 hda_nid_t nid = spec->capsrc_nids[c];
9740 unsigned int mux_idx;
9741 const struct hda_input_mux *imux;
9742 int conns, mute, idx, item;
9744 conns = snd_hda_get_connections(codec, nid, conn_list,
9745 ARRAY_SIZE(conn_list));
9746 if (conns < 0)
9747 continue;
9748 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9749 imux = &spec->input_mux[mux_idx];
9750 if (!imux->num_items && mux_idx > 0)
9751 imux = &spec->input_mux[0];
9752 for (idx = 0; idx < conns; idx++) {
9753 /* if the current connection is the selected one,
9754 * unmute it as default - otherwise mute it
9756 mute = AMP_IN_MUTE(idx);
9757 for (item = 0; item < imux->num_items; item++) {
9758 if (imux->items[item].index == idx) {
9759 if (spec->cur_mux[c] == item)
9760 mute = AMP_IN_UNMUTE(idx);
9761 break;
9764 /* check if we have a selector or mixer
9765 * we could check for the widget type instead, but
9766 * just check for Amp-In presence (in case of mixer
9767 * without amp-in there is something wrong, this
9768 * function shouldn't be used or capsrc nid is wrong)
9770 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9771 snd_hda_codec_write(codec, nid, 0,
9772 AC_VERB_SET_AMP_GAIN_MUTE,
9773 mute);
9774 else if (mute != AMP_IN_MUTE(idx))
9775 snd_hda_codec_write(codec, nid, 0,
9776 AC_VERB_SET_CONNECT_SEL,
9777 idx);
9782 /* add mic boosts if needed */
9783 static int alc_auto_add_mic_boost(struct hda_codec *codec)
9785 struct alc_spec *spec = codec->spec;
9786 int err;
9787 hda_nid_t nid;
9789 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9790 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9791 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9792 "Mic Boost",
9793 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9794 if (err < 0)
9795 return err;
9797 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9798 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9799 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9800 "Front Mic Boost",
9801 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9802 if (err < 0)
9803 return err;
9805 return 0;
9808 /* almost identical with ALC880 parser... */
9809 static int alc882_parse_auto_config(struct hda_codec *codec)
9811 struct alc_spec *spec = codec->spec;
9812 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9813 int i, err;
9815 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9816 alc882_ignore);
9817 if (err < 0)
9818 return err;
9819 if (!spec->autocfg.line_outs)
9820 return 0; /* can't find valid BIOS pin config */
9822 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9823 if (err < 0)
9824 return err;
9825 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9826 if (err < 0)
9827 return err;
9828 err = alc880_auto_create_extra_out(spec,
9829 spec->autocfg.speaker_pins[0],
9830 "Speaker");
9831 if (err < 0)
9832 return err;
9833 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9834 "Headphone");
9835 if (err < 0)
9836 return err;
9837 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
9838 if (err < 0)
9839 return err;
9841 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9843 /* check multiple SPDIF-out (for recent codecs) */
9844 for (i = 0; i < spec->autocfg.dig_outs; i++) {
9845 hda_nid_t dig_nid;
9846 err = snd_hda_get_connections(codec,
9847 spec->autocfg.dig_out_pins[i],
9848 &dig_nid, 1);
9849 if (err < 0)
9850 continue;
9851 if (!i)
9852 spec->multiout.dig_out_nid = dig_nid;
9853 else {
9854 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9855 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
9856 break;
9857 spec->slave_dig_outs[i - 1] = dig_nid;
9860 if (spec->autocfg.dig_in_pin)
9861 spec->dig_in_nid = ALC880_DIGIN_NID;
9863 if (spec->kctls.list)
9864 add_mixer(spec, spec->kctls.list);
9866 add_verb(spec, alc883_auto_init_verbs);
9867 /* if ADC 0x07 is available, initialize it, too */
9868 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
9869 add_verb(spec, alc882_adc1_init_verbs);
9871 spec->num_mux_defs = 1;
9872 spec->input_mux = &spec->private_imux[0];
9874 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9876 err = alc_auto_add_mic_boost(codec);
9877 if (err < 0)
9878 return err;
9880 return 1; /* config found */
9883 /* additional initialization for auto-configuration model */
9884 static void alc882_auto_init(struct hda_codec *codec)
9886 struct alc_spec *spec = codec->spec;
9887 alc882_auto_init_multi_out(codec);
9888 alc882_auto_init_hp_out(codec);
9889 alc882_auto_init_analog_input(codec);
9890 alc882_auto_init_input_src(codec);
9891 if (spec->unsol_event)
9892 alc_inithook(codec);
9895 static int patch_alc882(struct hda_codec *codec)
9897 struct alc_spec *spec;
9898 int err, board_config;
9900 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9901 if (spec == NULL)
9902 return -ENOMEM;
9904 codec->spec = spec;
9906 switch (codec->vendor_id) {
9907 case 0x10ec0882:
9908 case 0x10ec0885:
9909 break;
9910 default:
9911 /* ALC883 and variants */
9912 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9913 break;
9916 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9917 alc882_models,
9918 alc882_cfg_tbl);
9920 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9921 board_config = snd_hda_check_board_codec_sid_config(codec,
9922 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9924 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9925 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9926 codec->chip_name);
9927 board_config = ALC882_AUTO;
9930 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
9932 if (board_config == ALC882_AUTO) {
9933 /* automatic parse from the BIOS config */
9934 err = alc882_parse_auto_config(codec);
9935 if (err < 0) {
9936 alc_free(codec);
9937 return err;
9938 } else if (!err) {
9939 printk(KERN_INFO
9940 "hda_codec: Cannot set up configuration "
9941 "from BIOS. Using base mode...\n");
9942 board_config = ALC882_3ST_DIG;
9946 err = snd_hda_attach_beep_device(codec, 0x1);
9947 if (err < 0) {
9948 alc_free(codec);
9949 return err;
9952 if (board_config != ALC882_AUTO)
9953 setup_preset(codec, &alc882_presets[board_config]);
9955 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9956 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9957 /* FIXME: setup DAC5 */
9958 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9959 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9961 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9962 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9964 if (codec->vendor_id == 0x10ec0888)
9965 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9967 if (!spec->adc_nids && spec->input_mux) {
9968 int i;
9969 spec->num_adc_nids = 0;
9970 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9971 hda_nid_t cap;
9972 hda_nid_t nid = alc882_adc_nids[i];
9973 unsigned int wcap = get_wcaps(codec, nid);
9974 /* get type */
9975 wcap = get_wcaps_type(wcap);
9976 if (wcap != AC_WID_AUD_IN)
9977 continue;
9978 spec->private_adc_nids[spec->num_adc_nids] = nid;
9979 err = snd_hda_get_connections(codec, nid, &cap, 1);
9980 if (err < 0)
9981 continue;
9982 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9983 spec->num_adc_nids++;
9985 spec->adc_nids = spec->private_adc_nids;
9986 spec->capsrc_nids = spec->private_capsrc_nids;
9989 set_capture_mixer(codec);
9990 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9992 spec->vmaster_nid = 0x0c;
9994 codec->patch_ops = alc_patch_ops;
9995 if (board_config == ALC882_AUTO)
9996 spec->init_hook = alc882_auto_init;
9997 #ifdef CONFIG_SND_HDA_POWER_SAVE
9998 if (!spec->loopback.amplist)
9999 spec->loopback.amplist = alc882_loopbacks;
10000 #endif
10001 codec->proc_widget_hook = print_realtek_coef;
10003 return 0;
10008 * ALC262 support
10011 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10012 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10014 #define alc262_dac_nids alc260_dac_nids
10015 #define alc262_adc_nids alc882_adc_nids
10016 #define alc262_adc_nids_alt alc882_adc_nids_alt
10017 #define alc262_capsrc_nids alc882_capsrc_nids
10018 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10020 #define alc262_modes alc260_modes
10021 #define alc262_capture_source alc882_capture_source
10023 static hda_nid_t alc262_dmic_adc_nids[1] = {
10024 /* ADC0 */
10025 0x09
10028 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10030 static struct snd_kcontrol_new alc262_base_mixer[] = {
10031 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10032 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10033 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10034 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10035 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10036 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10039 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10040 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10041 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10042 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10045 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10046 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10047 { } /* end */
10050 /* update HP, line and mono-out pins according to the master switch */
10051 static void alc262_hp_master_update(struct hda_codec *codec)
10053 struct alc_spec *spec = codec->spec;
10054 int val = spec->master_sw;
10056 /* HP & line-out */
10057 snd_hda_codec_write_cache(codec, 0x1b, 0,
10058 AC_VERB_SET_PIN_WIDGET_CONTROL,
10059 val ? PIN_HP : 0);
10060 snd_hda_codec_write_cache(codec, 0x15, 0,
10061 AC_VERB_SET_PIN_WIDGET_CONTROL,
10062 val ? PIN_HP : 0);
10063 /* mono (speaker) depending on the HP jack sense */
10064 val = val && !spec->jack_present;
10065 snd_hda_codec_write_cache(codec, 0x16, 0,
10066 AC_VERB_SET_PIN_WIDGET_CONTROL,
10067 val ? PIN_OUT : 0);
10070 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10072 struct alc_spec *spec = codec->spec;
10073 unsigned int presence;
10074 presence = snd_hda_codec_read(codec, 0x1b, 0,
10075 AC_VERB_GET_PIN_SENSE, 0);
10076 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10077 alc262_hp_master_update(codec);
10080 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10082 if ((res >> 26) != ALC880_HP_EVENT)
10083 return;
10084 alc262_hp_bpc_automute(codec);
10087 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10089 struct alc_spec *spec = codec->spec;
10090 unsigned int presence;
10091 presence = snd_hda_codec_read(codec, 0x15, 0,
10092 AC_VERB_GET_PIN_SENSE, 0);
10093 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
10094 alc262_hp_master_update(codec);
10097 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10098 unsigned int res)
10100 if ((res >> 26) != ALC880_HP_EVENT)
10101 return;
10102 alc262_hp_wildwest_automute(codec);
10105 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10107 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10108 struct snd_ctl_elem_value *ucontrol)
10110 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10111 struct alc_spec *spec = codec->spec;
10112 int val = !!*ucontrol->value.integer.value;
10114 if (val == spec->master_sw)
10115 return 0;
10116 spec->master_sw = val;
10117 alc262_hp_master_update(codec);
10118 return 1;
10121 #define ALC262_HP_MASTER_SWITCH \
10123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10124 .name = "Master Playback Switch", \
10125 .info = snd_ctl_boolean_mono_info, \
10126 .get = alc262_hp_master_sw_get, \
10127 .put = alc262_hp_master_sw_put, \
10130 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10131 ALC262_HP_MASTER_SWITCH,
10132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10133 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10135 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10136 HDA_OUTPUT),
10137 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10138 HDA_OUTPUT),
10139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10140 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10141 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10142 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10143 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10144 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10145 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10146 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10149 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10150 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10151 { } /* end */
10154 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10155 ALC262_HP_MASTER_SWITCH,
10156 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10157 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10158 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10160 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10161 HDA_OUTPUT),
10162 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10163 HDA_OUTPUT),
10164 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10165 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10166 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10169 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10170 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10171 { } /* end */
10174 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10175 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10176 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10177 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10178 { } /* end */
10181 /* mute/unmute internal speaker according to the hp jack and mute state */
10182 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10184 struct alc_spec *spec = codec->spec;
10186 spec->autocfg.hp_pins[0] = 0x15;
10187 spec->autocfg.speaker_pins[0] = 0x14;
10190 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10197 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10198 { } /* end */
10201 static struct hda_verb alc262_hp_t5735_verbs[] = {
10202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10205 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10209 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10210 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10212 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10213 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10216 { } /* end */
10219 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10220 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10221 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10222 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10223 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10224 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10225 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10226 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10229 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10233 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10234 .num_items = 1,
10235 .items = {
10236 { "Line", 0x1 },
10240 /* bind hp and internal speaker mute (with plug check) as master switch */
10241 static void alc262_hippo_master_update(struct hda_codec *codec)
10243 struct alc_spec *spec = codec->spec;
10244 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10245 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10246 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10247 unsigned int mute;
10249 /* HP */
10250 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10251 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10252 HDA_AMP_MUTE, mute);
10253 /* mute internal speaker per jack sense */
10254 if (spec->jack_present)
10255 mute = HDA_AMP_MUTE;
10256 if (line_nid)
10257 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10258 HDA_AMP_MUTE, mute);
10259 if (speaker_nid && speaker_nid != line_nid)
10260 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10261 HDA_AMP_MUTE, mute);
10264 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10266 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10267 struct snd_ctl_elem_value *ucontrol)
10269 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10270 struct alc_spec *spec = codec->spec;
10271 int val = !!*ucontrol->value.integer.value;
10273 if (val == spec->master_sw)
10274 return 0;
10275 spec->master_sw = val;
10276 alc262_hippo_master_update(codec);
10277 return 1;
10280 #define ALC262_HIPPO_MASTER_SWITCH \
10282 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10283 .name = "Master Playback Switch", \
10284 .info = snd_ctl_boolean_mono_info, \
10285 .get = alc262_hippo_master_sw_get, \
10286 .put = alc262_hippo_master_sw_put, \
10289 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10290 ALC262_HIPPO_MASTER_SWITCH,
10291 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10292 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10293 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10294 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10295 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10297 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10298 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10299 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10300 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10301 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10302 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10303 { } /* end */
10306 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10307 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10308 ALC262_HIPPO_MASTER_SWITCH,
10309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10310 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10315 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10316 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10317 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10318 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10319 { } /* end */
10322 /* mute/unmute internal speaker according to the hp jack and mute state */
10323 static void alc262_hippo_automute(struct hda_codec *codec)
10325 struct alc_spec *spec = codec->spec;
10326 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10327 unsigned int present;
10329 /* need to execute and sync at first */
10330 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10331 present = snd_hda_codec_read(codec, hp_nid, 0,
10332 AC_VERB_GET_PIN_SENSE, 0);
10333 spec->jack_present = (present & 0x80000000) != 0;
10334 alc262_hippo_master_update(codec);
10337 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10339 if ((res >> 26) != ALC880_HP_EVENT)
10340 return;
10341 alc262_hippo_automute(codec);
10344 static void alc262_hippo_setup(struct hda_codec *codec)
10346 struct alc_spec *spec = codec->spec;
10348 spec->autocfg.hp_pins[0] = 0x15;
10349 spec->autocfg.speaker_pins[0] = 0x14;
10352 static void alc262_hippo1_setup(struct hda_codec *codec)
10354 struct alc_spec *spec = codec->spec;
10356 spec->autocfg.hp_pins[0] = 0x1b;
10357 spec->autocfg.speaker_pins[0] = 0x14;
10361 static struct snd_kcontrol_new alc262_sony_mixer[] = {
10362 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10363 ALC262_HIPPO_MASTER_SWITCH,
10364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10366 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10367 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10368 { } /* end */
10371 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10372 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10373 ALC262_HIPPO_MASTER_SWITCH,
10374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10377 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10378 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10379 { } /* end */
10382 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10383 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10384 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10385 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10386 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10390 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10391 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10392 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10393 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10394 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10395 { } /* end */
10398 static struct hda_verb alc262_tyan_verbs[] = {
10399 /* Headphone automute */
10400 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10404 /* P11 AUX_IN, white 4-pin connector */
10405 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10406 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10407 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10408 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10413 /* unsolicited event for HP jack sensing */
10414 static void alc262_tyan_setup(struct hda_codec *codec)
10416 struct alc_spec *spec = codec->spec;
10418 spec->autocfg.hp_pins[0] = 0x1b;
10419 spec->autocfg.speaker_pins[0] = 0x15;
10423 #define alc262_capture_mixer alc882_capture_mixer
10424 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
10427 * generic initialization of ADC, input mixers and output mixers
10429 static struct hda_verb alc262_init_verbs[] = {
10431 * Unmute ADC0-2 and set the default input to mic-in
10433 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10434 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10435 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10437 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10440 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10441 * mixer widget
10442 * Note: PASD motherboards uses the Line In 2 as the input for
10443 * front panel mic (mic 2)
10445 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10446 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10447 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10448 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10449 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10450 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10453 * Set up output mixers (0x0c - 0x0e)
10455 /* set vol=0 to output mixers */
10456 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10457 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10459 /* set up input amps for analog loopback */
10460 /* Amp Indices: DAC = 0, mixer = 1 */
10461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10466 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10470 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10471 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10472 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10473 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10475 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10476 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10477 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10478 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10479 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10484 /* FIXME: use matrix-type input source selection */
10485 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10486 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10487 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10488 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10489 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10490 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10491 /* Input mixer2 */
10492 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10493 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10494 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10495 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10496 /* Input mixer3 */
10497 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10498 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10499 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10500 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10505 static struct hda_verb alc262_eapd_verbs[] = {
10506 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10507 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10511 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10512 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10513 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10514 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10516 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10517 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10521 static struct hda_verb alc262_sony_unsol_verbs[] = {
10522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10523 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10524 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10526 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10527 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10531 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10532 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10533 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10537 { } /* end */
10540 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10541 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10545 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10547 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10548 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10552 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10554 struct alc_spec *spec = codec->spec;
10556 spec->autocfg.hp_pins[0] = 0x15;
10557 spec->autocfg.speaker_pins[0] = 0x14;
10558 spec->ext_mic.pin = 0x18;
10559 spec->ext_mic.mux_idx = 0;
10560 spec->int_mic.pin = 0x12;
10561 spec->int_mic.mux_idx = 9;
10562 spec->auto_mic = 1;
10566 * nec model
10567 * 0x15 = headphone
10568 * 0x16 = internal speaker
10569 * 0x18 = external mic
10572 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10573 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10574 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 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("Mic Boost", 0x18, 0, HDA_INPUT),
10580 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10582 { } /* end */
10585 static struct hda_verb alc262_nec_verbs[] = {
10586 /* Unmute Speaker */
10587 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10589 /* Headphone */
10590 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10593 /* External mic to headphone */
10594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10595 /* External mic to speaker */
10596 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10601 * fujitsu model
10602 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10603 * 0x1b = port replicator headphone out
10606 #define ALC_HP_EVENT 0x37
10608 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10609 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10611 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10612 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10616 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10617 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10618 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10622 static struct hda_input_mux alc262_fujitsu_capture_source = {
10623 .num_items = 3,
10624 .items = {
10625 { "Mic", 0x0 },
10626 { "Int Mic", 0x1 },
10627 { "CD", 0x4 },
10631 static struct hda_input_mux alc262_HP_capture_source = {
10632 .num_items = 5,
10633 .items = {
10634 { "Mic", 0x0 },
10635 { "Front Mic", 0x1 },
10636 { "Line", 0x2 },
10637 { "CD", 0x4 },
10638 { "AUX IN", 0x6 },
10642 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10643 .num_items = 4,
10644 .items = {
10645 { "Mic", 0x0 },
10646 { "Front Mic", 0x2 },
10647 { "Line", 0x1 },
10648 { "CD", 0x4 },
10652 /* mute/unmute internal speaker according to the hp jacks and mute state */
10653 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10655 struct alc_spec *spec = codec->spec;
10656 unsigned int mute;
10658 if (force || !spec->sense_updated) {
10659 unsigned int present;
10660 /* need to execute and sync at first */
10661 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10662 /* check laptop HP jack */
10663 present = snd_hda_codec_read(codec, 0x14, 0,
10664 AC_VERB_GET_PIN_SENSE, 0);
10665 /* need to execute and sync at first */
10666 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10667 /* check docking HP jack */
10668 present |= snd_hda_codec_read(codec, 0x1b, 0,
10669 AC_VERB_GET_PIN_SENSE, 0);
10670 if (present & AC_PINSENSE_PRESENCE)
10671 spec->jack_present = 1;
10672 else
10673 spec->jack_present = 0;
10674 spec->sense_updated = 1;
10676 /* unmute internal speaker only if both HPs are unplugged and
10677 * master switch is on
10679 if (spec->jack_present)
10680 mute = HDA_AMP_MUTE;
10681 else
10682 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10683 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10684 HDA_AMP_MUTE, mute);
10687 /* unsolicited event for HP jack sensing */
10688 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10689 unsigned int res)
10691 if ((res >> 26) != ALC_HP_EVENT)
10692 return;
10693 alc262_fujitsu_automute(codec, 1);
10696 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10698 alc262_fujitsu_automute(codec, 1);
10701 /* bind volumes of both NID 0x0c and 0x0d */
10702 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10703 .ops = &snd_hda_bind_vol,
10704 .values = {
10705 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10706 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10711 /* mute/unmute internal speaker according to the hp jack and mute state */
10712 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10714 struct alc_spec *spec = codec->spec;
10715 unsigned int mute;
10717 if (force || !spec->sense_updated) {
10718 unsigned int present_int_hp;
10719 /* need to execute and sync at first */
10720 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10721 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10722 AC_VERB_GET_PIN_SENSE, 0);
10723 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10724 spec->sense_updated = 1;
10726 if (spec->jack_present) {
10727 /* mute internal speaker */
10728 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10729 HDA_AMP_MUTE, HDA_AMP_MUTE);
10730 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10731 HDA_AMP_MUTE, HDA_AMP_MUTE);
10732 } else {
10733 /* unmute internal speaker if necessary */
10734 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10735 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10736 HDA_AMP_MUTE, mute);
10737 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10738 HDA_AMP_MUTE, mute);
10742 /* unsolicited event for HP jack sensing */
10743 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10744 unsigned int res)
10746 if ((res >> 26) != ALC_HP_EVENT)
10747 return;
10748 alc262_lenovo_3000_automute(codec, 1);
10751 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
10752 int dir, int idx, long *valp)
10754 int i, change = 0;
10756 for (i = 0; i < 2; i++, valp++)
10757 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
10758 HDA_AMP_MUTE,
10759 *valp ? 0 : HDA_AMP_MUTE);
10760 return change;
10763 /* bind hp and internal speaker mute (with plug check) */
10764 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10765 struct snd_ctl_elem_value *ucontrol)
10767 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10768 long *valp = ucontrol->value.integer.value;
10769 int change;
10771 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
10772 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10773 if (change)
10774 alc262_fujitsu_automute(codec, 0);
10775 return change;
10778 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10779 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10781 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10782 .name = "Master Playback Switch",
10783 .info = snd_hda_mixer_amp_switch_info,
10784 .get = snd_hda_mixer_amp_switch_get,
10785 .put = alc262_fujitsu_master_sw_put,
10786 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10791 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10792 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10793 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10794 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10795 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10796 { } /* end */
10799 /* bind hp and internal speaker mute (with plug check) */
10800 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10801 struct snd_ctl_elem_value *ucontrol)
10803 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10804 long *valp = ucontrol->value.integer.value;
10805 int change;
10807 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
10808 if (change)
10809 alc262_lenovo_3000_automute(codec, 0);
10810 return change;
10813 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10814 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10816 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10817 .name = "Master Playback Switch",
10818 .info = snd_hda_mixer_amp_switch_info,
10819 .get = snd_hda_mixer_amp_switch_get,
10820 .put = alc262_lenovo_3000_master_sw_put,
10821 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10823 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10824 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10825 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10828 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10829 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10830 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10831 { } /* end */
10834 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10835 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10836 ALC262_HIPPO_MASTER_SWITCH,
10837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10839 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10840 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10841 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10842 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10843 { } /* end */
10846 /* additional init verbs for Benq laptops */
10847 static struct hda_verb alc262_EAPD_verbs[] = {
10848 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10849 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10853 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10854 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10855 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10857 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10858 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10862 /* Samsung Q1 Ultra Vista model setup */
10863 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10864 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10865 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10866 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10868 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10869 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10870 { } /* end */
10873 static struct hda_verb alc262_ultra_verbs[] = {
10874 /* output mixer */
10875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10878 /* speaker */
10879 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10880 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10881 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10882 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10883 /* HP */
10884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10885 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10887 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10888 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10889 /* internal mic */
10890 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10891 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10892 /* ADC, choose mic */
10893 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10898 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10899 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10900 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10901 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10902 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10906 /* mute/unmute internal speaker according to the hp jack and mute state */
10907 static void alc262_ultra_automute(struct hda_codec *codec)
10909 struct alc_spec *spec = codec->spec;
10910 unsigned int mute;
10912 mute = 0;
10913 /* auto-mute only when HP is used as HP */
10914 if (!spec->cur_mux[0]) {
10915 unsigned int present;
10916 /* need to execute and sync at first */
10917 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10918 present = snd_hda_codec_read(codec, 0x15, 0,
10919 AC_VERB_GET_PIN_SENSE, 0);
10920 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10921 if (spec->jack_present)
10922 mute = HDA_AMP_MUTE;
10924 /* mute/unmute internal speaker */
10925 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10926 HDA_AMP_MUTE, mute);
10927 /* mute/unmute HP */
10928 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10929 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10932 /* unsolicited event for HP jack sensing */
10933 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10934 unsigned int res)
10936 if ((res >> 26) != ALC880_HP_EVENT)
10937 return;
10938 alc262_ultra_automute(codec);
10941 static struct hda_input_mux alc262_ultra_capture_source = {
10942 .num_items = 2,
10943 .items = {
10944 { "Mic", 0x1 },
10945 { "Headphone", 0x7 },
10949 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10950 struct snd_ctl_elem_value *ucontrol)
10952 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10953 struct alc_spec *spec = codec->spec;
10954 int ret;
10956 ret = alc_mux_enum_put(kcontrol, ucontrol);
10957 if (!ret)
10958 return 0;
10959 /* reprogram the HP pin as mic or HP according to the input source */
10960 snd_hda_codec_write_cache(codec, 0x15, 0,
10961 AC_VERB_SET_PIN_WIDGET_CONTROL,
10962 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10963 alc262_ultra_automute(codec); /* mute/unmute HP */
10964 return ret;
10967 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10968 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10969 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10971 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10972 .name = "Capture Source",
10973 .info = alc_mux_enum_info,
10974 .get = alc_mux_enum_get,
10975 .put = alc262_ultra_mux_enum_put,
10977 { } /* end */
10980 /* We use two mixers depending on the output pin; 0x16 is a mono output
10981 * and thus it's bound with a different mixer.
10982 * This function returns which mixer amp should be used.
10984 static int alc262_check_volbit(hda_nid_t nid)
10986 if (!nid)
10987 return 0;
10988 else if (nid == 0x16)
10989 return 2;
10990 else
10991 return 1;
10994 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10995 const char *pfx, int *vbits)
10997 char name[32];
10998 unsigned long val;
10999 int vbit;
11001 vbit = alc262_check_volbit(nid);
11002 if (!vbit)
11003 return 0;
11004 if (*vbits & vbit) /* a volume control for this mixer already there */
11005 return 0;
11006 *vbits |= vbit;
11007 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
11008 if (vbit == 2)
11009 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11010 else
11011 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11012 return add_control(spec, ALC_CTL_WIDGET_VOL, name, val);
11015 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11016 const char *pfx)
11018 char name[32];
11019 unsigned long val;
11021 if (!nid)
11022 return 0;
11023 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
11024 if (nid == 0x16)
11025 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11026 else
11027 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11028 return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val);
11031 /* add playback controls from the parsed DAC table */
11032 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11033 const struct auto_pin_cfg *cfg)
11035 const char *pfx;
11036 int vbits;
11037 int err;
11039 spec->multiout.num_dacs = 1; /* only use one dac */
11040 spec->multiout.dac_nids = spec->private_dac_nids;
11041 spec->multiout.dac_nids[0] = 2;
11043 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11044 pfx = "Master";
11045 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11046 pfx = "Speaker";
11047 else
11048 pfx = "Front";
11049 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11050 if (err < 0)
11051 return err;
11052 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11053 if (err < 0)
11054 return err;
11055 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11056 if (err < 0)
11057 return err;
11059 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11060 alc262_check_volbit(cfg->speaker_pins[0]) |
11061 alc262_check_volbit(cfg->hp_pins[0]);
11062 if (vbits == 1 || vbits == 2)
11063 pfx = "Master"; /* only one mixer is used */
11064 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11065 pfx = "Speaker";
11066 else
11067 pfx = "Front";
11068 vbits = 0;
11069 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11070 if (err < 0)
11071 return err;
11072 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11073 &vbits);
11074 if (err < 0)
11075 return err;
11076 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11077 &vbits);
11078 if (err < 0)
11079 return err;
11080 return 0;
11083 #define alc262_auto_create_input_ctls \
11084 alc880_auto_create_input_ctls
11087 * generic initialization of ADC, input mixers and output mixers
11089 static struct hda_verb alc262_volume_init_verbs[] = {
11091 * Unmute ADC0-2 and set the default input to mic-in
11093 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11094 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11095 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11096 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11097 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11098 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11100 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11101 * mixer widget
11102 * Note: PASD motherboards uses the Line In 2 as the input for
11103 * front panel mic (mic 2)
11105 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11109 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11110 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11113 * Set up output mixers (0x0c - 0x0f)
11115 /* set vol=0 to output mixers */
11116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11117 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11118 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11120 /* set up input amps for analog loopback */
11121 /* Amp Indices: DAC = 0, mixer = 1 */
11122 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11123 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11124 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11125 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11126 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11127 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11129 /* FIXME: use matrix-type input source selection */
11130 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11131 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11132 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11136 /* Input mixer2 */
11137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11139 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11141 /* Input mixer3 */
11142 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11143 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11150 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11152 * Unmute ADC0-2 and set the default input to mic-in
11154 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11155 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11156 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11157 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11158 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11159 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11161 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11162 * mixer widget
11163 * Note: PASD motherboards uses the Line In 2 as the input for
11164 * front panel mic (mic 2)
11166 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11167 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11168 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11169 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11170 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11171 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11172 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11173 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11176 * Set up output mixers (0x0c - 0x0e)
11178 /* set vol=0 to output mixers */
11179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11180 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11181 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11183 /* set up input amps for analog loopback */
11184 /* Amp Indices: DAC = 0, mixer = 1 */
11185 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11186 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11187 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11188 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11192 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11194 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11196 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11197 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11199 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11200 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11202 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11203 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11204 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11205 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11206 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11209 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11210 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11211 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11212 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11213 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11216 /* FIXME: use matrix-type input source selection */
11217 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11218 /* Input mixer1: only unmute Mic */
11219 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11220 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11221 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11222 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11223 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11224 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11225 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11226 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11227 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11228 /* Input mixer2 */
11229 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11230 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11231 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11232 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11233 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11234 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11235 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11236 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11237 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11238 /* Input mixer3 */
11239 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11240 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11241 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11242 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11243 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11244 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11245 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11249 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11254 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11256 * Unmute ADC0-2 and set the default input to mic-in
11258 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11259 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11260 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11261 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11262 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11263 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11265 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11266 * mixer widget
11267 * Note: PASD motherboards uses the Line In 2 as the input for front
11268 * panel mic (mic 2)
11270 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11271 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11272 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11273 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11274 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11275 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11276 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11277 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11278 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11280 * Set up output mixers (0x0c - 0x0e)
11282 /* set vol=0 to output mixers */
11283 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11284 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11287 /* set up input amps for analog loopback */
11288 /* Amp Indices: DAC = 0, mixer = 1 */
11289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11290 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11291 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11292 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11293 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11294 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11297 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11298 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11300 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11301 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11302 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11303 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11305 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11308 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11309 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11311 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11312 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11313 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11315 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11316 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11318 /* FIXME: use matrix-type input source selection */
11319 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11320 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11321 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11322 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11323 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11324 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11325 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11326 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11328 /* Input mixer2 */
11329 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11330 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11334 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11335 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11336 /* Input mixer3 */
11337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11340 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11341 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11342 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11345 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11350 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11352 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11353 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11354 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11356 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11357 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11359 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11361 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11362 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11368 #ifdef CONFIG_SND_HDA_POWER_SAVE
11369 #define alc262_loopbacks alc880_loopbacks
11370 #endif
11372 /* pcm configuration: identical with ALC880 */
11373 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
11374 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
11375 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
11376 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
11379 * BIOS auto configuration
11381 static int alc262_parse_auto_config(struct hda_codec *codec)
11383 struct alc_spec *spec = codec->spec;
11384 int err;
11385 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11387 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11388 alc262_ignore);
11389 if (err < 0)
11390 return err;
11391 if (!spec->autocfg.line_outs) {
11392 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11393 spec->multiout.max_channels = 2;
11394 spec->no_analog = 1;
11395 goto dig_only;
11397 return 0; /* can't find valid BIOS pin config */
11399 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11400 if (err < 0)
11401 return err;
11402 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11403 if (err < 0)
11404 return err;
11406 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11408 dig_only:
11409 if (spec->autocfg.dig_outs) {
11410 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11411 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11413 if (spec->autocfg.dig_in_pin)
11414 spec->dig_in_nid = ALC262_DIGIN_NID;
11416 if (spec->kctls.list)
11417 add_mixer(spec, spec->kctls.list);
11419 add_verb(spec, alc262_volume_init_verbs);
11420 spec->num_mux_defs = 1;
11421 spec->input_mux = &spec->private_imux[0];
11423 err = alc_auto_add_mic_boost(codec);
11424 if (err < 0)
11425 return err;
11427 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11429 return 1;
11432 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11433 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11434 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11435 #define alc262_auto_init_input_src alc882_auto_init_input_src
11438 /* init callback for auto-configuration model -- overriding the default init */
11439 static void alc262_auto_init(struct hda_codec *codec)
11441 struct alc_spec *spec = codec->spec;
11442 alc262_auto_init_multi_out(codec);
11443 alc262_auto_init_hp_out(codec);
11444 alc262_auto_init_analog_input(codec);
11445 alc262_auto_init_input_src(codec);
11446 if (spec->unsol_event)
11447 alc_inithook(codec);
11451 * configuration and preset
11453 static const char *alc262_models[ALC262_MODEL_LAST] = {
11454 [ALC262_BASIC] = "basic",
11455 [ALC262_HIPPO] = "hippo",
11456 [ALC262_HIPPO_1] = "hippo_1",
11457 [ALC262_FUJITSU] = "fujitsu",
11458 [ALC262_HP_BPC] = "hp-bpc",
11459 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11460 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11461 [ALC262_HP_RP5700] = "hp-rp5700",
11462 [ALC262_BENQ_ED8] = "benq",
11463 [ALC262_BENQ_T31] = "benq-t31",
11464 [ALC262_SONY_ASSAMD] = "sony-assamd",
11465 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11466 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11467 [ALC262_ULTRA] = "ultra",
11468 [ALC262_LENOVO_3000] = "lenovo-3000",
11469 [ALC262_NEC] = "nec",
11470 [ALC262_TYAN] = "tyan",
11471 [ALC262_AUTO] = "auto",
11474 static struct snd_pci_quirk alc262_cfg_tbl[] = {
11475 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11476 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11477 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11478 ALC262_HP_BPC),
11479 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11480 ALC262_HP_BPC),
11481 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11482 ALC262_HP_BPC),
11483 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11484 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11485 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11486 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11487 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11488 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11489 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11490 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11491 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11492 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11493 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11494 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11495 ALC262_HP_TC_T5735),
11496 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11497 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11498 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11499 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11500 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11501 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11502 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
11503 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
11504 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11505 ALC262_SONY_ASSAMD),
11506 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11507 ALC262_TOSHIBA_RX1),
11508 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11509 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11510 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11511 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11512 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11513 ALC262_ULTRA),
11514 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11515 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11516 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11517 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11518 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11522 static struct alc_config_preset alc262_presets[] = {
11523 [ALC262_BASIC] = {
11524 .mixers = { alc262_base_mixer },
11525 .init_verbs = { alc262_init_verbs },
11526 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11527 .dac_nids = alc262_dac_nids,
11528 .hp_nid = 0x03,
11529 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11530 .channel_mode = alc262_modes,
11531 .input_mux = &alc262_capture_source,
11533 [ALC262_HIPPO] = {
11534 .mixers = { alc262_hippo_mixer },
11535 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11536 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11537 .dac_nids = alc262_dac_nids,
11538 .hp_nid = 0x03,
11539 .dig_out_nid = ALC262_DIGOUT_NID,
11540 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11541 .channel_mode = alc262_modes,
11542 .input_mux = &alc262_capture_source,
11543 .unsol_event = alc262_hippo_unsol_event,
11544 .setup = alc262_hippo_setup,
11545 .init_hook = alc262_hippo_automute,
11547 [ALC262_HIPPO_1] = {
11548 .mixers = { alc262_hippo1_mixer },
11549 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11550 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11551 .dac_nids = alc262_dac_nids,
11552 .hp_nid = 0x02,
11553 .dig_out_nid = ALC262_DIGOUT_NID,
11554 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11555 .channel_mode = alc262_modes,
11556 .input_mux = &alc262_capture_source,
11557 .unsol_event = alc262_hippo_unsol_event,
11558 .setup = alc262_hippo1_setup,
11559 .init_hook = alc262_hippo_automute,
11561 [ALC262_FUJITSU] = {
11562 .mixers = { alc262_fujitsu_mixer },
11563 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11564 alc262_fujitsu_unsol_verbs },
11565 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11566 .dac_nids = alc262_dac_nids,
11567 .hp_nid = 0x03,
11568 .dig_out_nid = ALC262_DIGOUT_NID,
11569 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11570 .channel_mode = alc262_modes,
11571 .input_mux = &alc262_fujitsu_capture_source,
11572 .unsol_event = alc262_fujitsu_unsol_event,
11573 .init_hook = alc262_fujitsu_init_hook,
11575 [ALC262_HP_BPC] = {
11576 .mixers = { alc262_HP_BPC_mixer },
11577 .init_verbs = { alc262_HP_BPC_init_verbs },
11578 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11579 .dac_nids = alc262_dac_nids,
11580 .hp_nid = 0x03,
11581 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11582 .channel_mode = alc262_modes,
11583 .input_mux = &alc262_HP_capture_source,
11584 .unsol_event = alc262_hp_bpc_unsol_event,
11585 .init_hook = alc262_hp_bpc_automute,
11587 [ALC262_HP_BPC_D7000_WF] = {
11588 .mixers = { alc262_HP_BPC_WildWest_mixer },
11589 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11590 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11591 .dac_nids = alc262_dac_nids,
11592 .hp_nid = 0x03,
11593 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11594 .channel_mode = alc262_modes,
11595 .input_mux = &alc262_HP_D7000_capture_source,
11596 .unsol_event = alc262_hp_wildwest_unsol_event,
11597 .init_hook = alc262_hp_wildwest_automute,
11599 [ALC262_HP_BPC_D7000_WL] = {
11600 .mixers = { alc262_HP_BPC_WildWest_mixer,
11601 alc262_HP_BPC_WildWest_option_mixer },
11602 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11603 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11604 .dac_nids = alc262_dac_nids,
11605 .hp_nid = 0x03,
11606 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11607 .channel_mode = alc262_modes,
11608 .input_mux = &alc262_HP_D7000_capture_source,
11609 .unsol_event = alc262_hp_wildwest_unsol_event,
11610 .init_hook = alc262_hp_wildwest_automute,
11612 [ALC262_HP_TC_T5735] = {
11613 .mixers = { alc262_hp_t5735_mixer },
11614 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11615 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11616 .dac_nids = alc262_dac_nids,
11617 .hp_nid = 0x03,
11618 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11619 .channel_mode = alc262_modes,
11620 .input_mux = &alc262_capture_source,
11621 .unsol_event = alc_sku_unsol_event,
11622 .setup = alc262_hp_t5735_setup,
11623 .init_hook = alc_inithook,
11625 [ALC262_HP_RP5700] = {
11626 .mixers = { alc262_hp_rp5700_mixer },
11627 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11628 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11629 .dac_nids = alc262_dac_nids,
11630 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11631 .channel_mode = alc262_modes,
11632 .input_mux = &alc262_hp_rp5700_capture_source,
11634 [ALC262_BENQ_ED8] = {
11635 .mixers = { alc262_base_mixer },
11636 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11637 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11638 .dac_nids = alc262_dac_nids,
11639 .hp_nid = 0x03,
11640 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11641 .channel_mode = alc262_modes,
11642 .input_mux = &alc262_capture_source,
11644 [ALC262_SONY_ASSAMD] = {
11645 .mixers = { alc262_sony_mixer },
11646 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11647 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11648 .dac_nids = alc262_dac_nids,
11649 .hp_nid = 0x02,
11650 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11651 .channel_mode = alc262_modes,
11652 .input_mux = &alc262_capture_source,
11653 .unsol_event = alc262_hippo_unsol_event,
11654 .setup = alc262_hippo_setup,
11655 .init_hook = alc262_hippo_automute,
11657 [ALC262_BENQ_T31] = {
11658 .mixers = { alc262_benq_t31_mixer },
11659 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11660 alc_hp15_unsol_verbs },
11661 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11662 .dac_nids = alc262_dac_nids,
11663 .hp_nid = 0x03,
11664 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11665 .channel_mode = alc262_modes,
11666 .input_mux = &alc262_capture_source,
11667 .unsol_event = alc262_hippo_unsol_event,
11668 .setup = alc262_hippo_setup,
11669 .init_hook = alc262_hippo_automute,
11671 [ALC262_ULTRA] = {
11672 .mixers = { alc262_ultra_mixer },
11673 .cap_mixer = alc262_ultra_capture_mixer,
11674 .init_verbs = { alc262_ultra_verbs },
11675 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11676 .dac_nids = alc262_dac_nids,
11677 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11678 .channel_mode = alc262_modes,
11679 .input_mux = &alc262_ultra_capture_source,
11680 .adc_nids = alc262_adc_nids, /* ADC0 */
11681 .capsrc_nids = alc262_capsrc_nids,
11682 .num_adc_nids = 1, /* single ADC */
11683 .unsol_event = alc262_ultra_unsol_event,
11684 .init_hook = alc262_ultra_automute,
11686 [ALC262_LENOVO_3000] = {
11687 .mixers = { alc262_lenovo_3000_mixer },
11688 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11689 alc262_lenovo_3000_unsol_verbs },
11690 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11691 .dac_nids = alc262_dac_nids,
11692 .hp_nid = 0x03,
11693 .dig_out_nid = ALC262_DIGOUT_NID,
11694 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11695 .channel_mode = alc262_modes,
11696 .input_mux = &alc262_fujitsu_capture_source,
11697 .unsol_event = alc262_lenovo_3000_unsol_event,
11699 [ALC262_NEC] = {
11700 .mixers = { alc262_nec_mixer },
11701 .init_verbs = { alc262_nec_verbs },
11702 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11703 .dac_nids = alc262_dac_nids,
11704 .hp_nid = 0x03,
11705 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11706 .channel_mode = alc262_modes,
11707 .input_mux = &alc262_capture_source,
11709 [ALC262_TOSHIBA_S06] = {
11710 .mixers = { alc262_toshiba_s06_mixer },
11711 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11712 alc262_eapd_verbs },
11713 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11714 .capsrc_nids = alc262_dmic_capsrc_nids,
11715 .dac_nids = alc262_dac_nids,
11716 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11717 .num_adc_nids = 1, /* single ADC */
11718 .dig_out_nid = ALC262_DIGOUT_NID,
11719 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11720 .channel_mode = alc262_modes,
11721 .unsol_event = alc_sku_unsol_event,
11722 .setup = alc262_toshiba_s06_setup,
11723 .init_hook = alc_inithook,
11725 [ALC262_TOSHIBA_RX1] = {
11726 .mixers = { alc262_toshiba_rx1_mixer },
11727 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11728 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11729 .dac_nids = alc262_dac_nids,
11730 .hp_nid = 0x03,
11731 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11732 .channel_mode = alc262_modes,
11733 .input_mux = &alc262_capture_source,
11734 .unsol_event = alc262_hippo_unsol_event,
11735 .setup = alc262_hippo_setup,
11736 .init_hook = alc262_hippo_automute,
11738 [ALC262_TYAN] = {
11739 .mixers = { alc262_tyan_mixer },
11740 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11741 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11742 .dac_nids = alc262_dac_nids,
11743 .hp_nid = 0x02,
11744 .dig_out_nid = ALC262_DIGOUT_NID,
11745 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11746 .channel_mode = alc262_modes,
11747 .input_mux = &alc262_capture_source,
11748 .unsol_event = alc_automute_amp_unsol_event,
11749 .setup = alc262_tyan_setup,
11750 .init_hook = alc_automute_amp,
11754 static int patch_alc262(struct hda_codec *codec)
11756 struct alc_spec *spec;
11757 int board_config;
11758 int err;
11760 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11761 if (spec == NULL)
11762 return -ENOMEM;
11764 codec->spec = spec;
11765 #if 0
11766 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11767 * under-run
11770 int tmp;
11771 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11772 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11773 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11774 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11776 #endif
11778 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11780 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11781 alc262_models,
11782 alc262_cfg_tbl);
11784 if (board_config < 0) {
11785 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11786 codec->chip_name);
11787 board_config = ALC262_AUTO;
11790 if (board_config == ALC262_AUTO) {
11791 /* automatic parse from the BIOS config */
11792 err = alc262_parse_auto_config(codec);
11793 if (err < 0) {
11794 alc_free(codec);
11795 return err;
11796 } else if (!err) {
11797 printk(KERN_INFO
11798 "hda_codec: Cannot set up configuration "
11799 "from BIOS. Using base mode...\n");
11800 board_config = ALC262_BASIC;
11804 if (!spec->no_analog) {
11805 err = snd_hda_attach_beep_device(codec, 0x1);
11806 if (err < 0) {
11807 alc_free(codec);
11808 return err;
11812 if (board_config != ALC262_AUTO)
11813 setup_preset(codec, &alc262_presets[board_config]);
11815 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11816 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11818 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11819 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11821 if (!spec->adc_nids && spec->input_mux) {
11822 int i;
11823 /* check whether the digital-mic has to be supported */
11824 for (i = 0; i < spec->input_mux->num_items; i++) {
11825 if (spec->input_mux->items[i].index >= 9)
11826 break;
11828 if (i < spec->input_mux->num_items) {
11829 /* use only ADC0 */
11830 spec->adc_nids = alc262_dmic_adc_nids;
11831 spec->num_adc_nids = 1;
11832 spec->capsrc_nids = alc262_dmic_capsrc_nids;
11833 } else {
11834 /* all analog inputs */
11835 /* check whether NID 0x07 is valid */
11836 unsigned int wcap = get_wcaps(codec, 0x07);
11838 /* get type */
11839 wcap = get_wcaps_type(wcap);
11840 if (wcap != AC_WID_AUD_IN) {
11841 spec->adc_nids = alc262_adc_nids_alt;
11842 spec->num_adc_nids =
11843 ARRAY_SIZE(alc262_adc_nids_alt);
11844 spec->capsrc_nids = alc262_capsrc_nids_alt;
11845 } else {
11846 spec->adc_nids = alc262_adc_nids;
11847 spec->num_adc_nids =
11848 ARRAY_SIZE(alc262_adc_nids);
11849 spec->capsrc_nids = alc262_capsrc_nids;
11853 if (!spec->cap_mixer && !spec->no_analog)
11854 set_capture_mixer(codec);
11855 if (!spec->no_analog)
11856 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11858 spec->vmaster_nid = 0x0c;
11860 codec->patch_ops = alc_patch_ops;
11861 if (board_config == ALC262_AUTO)
11862 spec->init_hook = alc262_auto_init;
11863 #ifdef CONFIG_SND_HDA_POWER_SAVE
11864 if (!spec->loopback.amplist)
11865 spec->loopback.amplist = alc262_loopbacks;
11866 #endif
11867 codec->proc_widget_hook = print_realtek_coef;
11869 return 0;
11873 * ALC268 channel source setting (2 channel)
11875 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11876 #define alc268_modes alc260_modes
11878 static hda_nid_t alc268_dac_nids[2] = {
11879 /* front, hp */
11880 0x02, 0x03
11883 static hda_nid_t alc268_adc_nids[2] = {
11884 /* ADC0-1 */
11885 0x08, 0x07
11888 static hda_nid_t alc268_adc_nids_alt[1] = {
11889 /* ADC0 */
11890 0x08
11893 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11895 static struct snd_kcontrol_new alc268_base_mixer[] = {
11896 /* output mixer control */
11897 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11898 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11899 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11901 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11902 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11903 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11907 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11908 /* output mixer control */
11909 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11910 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11911 ALC262_HIPPO_MASTER_SWITCH,
11912 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11913 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11914 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11918 /* bind Beep switches of both NID 0x0f and 0x10 */
11919 static struct hda_bind_ctls alc268_bind_beep_sw = {
11920 .ops = &snd_hda_bind_sw,
11921 .values = {
11922 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11923 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11928 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11929 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11930 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11934 static struct hda_verb alc268_eapd_verbs[] = {
11935 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11936 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11940 /* Toshiba specific */
11941 static struct hda_verb alc268_toshiba_verbs[] = {
11942 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11943 { } /* end */
11946 /* Acer specific */
11947 /* bind volumes of both NID 0x02 and 0x03 */
11948 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11949 .ops = &snd_hda_bind_vol,
11950 .values = {
11951 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11952 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11957 /* mute/unmute internal speaker according to the hp jack and mute state */
11958 static void alc268_acer_automute(struct hda_codec *codec, int force)
11960 struct alc_spec *spec = codec->spec;
11961 unsigned int mute;
11963 if (force || !spec->sense_updated) {
11964 unsigned int present;
11965 present = snd_hda_codec_read(codec, 0x14, 0,
11966 AC_VERB_GET_PIN_SENSE, 0);
11967 spec->jack_present = (present & 0x80000000) != 0;
11968 spec->sense_updated = 1;
11970 if (spec->jack_present)
11971 mute = HDA_AMP_MUTE; /* mute internal speaker */
11972 else /* unmute internal speaker if necessary */
11973 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11974 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11975 HDA_AMP_MUTE, mute);
11979 /* bind hp and internal speaker mute (with plug check) */
11980 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11981 struct snd_ctl_elem_value *ucontrol)
11983 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11984 long *valp = ucontrol->value.integer.value;
11985 int change;
11987 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11988 if (change)
11989 alc268_acer_automute(codec, 0);
11990 return change;
11993 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11994 /* output mixer control */
11995 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11997 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11998 .name = "Master Playback Switch",
11999 .info = snd_hda_mixer_amp_switch_info,
12000 .get = snd_hda_mixer_amp_switch_get,
12001 .put = alc268_acer_master_sw_put,
12002 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12004 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12008 static struct snd_kcontrol_new alc268_acer_mixer[] = {
12009 /* output mixer control */
12010 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12013 .name = "Master Playback Switch",
12014 .info = snd_hda_mixer_amp_switch_info,
12015 .get = snd_hda_mixer_amp_switch_get,
12016 .put = alc268_acer_master_sw_put,
12017 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12020 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12021 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12025 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12026 /* output mixer control */
12027 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12029 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12030 .name = "Master Playback Switch",
12031 .info = snd_hda_mixer_amp_switch_info,
12032 .get = snd_hda_mixer_amp_switch_get,
12033 .put = alc268_acer_master_sw_put,
12034 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12036 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12037 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12041 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12042 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12043 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12045 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12046 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12047 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12051 static struct hda_verb alc268_acer_verbs[] = {
12052 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12053 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12055 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12056 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12057 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12058 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12062 /* unsolicited event for HP jack sensing */
12063 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12064 #define alc268_toshiba_setup alc262_hippo_setup
12065 #define alc268_toshiba_automute alc262_hippo_automute
12067 static void alc268_acer_unsol_event(struct hda_codec *codec,
12068 unsigned int res)
12070 if ((res >> 26) != ALC880_HP_EVENT)
12071 return;
12072 alc268_acer_automute(codec, 1);
12075 static void alc268_acer_init_hook(struct hda_codec *codec)
12077 alc268_acer_automute(codec, 1);
12080 /* toggle speaker-output according to the hp-jack state */
12081 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12083 unsigned int present;
12084 unsigned char bits;
12086 present = snd_hda_codec_read(codec, 0x15, 0,
12087 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12088 bits = present ? AMP_IN_MUTE(0) : 0;
12089 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12090 AMP_IN_MUTE(0), bits);
12091 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12092 AMP_IN_MUTE(0), bits);
12095 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12096 unsigned int res)
12098 switch (res >> 26) {
12099 case ALC880_HP_EVENT:
12100 alc268_aspire_one_speaker_automute(codec);
12101 break;
12102 case ALC880_MIC_EVENT:
12103 alc_mic_automute(codec);
12104 break;
12108 static void alc268_acer_lc_setup(struct hda_codec *codec)
12110 struct alc_spec *spec = codec->spec;
12111 spec->ext_mic.pin = 0x18;
12112 spec->ext_mic.mux_idx = 0;
12113 spec->int_mic.pin = 0x12;
12114 spec->int_mic.mux_idx = 6;
12115 spec->auto_mic = 1;
12118 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12120 alc268_aspire_one_speaker_automute(codec);
12121 alc_mic_automute(codec);
12124 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12125 /* output mixer control */
12126 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12127 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12128 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12129 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12130 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12131 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12135 static struct hda_verb alc268_dell_verbs[] = {
12136 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12137 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12138 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12139 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12143 /* mute/unmute internal speaker according to the hp jack and mute state */
12144 static void alc268_dell_setup(struct hda_codec *codec)
12146 struct alc_spec *spec = codec->spec;
12148 spec->autocfg.hp_pins[0] = 0x15;
12149 spec->autocfg.speaker_pins[0] = 0x14;
12150 spec->ext_mic.pin = 0x18;
12151 spec->ext_mic.mux_idx = 0;
12152 spec->int_mic.pin = 0x19;
12153 spec->int_mic.mux_idx = 1;
12154 spec->auto_mic = 1;
12157 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12158 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12159 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12160 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12161 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12162 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12163 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12164 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12165 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12169 static struct hda_verb alc267_quanta_il1_verbs[] = {
12170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12175 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12177 struct alc_spec *spec = codec->spec;
12178 spec->autocfg.hp_pins[0] = 0x15;
12179 spec->autocfg.speaker_pins[0] = 0x14;
12180 spec->ext_mic.pin = 0x18;
12181 spec->ext_mic.mux_idx = 0;
12182 spec->int_mic.pin = 0x19;
12183 spec->int_mic.mux_idx = 1;
12184 spec->auto_mic = 1;
12188 * generic initialization of ADC, input mixers and output mixers
12190 static struct hda_verb alc268_base_init_verbs[] = {
12191 /* Unmute DAC0-1 and set vol = 0 */
12192 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12193 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12196 * Set up output mixers (0x0c - 0x0e)
12198 /* set vol=0 to output mixers */
12199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12200 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12202 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12203 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12206 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12207 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12208 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12209 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12210 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12211 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12212 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12214 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12216 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12217 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12220 /* set PCBEEP vol = 0, mute connections */
12221 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12223 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12225 /* Unmute Selector 23h,24h and set the default input to mic-in */
12227 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12228 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12229 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12230 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12236 * generic initialization of ADC, input mixers and output mixers
12238 static struct hda_verb alc268_volume_init_verbs[] = {
12239 /* set output DAC */
12240 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12241 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12243 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12244 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12245 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12246 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12247 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12249 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12251 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12253 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12256 /* set PCBEEP vol = 0, mute connections */
12257 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12258 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12259 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12264 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12265 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12266 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12267 { } /* end */
12270 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12271 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12272 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12273 _DEFINE_CAPSRC(1),
12274 { } /* end */
12277 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12278 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12279 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12280 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12281 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12282 _DEFINE_CAPSRC(2),
12283 { } /* end */
12286 static struct hda_input_mux alc268_capture_source = {
12287 .num_items = 4,
12288 .items = {
12289 { "Mic", 0x0 },
12290 { "Front Mic", 0x1 },
12291 { "Line", 0x2 },
12292 { "CD", 0x3 },
12296 static struct hda_input_mux alc268_acer_capture_source = {
12297 .num_items = 3,
12298 .items = {
12299 { "Mic", 0x0 },
12300 { "Internal Mic", 0x1 },
12301 { "Line", 0x2 },
12305 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12306 .num_items = 3,
12307 .items = {
12308 { "Mic", 0x0 },
12309 { "Internal Mic", 0x6 },
12310 { "Line", 0x2 },
12314 #ifdef CONFIG_SND_DEBUG
12315 static struct snd_kcontrol_new alc268_test_mixer[] = {
12316 /* Volume widgets */
12317 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12318 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12319 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12320 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12321 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12322 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12323 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12324 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12325 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12326 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12327 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12328 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12329 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12330 /* The below appears problematic on some hardwares */
12331 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12332 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12333 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12334 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12335 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12337 /* Modes for retasking pin widgets */
12338 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12339 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12340 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12341 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12343 /* Controls for GPIO pins, assuming they are configured as outputs */
12344 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12345 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12346 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12347 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12349 /* Switches to allow the digital SPDIF output pin to be enabled.
12350 * The ALC268 does not have an SPDIF input.
12352 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12354 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12355 * this output to turn on an external amplifier.
12357 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12358 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12360 { } /* end */
12362 #endif
12364 /* create input playback/capture controls for the given pin */
12365 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12366 const char *ctlname, int idx)
12368 char name[32];
12369 hda_nid_t dac;
12370 int err;
12372 sprintf(name, "%s Playback Volume", ctlname);
12373 switch (nid) {
12374 case 0x14:
12375 case 0x16:
12376 dac = 0x02;
12377 break;
12378 case 0x15:
12379 dac = 0x03;
12380 break;
12381 default:
12382 return 0;
12384 if (spec->multiout.dac_nids[0] != dac &&
12385 spec->multiout.dac_nids[1] != dac) {
12386 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12387 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12388 HDA_OUTPUT));
12389 if (err < 0)
12390 return err;
12391 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12394 sprintf(name, "%s Playback Switch", ctlname);
12395 if (nid != 0x16)
12396 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12397 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12398 else /* mono */
12399 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12400 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12401 if (err < 0)
12402 return err;
12403 return 0;
12406 /* add playback controls from the parsed DAC table */
12407 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12408 const struct auto_pin_cfg *cfg)
12410 hda_nid_t nid;
12411 int err;
12413 spec->multiout.dac_nids = spec->private_dac_nids;
12415 nid = cfg->line_out_pins[0];
12416 if (nid) {
12417 const char *name;
12418 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12419 name = "Speaker";
12420 else
12421 name = "Front";
12422 err = alc268_new_analog_output(spec, nid, name, 0);
12423 if (err < 0)
12424 return err;
12427 nid = cfg->speaker_pins[0];
12428 if (nid == 0x1d) {
12429 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12430 "Speaker Playback Volume",
12431 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12432 if (err < 0)
12433 return err;
12434 } else {
12435 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12436 if (err < 0)
12437 return err;
12439 nid = cfg->hp_pins[0];
12440 if (nid) {
12441 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12442 if (err < 0)
12443 return err;
12446 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12447 if (nid == 0x16) {
12448 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12449 "Mono Playback Switch",
12450 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12451 if (err < 0)
12452 return err;
12454 return 0;
12457 /* create playback/capture controls for input pins */
12458 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12459 const struct auto_pin_cfg *cfg)
12461 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12464 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12465 hda_nid_t nid, int pin_type)
12467 int idx;
12469 alc_set_pin_output(codec, nid, pin_type);
12470 if (nid == 0x14 || nid == 0x16)
12471 idx = 0;
12472 else
12473 idx = 1;
12474 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12477 static void alc268_auto_init_multi_out(struct hda_codec *codec)
12479 struct alc_spec *spec = codec->spec;
12480 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12481 if (nid) {
12482 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12483 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12487 static void alc268_auto_init_hp_out(struct hda_codec *codec)
12489 struct alc_spec *spec = codec->spec;
12490 hda_nid_t pin;
12492 pin = spec->autocfg.hp_pins[0];
12493 if (pin)
12494 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12495 pin = spec->autocfg.speaker_pins[0];
12496 if (pin)
12497 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12500 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12502 struct alc_spec *spec = codec->spec;
12503 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12504 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12505 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12506 unsigned int dac_vol1, dac_vol2;
12508 if (line_nid == 0x1d || speaker_nid == 0x1d) {
12509 snd_hda_codec_write(codec, speaker_nid, 0,
12510 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12511 /* mute mixer inputs from 0x1d */
12512 snd_hda_codec_write(codec, 0x0f, 0,
12513 AC_VERB_SET_AMP_GAIN_MUTE,
12514 AMP_IN_UNMUTE(1));
12515 snd_hda_codec_write(codec, 0x10, 0,
12516 AC_VERB_SET_AMP_GAIN_MUTE,
12517 AMP_IN_UNMUTE(1));
12518 } else {
12519 /* unmute mixer inputs from 0x1d */
12520 snd_hda_codec_write(codec, 0x0f, 0,
12521 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12522 snd_hda_codec_write(codec, 0x10, 0,
12523 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12526 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12527 if (line_nid == 0x14)
12528 dac_vol2 = AMP_OUT_ZERO;
12529 else if (line_nid == 0x15)
12530 dac_vol1 = AMP_OUT_ZERO;
12531 if (hp_nid == 0x14)
12532 dac_vol2 = AMP_OUT_ZERO;
12533 else if (hp_nid == 0x15)
12534 dac_vol1 = AMP_OUT_ZERO;
12535 if (line_nid != 0x16 || hp_nid != 0x16 ||
12536 spec->autocfg.line_out_pins[1] != 0x16 ||
12537 spec->autocfg.line_out_pins[2] != 0x16)
12538 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12540 snd_hda_codec_write(codec, 0x02, 0,
12541 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12542 snd_hda_codec_write(codec, 0x03, 0,
12543 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12546 /* pcm configuration: identical with ALC880 */
12547 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12548 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12549 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12550 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12553 * BIOS auto configuration
12555 static int alc268_parse_auto_config(struct hda_codec *codec)
12557 struct alc_spec *spec = codec->spec;
12558 int err;
12559 static hda_nid_t alc268_ignore[] = { 0 };
12561 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12562 alc268_ignore);
12563 if (err < 0)
12564 return err;
12565 if (!spec->autocfg.line_outs) {
12566 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12567 spec->multiout.max_channels = 2;
12568 spec->no_analog = 1;
12569 goto dig_only;
12571 return 0; /* can't find valid BIOS pin config */
12573 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12574 if (err < 0)
12575 return err;
12576 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12577 if (err < 0)
12578 return err;
12580 spec->multiout.max_channels = 2;
12582 dig_only:
12583 /* digital only support output */
12584 if (spec->autocfg.dig_outs) {
12585 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12586 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12588 if (spec->kctls.list)
12589 add_mixer(spec, spec->kctls.list);
12591 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12592 add_mixer(spec, alc268_beep_mixer);
12594 add_verb(spec, alc268_volume_init_verbs);
12595 spec->num_mux_defs = 2;
12596 spec->input_mux = &spec->private_imux[0];
12598 err = alc_auto_add_mic_boost(codec);
12599 if (err < 0)
12600 return err;
12602 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
12604 return 1;
12607 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12609 /* init callback for auto-configuration model -- overriding the default init */
12610 static void alc268_auto_init(struct hda_codec *codec)
12612 struct alc_spec *spec = codec->spec;
12613 alc268_auto_init_multi_out(codec);
12614 alc268_auto_init_hp_out(codec);
12615 alc268_auto_init_mono_speaker_out(codec);
12616 alc268_auto_init_analog_input(codec);
12617 if (spec->unsol_event)
12618 alc_inithook(codec);
12622 * configuration and preset
12624 static const char *alc268_models[ALC268_MODEL_LAST] = {
12625 [ALC267_QUANTA_IL1] = "quanta-il1",
12626 [ALC268_3ST] = "3stack",
12627 [ALC268_TOSHIBA] = "toshiba",
12628 [ALC268_ACER] = "acer",
12629 [ALC268_ACER_DMIC] = "acer-dmic",
12630 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12631 [ALC268_DELL] = "dell",
12632 [ALC268_ZEPTO] = "zepto",
12633 #ifdef CONFIG_SND_DEBUG
12634 [ALC268_TEST] = "test",
12635 #endif
12636 [ALC268_AUTO] = "auto",
12639 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12640 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12641 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12642 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12643 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12644 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12645 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12646 ALC268_ACER_ASPIRE_ONE),
12647 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12648 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
12649 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
12650 /* almost compatible with toshiba but with optional digital outs;
12651 * auto-probing seems working fine
12653 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12654 ALC268_AUTO),
12655 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12656 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12657 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12658 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12659 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12660 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12664 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
12665 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12666 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
12667 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
12668 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12669 ALC268_TOSHIBA),
12673 static struct alc_config_preset alc268_presets[] = {
12674 [ALC267_QUANTA_IL1] = {
12675 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12676 alc268_capture_nosrc_mixer },
12677 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12678 alc267_quanta_il1_verbs },
12679 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12680 .dac_nids = alc268_dac_nids,
12681 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12682 .adc_nids = alc268_adc_nids_alt,
12683 .hp_nid = 0x03,
12684 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12685 .channel_mode = alc268_modes,
12686 .unsol_event = alc_sku_unsol_event,
12687 .setup = alc267_quanta_il1_setup,
12688 .init_hook = alc_inithook,
12690 [ALC268_3ST] = {
12691 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12692 alc268_beep_mixer },
12693 .init_verbs = { alc268_base_init_verbs },
12694 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12695 .dac_nids = alc268_dac_nids,
12696 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12697 .adc_nids = alc268_adc_nids_alt,
12698 .capsrc_nids = alc268_capsrc_nids,
12699 .hp_nid = 0x03,
12700 .dig_out_nid = ALC268_DIGOUT_NID,
12701 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12702 .channel_mode = alc268_modes,
12703 .input_mux = &alc268_capture_source,
12705 [ALC268_TOSHIBA] = {
12706 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12707 alc268_beep_mixer },
12708 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12709 alc268_toshiba_verbs },
12710 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12711 .dac_nids = alc268_dac_nids,
12712 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12713 .adc_nids = alc268_adc_nids_alt,
12714 .capsrc_nids = alc268_capsrc_nids,
12715 .hp_nid = 0x03,
12716 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12717 .channel_mode = alc268_modes,
12718 .input_mux = &alc268_capture_source,
12719 .unsol_event = alc268_toshiba_unsol_event,
12720 .setup = alc268_toshiba_setup,
12721 .init_hook = alc268_toshiba_automute,
12723 [ALC268_ACER] = {
12724 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12725 alc268_beep_mixer },
12726 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12727 alc268_acer_verbs },
12728 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12729 .dac_nids = alc268_dac_nids,
12730 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12731 .adc_nids = alc268_adc_nids_alt,
12732 .capsrc_nids = alc268_capsrc_nids,
12733 .hp_nid = 0x02,
12734 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12735 .channel_mode = alc268_modes,
12736 .input_mux = &alc268_acer_capture_source,
12737 .unsol_event = alc268_acer_unsol_event,
12738 .init_hook = alc268_acer_init_hook,
12740 [ALC268_ACER_DMIC] = {
12741 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12742 alc268_beep_mixer },
12743 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12744 alc268_acer_verbs },
12745 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12746 .dac_nids = alc268_dac_nids,
12747 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12748 .adc_nids = alc268_adc_nids_alt,
12749 .capsrc_nids = alc268_capsrc_nids,
12750 .hp_nid = 0x02,
12751 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12752 .channel_mode = alc268_modes,
12753 .input_mux = &alc268_acer_dmic_capture_source,
12754 .unsol_event = alc268_acer_unsol_event,
12755 .init_hook = alc268_acer_init_hook,
12757 [ALC268_ACER_ASPIRE_ONE] = {
12758 .mixers = { alc268_acer_aspire_one_mixer,
12759 alc268_beep_mixer,
12760 alc268_capture_nosrc_mixer },
12761 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12762 alc268_acer_aspire_one_verbs },
12763 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12764 .dac_nids = alc268_dac_nids,
12765 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12766 .adc_nids = alc268_adc_nids_alt,
12767 .capsrc_nids = alc268_capsrc_nids,
12768 .hp_nid = 0x03,
12769 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12770 .channel_mode = alc268_modes,
12771 .unsol_event = alc268_acer_lc_unsol_event,
12772 .setup = alc268_acer_lc_setup,
12773 .init_hook = alc268_acer_lc_init_hook,
12775 [ALC268_DELL] = {
12776 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12777 alc268_capture_nosrc_mixer },
12778 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12779 alc268_dell_verbs },
12780 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12781 .dac_nids = alc268_dac_nids,
12782 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12783 .adc_nids = alc268_adc_nids_alt,
12784 .capsrc_nids = alc268_capsrc_nids,
12785 .hp_nid = 0x02,
12786 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12787 .channel_mode = alc268_modes,
12788 .unsol_event = alc_sku_unsol_event,
12789 .setup = alc268_dell_setup,
12790 .init_hook = alc_inithook,
12792 [ALC268_ZEPTO] = {
12793 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12794 alc268_beep_mixer },
12795 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12796 alc268_toshiba_verbs },
12797 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12798 .dac_nids = alc268_dac_nids,
12799 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12800 .adc_nids = alc268_adc_nids_alt,
12801 .capsrc_nids = alc268_capsrc_nids,
12802 .hp_nid = 0x03,
12803 .dig_out_nid = ALC268_DIGOUT_NID,
12804 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12805 .channel_mode = alc268_modes,
12806 .input_mux = &alc268_capture_source,
12807 .setup = alc268_toshiba_setup,
12808 .init_hook = alc268_toshiba_automute,
12810 #ifdef CONFIG_SND_DEBUG
12811 [ALC268_TEST] = {
12812 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12813 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12814 alc268_volume_init_verbs },
12815 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12816 .dac_nids = alc268_dac_nids,
12817 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12818 .adc_nids = alc268_adc_nids_alt,
12819 .capsrc_nids = alc268_capsrc_nids,
12820 .hp_nid = 0x03,
12821 .dig_out_nid = ALC268_DIGOUT_NID,
12822 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12823 .channel_mode = alc268_modes,
12824 .input_mux = &alc268_capture_source,
12826 #endif
12829 static int patch_alc268(struct hda_codec *codec)
12831 struct alc_spec *spec;
12832 int board_config;
12833 int i, has_beep, err;
12835 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12836 if (spec == NULL)
12837 return -ENOMEM;
12839 codec->spec = spec;
12841 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12842 alc268_models,
12843 alc268_cfg_tbl);
12845 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
12846 board_config = snd_hda_check_board_codec_sid_config(codec,
12847 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12849 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12850 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12851 codec->chip_name);
12852 board_config = ALC268_AUTO;
12855 if (board_config == ALC268_AUTO) {
12856 /* automatic parse from the BIOS config */
12857 err = alc268_parse_auto_config(codec);
12858 if (err < 0) {
12859 alc_free(codec);
12860 return err;
12861 } else if (!err) {
12862 printk(KERN_INFO
12863 "hda_codec: Cannot set up configuration "
12864 "from BIOS. Using base mode...\n");
12865 board_config = ALC268_3ST;
12869 if (board_config != ALC268_AUTO)
12870 setup_preset(codec, &alc268_presets[board_config]);
12872 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12873 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12874 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12876 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12878 has_beep = 0;
12879 for (i = 0; i < spec->num_mixers; i++) {
12880 if (spec->mixers[i] == alc268_beep_mixer) {
12881 has_beep = 1;
12882 break;
12886 if (has_beep) {
12887 err = snd_hda_attach_beep_device(codec, 0x1);
12888 if (err < 0) {
12889 alc_free(codec);
12890 return err;
12892 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12893 /* override the amp caps for beep generator */
12894 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12895 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12896 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12897 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12898 (0 << AC_AMPCAP_MUTE_SHIFT));
12901 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12902 /* check whether NID 0x07 is valid */
12903 unsigned int wcap = get_wcaps(codec, 0x07);
12904 int i;
12906 spec->capsrc_nids = alc268_capsrc_nids;
12907 /* get type */
12908 wcap = get_wcaps_type(wcap);
12909 if (spec->auto_mic ||
12910 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12911 spec->adc_nids = alc268_adc_nids_alt;
12912 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12913 if (spec->auto_mic)
12914 fixup_automic_adc(codec);
12915 if (spec->auto_mic || spec->input_mux->num_items == 1)
12916 add_mixer(spec, alc268_capture_nosrc_mixer);
12917 else
12918 add_mixer(spec, alc268_capture_alt_mixer);
12919 } else {
12920 spec->adc_nids = alc268_adc_nids;
12921 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12922 add_mixer(spec, alc268_capture_mixer);
12924 /* set default input source */
12925 for (i = 0; i < spec->num_adc_nids; i++)
12926 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12927 0, AC_VERB_SET_CONNECT_SEL,
12928 i < spec->num_mux_defs ?
12929 spec->input_mux[i].items[0].index :
12930 spec->input_mux->items[0].index);
12933 spec->vmaster_nid = 0x02;
12935 codec->patch_ops = alc_patch_ops;
12936 if (board_config == ALC268_AUTO)
12937 spec->init_hook = alc268_auto_init;
12939 codec->proc_widget_hook = print_realtek_coef;
12941 return 0;
12945 * ALC269 channel source setting (2 channel)
12947 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12949 #define alc269_dac_nids alc260_dac_nids
12951 static hda_nid_t alc269_adc_nids[1] = {
12952 /* ADC1 */
12953 0x08,
12956 static hda_nid_t alc269_capsrc_nids[1] = {
12957 0x23,
12960 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12961 * not a mux!
12964 #define alc269_modes alc260_modes
12965 #define alc269_capture_source alc880_lg_lw_capture_source
12967 static struct snd_kcontrol_new alc269_base_mixer[] = {
12968 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12969 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12970 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12971 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12974 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12975 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12977 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12978 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12979 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12980 { } /* end */
12983 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12984 /* output mixer control */
12985 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12988 .name = "Master Playback Switch",
12989 .info = snd_hda_mixer_amp_switch_info,
12990 .get = snd_hda_mixer_amp_switch_get,
12991 .put = alc268_acer_master_sw_put,
12992 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12996 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12997 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12998 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12999 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13003 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13004 /* output mixer control */
13005 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13008 .name = "Master Playback Switch",
13009 .info = snd_hda_mixer_amp_switch_info,
13010 .get = snd_hda_mixer_amp_switch_get,
13011 .put = alc268_acer_master_sw_put,
13012 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13016 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13017 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13018 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13019 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13020 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13021 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13022 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
13026 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13027 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13028 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13030 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13031 { } /* end */
13034 /* capture mixer elements */
13035 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
13036 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13037 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13038 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13039 { } /* end */
13042 /* FSC amilo */
13043 #define alc269_fujitsu_mixer alc269_eeepc_mixer
13045 static struct hda_verb alc269_quanta_fl1_verbs[] = {
13046 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13047 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13048 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13049 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13050 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13051 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13055 static struct hda_verb alc269_lifebook_verbs[] = {
13056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13057 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13058 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13059 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13060 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13061 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13063 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13064 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13065 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13069 /* toggle speaker-output according to the hp-jack state */
13070 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13072 unsigned int present;
13073 unsigned char bits;
13075 present = snd_hda_codec_read(codec, 0x15, 0,
13076 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13077 bits = present ? AMP_IN_MUTE(0) : 0;
13078 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13079 AMP_IN_MUTE(0), bits);
13080 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13081 AMP_IN_MUTE(0), bits);
13083 snd_hda_codec_write(codec, 0x20, 0,
13084 AC_VERB_SET_COEF_INDEX, 0x0c);
13085 snd_hda_codec_write(codec, 0x20, 0,
13086 AC_VERB_SET_PROC_COEF, 0x680);
13088 snd_hda_codec_write(codec, 0x20, 0,
13089 AC_VERB_SET_COEF_INDEX, 0x0c);
13090 snd_hda_codec_write(codec, 0x20, 0,
13091 AC_VERB_SET_PROC_COEF, 0x480);
13094 /* toggle speaker-output according to the hp-jacks state */
13095 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13097 unsigned int present;
13098 unsigned char bits;
13100 /* Check laptop headphone socket */
13101 present = snd_hda_codec_read(codec, 0x15, 0,
13102 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13104 /* Check port replicator headphone socket */
13105 present |= snd_hda_codec_read(codec, 0x1a, 0,
13106 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13108 bits = present ? AMP_IN_MUTE(0) : 0;
13109 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13110 AMP_IN_MUTE(0), bits);
13111 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13112 AMP_IN_MUTE(0), bits);
13114 snd_hda_codec_write(codec, 0x20, 0,
13115 AC_VERB_SET_COEF_INDEX, 0x0c);
13116 snd_hda_codec_write(codec, 0x20, 0,
13117 AC_VERB_SET_PROC_COEF, 0x680);
13119 snd_hda_codec_write(codec, 0x20, 0,
13120 AC_VERB_SET_COEF_INDEX, 0x0c);
13121 snd_hda_codec_write(codec, 0x20, 0,
13122 AC_VERB_SET_PROC_COEF, 0x480);
13125 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13127 unsigned int present_laptop;
13128 unsigned int present_dock;
13130 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
13131 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13133 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
13134 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13136 /* Laptop mic port overrides dock mic port, design decision */
13137 if (present_dock)
13138 snd_hda_codec_write(codec, 0x23, 0,
13139 AC_VERB_SET_CONNECT_SEL, 0x3);
13140 if (present_laptop)
13141 snd_hda_codec_write(codec, 0x23, 0,
13142 AC_VERB_SET_CONNECT_SEL, 0x0);
13143 if (!present_dock && !present_laptop)
13144 snd_hda_codec_write(codec, 0x23, 0,
13145 AC_VERB_SET_CONNECT_SEL, 0x1);
13148 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13149 unsigned int res)
13151 switch (res >> 26) {
13152 case ALC880_HP_EVENT:
13153 alc269_quanta_fl1_speaker_automute(codec);
13154 break;
13155 case ALC880_MIC_EVENT:
13156 alc_mic_automute(codec);
13157 break;
13161 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13162 unsigned int res)
13164 if ((res >> 26) == ALC880_HP_EVENT)
13165 alc269_lifebook_speaker_automute(codec);
13166 if ((res >> 26) == ALC880_MIC_EVENT)
13167 alc269_lifebook_mic_autoswitch(codec);
13170 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13172 struct alc_spec *spec = codec->spec;
13173 spec->ext_mic.pin = 0x18;
13174 spec->ext_mic.mux_idx = 0;
13175 spec->int_mic.pin = 0x19;
13176 spec->int_mic.mux_idx = 1;
13177 spec->auto_mic = 1;
13180 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13182 alc269_quanta_fl1_speaker_automute(codec);
13183 alc_mic_automute(codec);
13186 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13188 alc269_lifebook_speaker_automute(codec);
13189 alc269_lifebook_mic_autoswitch(codec);
13192 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13193 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13194 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13195 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13196 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13197 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13198 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13199 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13203 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13205 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13206 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13207 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13208 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13209 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13213 /* toggle speaker-output according to the hp-jack state */
13214 static void alc269_speaker_automute(struct hda_codec *codec)
13216 unsigned int present;
13217 unsigned char bits;
13219 present = snd_hda_codec_read(codec, 0x15, 0,
13220 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13221 bits = present ? AMP_IN_MUTE(0) : 0;
13222 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13223 AMP_IN_MUTE(0), bits);
13224 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13225 AMP_IN_MUTE(0), bits);
13228 /* unsolicited event for HP jack sensing */
13229 static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13230 unsigned int res)
13232 switch (res >> 26) {
13233 case ALC880_HP_EVENT:
13234 alc269_speaker_automute(codec);
13235 break;
13236 case ALC880_MIC_EVENT:
13237 alc_mic_automute(codec);
13238 break;
13242 static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13244 struct alc_spec *spec = codec->spec;
13245 spec->ext_mic.pin = 0x18;
13246 spec->ext_mic.mux_idx = 0;
13247 spec->int_mic.pin = 0x12;
13248 spec->int_mic.mux_idx = 5;
13249 spec->auto_mic = 1;
13252 static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13254 struct alc_spec *spec = codec->spec;
13255 spec->ext_mic.pin = 0x18;
13256 spec->ext_mic.mux_idx = 0;
13257 spec->int_mic.pin = 0x19;
13258 spec->int_mic.mux_idx = 1;
13259 spec->auto_mic = 1;
13262 static void alc269_eeepc_inithook(struct hda_codec *codec)
13264 alc269_speaker_automute(codec);
13265 alc_mic_automute(codec);
13269 * generic initialization of ADC, input mixers and output mixers
13271 static struct hda_verb alc269_init_verbs[] = {
13273 * Unmute ADC0 and set the default input to mic-in
13275 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13277 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13278 * analog-loopback mixer widget
13279 * Note: PASD motherboards uses the Line In 2 as the input for
13280 * front panel mic (mic 2)
13282 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13286 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13287 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13290 * Set up output mixers (0x0c - 0x0e)
13292 /* set vol=0 to output mixers */
13293 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13294 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13296 /* set up input amps for analog loopback */
13297 /* Amp Indices: DAC = 0, mixer = 1 */
13298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13299 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13300 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13301 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13302 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13303 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13305 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13307 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13308 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13309 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13310 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13311 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13313 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13315 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13316 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13317 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13318 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13319 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13321 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13322 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13324 /* FIXME: use matrix-type input source selection */
13325 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13326 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13330 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13332 /* set EAPD */
13333 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13334 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13338 #define alc269_auto_create_multi_out_ctls \
13339 alc268_auto_create_multi_out_ctls
13340 #define alc269_auto_create_input_ctls \
13341 alc268_auto_create_input_ctls
13343 #ifdef CONFIG_SND_HDA_POWER_SAVE
13344 #define alc269_loopbacks alc880_loopbacks
13345 #endif
13347 /* pcm configuration: identical with ALC880 */
13348 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13349 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13350 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13351 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13353 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13354 .substreams = 1,
13355 .channels_min = 2,
13356 .channels_max = 8,
13357 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13358 /* NID is set in alc_build_pcms */
13359 .ops = {
13360 .open = alc880_playback_pcm_open,
13361 .prepare = alc880_playback_pcm_prepare,
13362 .cleanup = alc880_playback_pcm_cleanup
13366 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13367 .substreams = 1,
13368 .channels_min = 2,
13369 .channels_max = 2,
13370 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13371 /* NID is set in alc_build_pcms */
13375 * BIOS auto configuration
13377 static int alc269_parse_auto_config(struct hda_codec *codec)
13379 struct alc_spec *spec = codec->spec;
13380 int err;
13381 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13383 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13384 alc269_ignore);
13385 if (err < 0)
13386 return err;
13388 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13389 if (err < 0)
13390 return err;
13391 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13392 if (err < 0)
13393 return err;
13395 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13397 if (spec->autocfg.dig_outs)
13398 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13400 if (spec->kctls.list)
13401 add_mixer(spec, spec->kctls.list);
13403 add_verb(spec, alc269_init_verbs);
13404 spec->num_mux_defs = 1;
13405 spec->input_mux = &spec->private_imux[0];
13406 /* set default input source */
13407 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13408 0, AC_VERB_SET_CONNECT_SEL,
13409 spec->input_mux->items[0].index);
13411 err = alc_auto_add_mic_boost(codec);
13412 if (err < 0)
13413 return err;
13415 if (!spec->cap_mixer && !spec->no_analog)
13416 set_capture_mixer(codec);
13418 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13420 return 1;
13423 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
13424 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
13425 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13428 /* init callback for auto-configuration model -- overriding the default init */
13429 static void alc269_auto_init(struct hda_codec *codec)
13431 struct alc_spec *spec = codec->spec;
13432 alc269_auto_init_multi_out(codec);
13433 alc269_auto_init_hp_out(codec);
13434 alc269_auto_init_analog_input(codec);
13435 if (spec->unsol_event)
13436 alc_inithook(codec);
13440 * configuration and preset
13442 static const char *alc269_models[ALC269_MODEL_LAST] = {
13443 [ALC269_BASIC] = "basic",
13444 [ALC269_QUANTA_FL1] = "quanta",
13445 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13446 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13447 [ALC269_FUJITSU] = "fujitsu",
13448 [ALC269_LIFEBOOK] = "lifebook",
13449 [ALC269_AUTO] = "auto",
13452 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13453 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13454 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13455 ALC269_ASUS_EEEPC_P703),
13456 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13457 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13458 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13459 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13460 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13461 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13462 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13463 ALC269_ASUS_EEEPC_P901),
13464 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13465 ALC269_ASUS_EEEPC_P901),
13466 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13467 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13468 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13472 static struct alc_config_preset alc269_presets[] = {
13473 [ALC269_BASIC] = {
13474 .mixers = { alc269_base_mixer },
13475 .init_verbs = { alc269_init_verbs },
13476 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13477 .dac_nids = alc269_dac_nids,
13478 .hp_nid = 0x03,
13479 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13480 .channel_mode = alc269_modes,
13481 .input_mux = &alc269_capture_source,
13483 [ALC269_QUANTA_FL1] = {
13484 .mixers = { alc269_quanta_fl1_mixer },
13485 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13486 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13487 .dac_nids = alc269_dac_nids,
13488 .hp_nid = 0x03,
13489 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13490 .channel_mode = alc269_modes,
13491 .input_mux = &alc269_capture_source,
13492 .unsol_event = alc269_quanta_fl1_unsol_event,
13493 .setup = alc269_quanta_fl1_setup,
13494 .init_hook = alc269_quanta_fl1_init_hook,
13496 [ALC269_ASUS_EEEPC_P703] = {
13497 .mixers = { alc269_eeepc_mixer },
13498 .cap_mixer = alc269_epc_capture_mixer,
13499 .init_verbs = { alc269_init_verbs,
13500 alc269_eeepc_amic_init_verbs },
13501 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13502 .dac_nids = alc269_dac_nids,
13503 .hp_nid = 0x03,
13504 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13505 .channel_mode = alc269_modes,
13506 .unsol_event = alc269_eeepc_unsol_event,
13507 .setup = alc269_eeepc_amic_setup,
13508 .init_hook = alc269_eeepc_inithook,
13510 [ALC269_ASUS_EEEPC_P901] = {
13511 .mixers = { alc269_eeepc_mixer },
13512 .cap_mixer = alc269_epc_capture_mixer,
13513 .init_verbs = { alc269_init_verbs,
13514 alc269_eeepc_dmic_init_verbs },
13515 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13516 .dac_nids = alc269_dac_nids,
13517 .hp_nid = 0x03,
13518 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13519 .channel_mode = alc269_modes,
13520 .unsol_event = alc269_eeepc_unsol_event,
13521 .setup = alc269_eeepc_dmic_setup,
13522 .init_hook = alc269_eeepc_inithook,
13524 [ALC269_FUJITSU] = {
13525 .mixers = { alc269_fujitsu_mixer },
13526 .cap_mixer = alc269_epc_capture_mixer,
13527 .init_verbs = { alc269_init_verbs,
13528 alc269_eeepc_dmic_init_verbs },
13529 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13530 .dac_nids = alc269_dac_nids,
13531 .hp_nid = 0x03,
13532 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13533 .channel_mode = alc269_modes,
13534 .unsol_event = alc269_eeepc_unsol_event,
13535 .setup = alc269_eeepc_dmic_setup,
13536 .init_hook = alc269_eeepc_inithook,
13538 [ALC269_LIFEBOOK] = {
13539 .mixers = { alc269_lifebook_mixer },
13540 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13541 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13542 .dac_nids = alc269_dac_nids,
13543 .hp_nid = 0x03,
13544 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13545 .channel_mode = alc269_modes,
13546 .input_mux = &alc269_capture_source,
13547 .unsol_event = alc269_lifebook_unsol_event,
13548 .init_hook = alc269_lifebook_init_hook,
13552 static int patch_alc269(struct hda_codec *codec)
13554 struct alc_spec *spec;
13555 int board_config;
13556 int err;
13558 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13559 if (spec == NULL)
13560 return -ENOMEM;
13562 codec->spec = spec;
13564 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13566 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13567 alc269_models,
13568 alc269_cfg_tbl);
13570 if (board_config < 0) {
13571 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13572 codec->chip_name);
13573 board_config = ALC269_AUTO;
13576 if (board_config == ALC269_AUTO) {
13577 /* automatic parse from the BIOS config */
13578 err = alc269_parse_auto_config(codec);
13579 if (err < 0) {
13580 alc_free(codec);
13581 return err;
13582 } else if (!err) {
13583 printk(KERN_INFO
13584 "hda_codec: Cannot set up configuration "
13585 "from BIOS. Using base mode...\n");
13586 board_config = ALC269_BASIC;
13590 err = snd_hda_attach_beep_device(codec, 0x1);
13591 if (err < 0) {
13592 alc_free(codec);
13593 return err;
13596 if (board_config != ALC269_AUTO)
13597 setup_preset(codec, &alc269_presets[board_config]);
13599 if (codec->subsystem_id == 0x17aa3bf8) {
13600 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13601 * fix the sample rate of analog I/O to 44.1kHz
13603 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13604 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13605 } else {
13606 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13607 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13609 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13610 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13612 spec->adc_nids = alc269_adc_nids;
13613 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13614 spec->capsrc_nids = alc269_capsrc_nids;
13615 if (!spec->cap_mixer)
13616 set_capture_mixer(codec);
13617 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13619 spec->vmaster_nid = 0x02;
13621 codec->patch_ops = alc_patch_ops;
13622 if (board_config == ALC269_AUTO)
13623 spec->init_hook = alc269_auto_init;
13624 #ifdef CONFIG_SND_HDA_POWER_SAVE
13625 if (!spec->loopback.amplist)
13626 spec->loopback.amplist = alc269_loopbacks;
13627 #endif
13628 codec->proc_widget_hook = print_realtek_coef;
13630 return 0;
13634 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13638 * set the path ways for 2 channel output
13639 * need to set the codec line out and mic 1 pin widgets to inputs
13641 static struct hda_verb alc861_threestack_ch2_init[] = {
13642 /* set pin widget 1Ah (line in) for input */
13643 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13644 /* set pin widget 18h (mic1/2) for input, for mic also enable
13645 * the vref
13647 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13649 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13650 #if 0
13651 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13652 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13653 #endif
13654 { } /* end */
13657 * 6ch mode
13658 * need to set the codec line out and mic 1 pin widgets to outputs
13660 static struct hda_verb alc861_threestack_ch6_init[] = {
13661 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13662 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13663 /* set pin widget 18h (mic1) for output (CLFE)*/
13664 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13666 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13667 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13669 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13670 #if 0
13671 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13672 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13673 #endif
13674 { } /* end */
13677 static struct hda_channel_mode alc861_threestack_modes[2] = {
13678 { 2, alc861_threestack_ch2_init },
13679 { 6, alc861_threestack_ch6_init },
13681 /* Set mic1 as input and unmute the mixer */
13682 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13683 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13684 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13685 { } /* end */
13687 /* Set mic1 as output and mute mixer */
13688 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13689 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13690 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13691 { } /* end */
13694 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13695 { 2, alc861_uniwill_m31_ch2_init },
13696 { 4, alc861_uniwill_m31_ch4_init },
13699 /* Set mic1 and line-in as input and unmute the mixer */
13700 static struct hda_verb alc861_asus_ch2_init[] = {
13701 /* set pin widget 1Ah (line in) for input */
13702 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13703 /* set pin widget 18h (mic1/2) for input, for mic also enable
13704 * the vref
13706 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13708 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13709 #if 0
13710 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13711 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13712 #endif
13713 { } /* end */
13715 /* Set mic1 nad line-in as output and mute mixer */
13716 static struct hda_verb alc861_asus_ch6_init[] = {
13717 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13718 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13719 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13720 /* set pin widget 18h (mic1) for output (CLFE)*/
13721 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13722 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13723 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13724 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13726 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13727 #if 0
13728 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13729 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13730 #endif
13731 { } /* end */
13734 static struct hda_channel_mode alc861_asus_modes[2] = {
13735 { 2, alc861_asus_ch2_init },
13736 { 6, alc861_asus_ch6_init },
13739 /* patch-ALC861 */
13741 static struct snd_kcontrol_new alc861_base_mixer[] = {
13742 /* output mixer control */
13743 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13744 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13745 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13746 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13747 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13749 /*Input mixer control */
13750 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13751 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13752 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13753 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13754 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13755 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13757 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13758 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13759 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13761 { } /* end */
13764 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13765 /* output mixer control */
13766 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13767 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13768 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13769 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13770 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13772 /* Input mixer control */
13773 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13774 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13775 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13776 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13777 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13778 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13780 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13786 .name = "Channel Mode",
13787 .info = alc_ch_mode_info,
13788 .get = alc_ch_mode_get,
13789 .put = alc_ch_mode_put,
13790 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13792 { } /* end */
13795 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13796 /* output mixer control */
13797 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13799 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13801 { } /* end */
13804 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13805 /* output mixer control */
13806 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13807 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13808 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13809 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13810 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13812 /* Input mixer control */
13813 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13814 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13815 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13816 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13817 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13818 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13820 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13821 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13822 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13826 .name = "Channel Mode",
13827 .info = alc_ch_mode_info,
13828 .get = alc_ch_mode_get,
13829 .put = alc_ch_mode_put,
13830 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13832 { } /* end */
13835 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13836 /* output mixer control */
13837 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13838 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13839 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13840 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13841 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13843 /* Input mixer control */
13844 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13845 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13846 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13847 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13848 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13849 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13851 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13852 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13857 .name = "Channel Mode",
13858 .info = alc_ch_mode_info,
13859 .get = alc_ch_mode_get,
13860 .put = alc_ch_mode_put,
13861 .private_value = ARRAY_SIZE(alc861_asus_modes),
13866 /* additional mixer */
13867 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13868 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13869 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13874 * generic initialization of ADC, input mixers and output mixers
13876 static struct hda_verb alc861_base_init_verbs[] = {
13878 * Unmute ADC0 and set the default input to mic-in
13880 /* port-A for surround (rear panel) */
13881 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13882 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13883 /* port-B for mic-in (rear panel) with vref */
13884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13885 /* port-C for line-in (rear panel) */
13886 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13887 /* port-D for Front */
13888 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13889 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13890 /* port-E for HP out (front panel) */
13891 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13892 /* route front PCM to HP */
13893 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13894 /* port-F for mic-in (front panel) with vref */
13895 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13896 /* port-G for CLFE (rear panel) */
13897 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13898 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13899 /* port-H for side (rear panel) */
13900 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13901 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13902 /* CD-in */
13903 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13904 /* route front mic to ADC1*/
13905 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13906 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13908 /* Unmute DAC0~3 & spdif out*/
13909 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13910 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13911 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13912 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13915 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13916 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13917 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13918 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13919 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13921 /* Unmute Stereo Mixer 15 */
13922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13923 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13925 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13927 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13928 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13929 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13930 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13931 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13932 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13933 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13934 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13935 /* hp used DAC 3 (Front) */
13936 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13937 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13942 static struct hda_verb alc861_threestack_init_verbs[] = {
13944 * Unmute ADC0 and set the default input to mic-in
13946 /* port-A for surround (rear panel) */
13947 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13948 /* port-B for mic-in (rear panel) with vref */
13949 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13950 /* port-C for line-in (rear panel) */
13951 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13952 /* port-D for Front */
13953 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13954 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13955 /* port-E for HP out (front panel) */
13956 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13957 /* route front PCM to HP */
13958 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13959 /* port-F for mic-in (front panel) with vref */
13960 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13961 /* port-G for CLFE (rear panel) */
13962 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13963 /* port-H for side (rear panel) */
13964 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13965 /* CD-in */
13966 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13967 /* route front mic to ADC1*/
13968 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13969 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13970 /* Unmute DAC0~3 & spdif out*/
13971 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13972 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13973 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13974 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13977 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13978 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13979 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13980 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13981 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13983 /* Unmute Stereo Mixer 15 */
13984 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13986 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13989 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13990 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13991 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13992 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13993 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13994 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13995 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13996 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13997 /* hp used DAC 3 (Front) */
13998 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13999 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14003 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14005 * Unmute ADC0 and set the default input to mic-in
14007 /* port-A for surround (rear panel) */
14008 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14009 /* port-B for mic-in (rear panel) with vref */
14010 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14011 /* port-C for line-in (rear panel) */
14012 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14013 /* port-D for Front */
14014 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14015 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14016 /* port-E for HP out (front panel) */
14017 /* this has to be set to VREF80 */
14018 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14019 /* route front PCM to HP */
14020 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14021 /* port-F for mic-in (front panel) with vref */
14022 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14023 /* port-G for CLFE (rear panel) */
14024 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14025 /* port-H for side (rear panel) */
14026 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14027 /* CD-in */
14028 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14029 /* route front mic to ADC1*/
14030 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14032 /* Unmute DAC0~3 & spdif out*/
14033 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14034 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14035 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14036 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14039 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14040 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14041 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14042 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14043 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14045 /* Unmute Stereo Mixer 15 */
14046 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14047 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14048 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14049 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14051 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14052 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14053 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14054 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14055 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14056 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14057 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14058 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14059 /* hp used DAC 3 (Front) */
14060 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14061 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14065 static struct hda_verb alc861_asus_init_verbs[] = {
14067 * Unmute ADC0 and set the default input to mic-in
14069 /* port-A for surround (rear panel)
14070 * according to codec#0 this is the HP jack
14072 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14073 /* route front PCM to HP */
14074 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14075 /* port-B for mic-in (rear panel) with vref */
14076 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14077 /* port-C for line-in (rear panel) */
14078 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14079 /* port-D for Front */
14080 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14081 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14082 /* port-E for HP out (front panel) */
14083 /* this has to be set to VREF80 */
14084 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14085 /* route front PCM to HP */
14086 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14087 /* port-F for mic-in (front panel) with vref */
14088 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14089 /* port-G for CLFE (rear panel) */
14090 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14091 /* port-H for side (rear panel) */
14092 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14093 /* CD-in */
14094 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14095 /* route front mic to ADC1*/
14096 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14097 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14098 /* Unmute DAC0~3 & spdif out*/
14099 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14101 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14102 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14103 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14104 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14105 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14106 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14107 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14108 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14110 /* Unmute Stereo Mixer 15 */
14111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14114 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14117 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14118 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14119 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14120 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14121 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14122 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14124 /* hp used DAC 3 (Front) */
14125 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14126 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14130 /* additional init verbs for ASUS laptops */
14131 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14132 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14133 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14138 * generic initialization of ADC, input mixers and output mixers
14140 static struct hda_verb alc861_auto_init_verbs[] = {
14142 * Unmute ADC0 and set the default input to mic-in
14144 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14145 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14147 /* Unmute DAC0~3 & spdif out*/
14148 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14149 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14150 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14151 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14152 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14154 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14155 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14156 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14157 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14158 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14160 /* Unmute Stereo Mixer 15 */
14161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14167 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14168 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14172 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14175 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14178 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14180 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14181 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14184 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14189 static struct hda_verb alc861_toshiba_init_verbs[] = {
14190 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14195 /* toggle speaker-output according to the hp-jack state */
14196 static void alc861_toshiba_automute(struct hda_codec *codec)
14198 unsigned int present;
14200 present = snd_hda_codec_read(codec, 0x0f, 0,
14201 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14202 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14203 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14204 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14205 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14208 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14209 unsigned int res)
14211 if ((res >> 26) == ALC880_HP_EVENT)
14212 alc861_toshiba_automute(codec);
14215 /* pcm configuration: identical with ALC880 */
14216 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
14217 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
14218 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
14219 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
14222 #define ALC861_DIGOUT_NID 0x07
14224 static struct hda_channel_mode alc861_8ch_modes[1] = {
14225 { 8, NULL }
14228 static hda_nid_t alc861_dac_nids[4] = {
14229 /* front, surround, clfe, side */
14230 0x03, 0x06, 0x05, 0x04
14233 static hda_nid_t alc660_dac_nids[3] = {
14234 /* front, clfe, surround */
14235 0x03, 0x05, 0x06
14238 static hda_nid_t alc861_adc_nids[1] = {
14239 /* ADC0-2 */
14240 0x08,
14243 static struct hda_input_mux alc861_capture_source = {
14244 .num_items = 5,
14245 .items = {
14246 { "Mic", 0x0 },
14247 { "Front Mic", 0x3 },
14248 { "Line", 0x1 },
14249 { "CD", 0x4 },
14250 { "Mixer", 0x5 },
14254 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14256 struct alc_spec *spec = codec->spec;
14257 hda_nid_t mix, srcs[5];
14258 int i, j, num;
14260 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14261 return 0;
14262 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14263 if (num < 0)
14264 return 0;
14265 for (i = 0; i < num; i++) {
14266 unsigned int type;
14267 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14268 if (type != AC_WID_AUD_OUT)
14269 continue;
14270 for (j = 0; j < spec->multiout.num_dacs; j++)
14271 if (spec->multiout.dac_nids[j] == srcs[i])
14272 break;
14273 if (j >= spec->multiout.num_dacs)
14274 return srcs[i];
14276 return 0;
14279 /* fill in the dac_nids table from the parsed pin configuration */
14280 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14281 const struct auto_pin_cfg *cfg)
14283 struct alc_spec *spec = codec->spec;
14284 int i;
14285 hda_nid_t nid, dac;
14287 spec->multiout.dac_nids = spec->private_dac_nids;
14288 for (i = 0; i < cfg->line_outs; i++) {
14289 nid = cfg->line_out_pins[i];
14290 dac = alc861_look_for_dac(codec, nid);
14291 if (!dac)
14292 continue;
14293 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14295 return 0;
14298 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14299 hda_nid_t nid, unsigned int chs)
14301 char name[32];
14302 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14303 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14304 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14307 /* add playback controls from the parsed DAC table */
14308 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14309 const struct auto_pin_cfg *cfg)
14311 struct alc_spec *spec = codec->spec;
14312 static const char *chname[4] = {
14313 "Front", "Surround", NULL /*CLFE*/, "Side"
14315 hda_nid_t nid;
14316 int i, err;
14318 if (cfg->line_outs == 1) {
14319 const char *pfx = NULL;
14320 if (!cfg->hp_outs)
14321 pfx = "Master";
14322 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14323 pfx = "Speaker";
14324 if (pfx) {
14325 nid = spec->multiout.dac_nids[0];
14326 return alc861_create_out_sw(codec, pfx, nid, 3);
14330 for (i = 0; i < cfg->line_outs; i++) {
14331 nid = spec->multiout.dac_nids[i];
14332 if (!nid)
14333 continue;
14334 if (i == 2) {
14335 /* Center/LFE */
14336 err = alc861_create_out_sw(codec, "Center", nid, 1);
14337 if (err < 0)
14338 return err;
14339 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14340 if (err < 0)
14341 return err;
14342 } else {
14343 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14344 if (err < 0)
14345 return err;
14348 return 0;
14351 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14353 struct alc_spec *spec = codec->spec;
14354 int err;
14355 hda_nid_t nid;
14357 if (!pin)
14358 return 0;
14360 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14361 nid = alc861_look_for_dac(codec, pin);
14362 if (nid) {
14363 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14364 if (err < 0)
14365 return err;
14366 spec->multiout.hp_nid = nid;
14369 return 0;
14372 /* create playback/capture controls for input pins */
14373 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14374 const struct auto_pin_cfg *cfg)
14376 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14379 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14380 hda_nid_t nid,
14381 int pin_type, hda_nid_t dac)
14383 hda_nid_t mix, srcs[5];
14384 int i, num;
14386 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14387 pin_type);
14388 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14389 AMP_OUT_UNMUTE);
14390 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14391 return;
14392 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14393 if (num < 0)
14394 return;
14395 for (i = 0; i < num; i++) {
14396 unsigned int mute;
14397 if (srcs[i] == dac || srcs[i] == 0x15)
14398 mute = AMP_IN_UNMUTE(i);
14399 else
14400 mute = AMP_IN_MUTE(i);
14401 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14402 mute);
14406 static void alc861_auto_init_multi_out(struct hda_codec *codec)
14408 struct alc_spec *spec = codec->spec;
14409 int i;
14411 for (i = 0; i < spec->autocfg.line_outs; i++) {
14412 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14413 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14414 if (nid)
14415 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14416 spec->multiout.dac_nids[i]);
14420 static void alc861_auto_init_hp_out(struct hda_codec *codec)
14422 struct alc_spec *spec = codec->spec;
14424 if (spec->autocfg.hp_outs)
14425 alc861_auto_set_output_and_unmute(codec,
14426 spec->autocfg.hp_pins[0],
14427 PIN_HP,
14428 spec->multiout.hp_nid);
14429 if (spec->autocfg.speaker_outs)
14430 alc861_auto_set_output_and_unmute(codec,
14431 spec->autocfg.speaker_pins[0],
14432 PIN_OUT,
14433 spec->multiout.dac_nids[0]);
14436 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14438 struct alc_spec *spec = codec->spec;
14439 int i;
14441 for (i = 0; i < AUTO_PIN_LAST; i++) {
14442 hda_nid_t nid = spec->autocfg.input_pins[i];
14443 if (nid >= 0x0c && nid <= 0x11)
14444 alc_set_input_pin(codec, nid, i);
14448 /* parse the BIOS configuration and set up the alc_spec */
14449 /* return 1 if successful, 0 if the proper config is not found,
14450 * or a negative error code
14452 static int alc861_parse_auto_config(struct hda_codec *codec)
14454 struct alc_spec *spec = codec->spec;
14455 int err;
14456 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14458 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14459 alc861_ignore);
14460 if (err < 0)
14461 return err;
14462 if (!spec->autocfg.line_outs)
14463 return 0; /* can't find valid BIOS pin config */
14465 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14466 if (err < 0)
14467 return err;
14468 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14469 if (err < 0)
14470 return err;
14471 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14472 if (err < 0)
14473 return err;
14474 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14475 if (err < 0)
14476 return err;
14478 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14480 if (spec->autocfg.dig_outs)
14481 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14483 if (spec->kctls.list)
14484 add_mixer(spec, spec->kctls.list);
14486 add_verb(spec, alc861_auto_init_verbs);
14488 spec->num_mux_defs = 1;
14489 spec->input_mux = &spec->private_imux[0];
14491 spec->adc_nids = alc861_adc_nids;
14492 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14493 set_capture_mixer(codec);
14495 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14497 return 1;
14500 /* additional initialization for auto-configuration model */
14501 static void alc861_auto_init(struct hda_codec *codec)
14503 struct alc_spec *spec = codec->spec;
14504 alc861_auto_init_multi_out(codec);
14505 alc861_auto_init_hp_out(codec);
14506 alc861_auto_init_analog_input(codec);
14507 if (spec->unsol_event)
14508 alc_inithook(codec);
14511 #ifdef CONFIG_SND_HDA_POWER_SAVE
14512 static struct hda_amp_list alc861_loopbacks[] = {
14513 { 0x15, HDA_INPUT, 0 },
14514 { 0x15, HDA_INPUT, 1 },
14515 { 0x15, HDA_INPUT, 2 },
14516 { 0x15, HDA_INPUT, 3 },
14517 { } /* end */
14519 #endif
14523 * configuration and preset
14525 static const char *alc861_models[ALC861_MODEL_LAST] = {
14526 [ALC861_3ST] = "3stack",
14527 [ALC660_3ST] = "3stack-660",
14528 [ALC861_3ST_DIG] = "3stack-dig",
14529 [ALC861_6ST_DIG] = "6stack-dig",
14530 [ALC861_UNIWILL_M31] = "uniwill-m31",
14531 [ALC861_TOSHIBA] = "toshiba",
14532 [ALC861_ASUS] = "asus",
14533 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14534 [ALC861_AUTO] = "auto",
14537 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14538 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14539 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14540 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14541 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14542 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14543 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14544 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14545 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14546 * Any other models that need this preset?
14548 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14549 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14550 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14551 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14552 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14553 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14554 /* FIXME: the below seems conflict */
14555 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14556 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14557 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14561 static struct alc_config_preset alc861_presets[] = {
14562 [ALC861_3ST] = {
14563 .mixers = { alc861_3ST_mixer },
14564 .init_verbs = { alc861_threestack_init_verbs },
14565 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14566 .dac_nids = alc861_dac_nids,
14567 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14568 .channel_mode = alc861_threestack_modes,
14569 .need_dac_fix = 1,
14570 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14571 .adc_nids = alc861_adc_nids,
14572 .input_mux = &alc861_capture_source,
14574 [ALC861_3ST_DIG] = {
14575 .mixers = { alc861_base_mixer },
14576 .init_verbs = { alc861_threestack_init_verbs },
14577 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14578 .dac_nids = alc861_dac_nids,
14579 .dig_out_nid = ALC861_DIGOUT_NID,
14580 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14581 .channel_mode = alc861_threestack_modes,
14582 .need_dac_fix = 1,
14583 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14584 .adc_nids = alc861_adc_nids,
14585 .input_mux = &alc861_capture_source,
14587 [ALC861_6ST_DIG] = {
14588 .mixers = { alc861_base_mixer },
14589 .init_verbs = { alc861_base_init_verbs },
14590 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14591 .dac_nids = alc861_dac_nids,
14592 .dig_out_nid = ALC861_DIGOUT_NID,
14593 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14594 .channel_mode = alc861_8ch_modes,
14595 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14596 .adc_nids = alc861_adc_nids,
14597 .input_mux = &alc861_capture_source,
14599 [ALC660_3ST] = {
14600 .mixers = { alc861_3ST_mixer },
14601 .init_verbs = { alc861_threestack_init_verbs },
14602 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14603 .dac_nids = alc660_dac_nids,
14604 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14605 .channel_mode = alc861_threestack_modes,
14606 .need_dac_fix = 1,
14607 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14608 .adc_nids = alc861_adc_nids,
14609 .input_mux = &alc861_capture_source,
14611 [ALC861_UNIWILL_M31] = {
14612 .mixers = { alc861_uniwill_m31_mixer },
14613 .init_verbs = { alc861_uniwill_m31_init_verbs },
14614 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14615 .dac_nids = alc861_dac_nids,
14616 .dig_out_nid = ALC861_DIGOUT_NID,
14617 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14618 .channel_mode = alc861_uniwill_m31_modes,
14619 .need_dac_fix = 1,
14620 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14621 .adc_nids = alc861_adc_nids,
14622 .input_mux = &alc861_capture_source,
14624 [ALC861_TOSHIBA] = {
14625 .mixers = { alc861_toshiba_mixer },
14626 .init_verbs = { alc861_base_init_verbs,
14627 alc861_toshiba_init_verbs },
14628 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14629 .dac_nids = alc861_dac_nids,
14630 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14631 .channel_mode = alc883_3ST_2ch_modes,
14632 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14633 .adc_nids = alc861_adc_nids,
14634 .input_mux = &alc861_capture_source,
14635 .unsol_event = alc861_toshiba_unsol_event,
14636 .init_hook = alc861_toshiba_automute,
14638 [ALC861_ASUS] = {
14639 .mixers = { alc861_asus_mixer },
14640 .init_verbs = { alc861_asus_init_verbs },
14641 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14642 .dac_nids = alc861_dac_nids,
14643 .dig_out_nid = ALC861_DIGOUT_NID,
14644 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14645 .channel_mode = alc861_asus_modes,
14646 .need_dac_fix = 1,
14647 .hp_nid = 0x06,
14648 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14649 .adc_nids = alc861_adc_nids,
14650 .input_mux = &alc861_capture_source,
14652 [ALC861_ASUS_LAPTOP] = {
14653 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14654 .init_verbs = { alc861_asus_init_verbs,
14655 alc861_asus_laptop_init_verbs },
14656 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14657 .dac_nids = alc861_dac_nids,
14658 .dig_out_nid = ALC861_DIGOUT_NID,
14659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14660 .channel_mode = alc883_3ST_2ch_modes,
14661 .need_dac_fix = 1,
14662 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14663 .adc_nids = alc861_adc_nids,
14664 .input_mux = &alc861_capture_source,
14669 static int patch_alc861(struct hda_codec *codec)
14671 struct alc_spec *spec;
14672 int board_config;
14673 int err;
14675 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14676 if (spec == NULL)
14677 return -ENOMEM;
14679 codec->spec = spec;
14681 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14682 alc861_models,
14683 alc861_cfg_tbl);
14685 if (board_config < 0) {
14686 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14687 codec->chip_name);
14688 board_config = ALC861_AUTO;
14691 if (board_config == ALC861_AUTO) {
14692 /* automatic parse from the BIOS config */
14693 err = alc861_parse_auto_config(codec);
14694 if (err < 0) {
14695 alc_free(codec);
14696 return err;
14697 } else if (!err) {
14698 printk(KERN_INFO
14699 "hda_codec: Cannot set up configuration "
14700 "from BIOS. Using base mode...\n");
14701 board_config = ALC861_3ST_DIG;
14705 err = snd_hda_attach_beep_device(codec, 0x23);
14706 if (err < 0) {
14707 alc_free(codec);
14708 return err;
14711 if (board_config != ALC861_AUTO)
14712 setup_preset(codec, &alc861_presets[board_config]);
14714 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14715 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14717 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14718 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14720 if (!spec->cap_mixer)
14721 set_capture_mixer(codec);
14722 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14724 spec->vmaster_nid = 0x03;
14726 codec->patch_ops = alc_patch_ops;
14727 if (board_config == ALC861_AUTO)
14728 spec->init_hook = alc861_auto_init;
14729 #ifdef CONFIG_SND_HDA_POWER_SAVE
14730 if (!spec->loopback.amplist)
14731 spec->loopback.amplist = alc861_loopbacks;
14732 #endif
14733 codec->proc_widget_hook = print_realtek_coef;
14735 return 0;
14739 * ALC861-VD support
14741 * Based on ALC882
14743 * In addition, an independent DAC
14745 #define ALC861VD_DIGOUT_NID 0x06
14747 static hda_nid_t alc861vd_dac_nids[4] = {
14748 /* front, surr, clfe, side surr */
14749 0x02, 0x03, 0x04, 0x05
14752 /* dac_nids for ALC660vd are in a different order - according to
14753 * Realtek's driver.
14754 * This should probably result in a different mixer for 6stack models
14755 * of ALC660vd codecs, but for now there is only 3stack mixer
14756 * - and it is the same as in 861vd.
14757 * adc_nids in ALC660vd are (is) the same as in 861vd
14759 static hda_nid_t alc660vd_dac_nids[3] = {
14760 /* front, rear, clfe, rear_surr */
14761 0x02, 0x04, 0x03
14764 static hda_nid_t alc861vd_adc_nids[1] = {
14765 /* ADC0 */
14766 0x09,
14769 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14771 /* input MUX */
14772 /* FIXME: should be a matrix-type input source selection */
14773 static struct hda_input_mux alc861vd_capture_source = {
14774 .num_items = 4,
14775 .items = {
14776 { "Mic", 0x0 },
14777 { "Front Mic", 0x1 },
14778 { "Line", 0x2 },
14779 { "CD", 0x4 },
14783 static struct hda_input_mux alc861vd_dallas_capture_source = {
14784 .num_items = 2,
14785 .items = {
14786 { "Ext Mic", 0x0 },
14787 { "Int Mic", 0x1 },
14791 static struct hda_input_mux alc861vd_hp_capture_source = {
14792 .num_items = 2,
14793 .items = {
14794 { "Front Mic", 0x0 },
14795 { "ATAPI Mic", 0x1 },
14800 * 2ch mode
14802 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14803 { 2, NULL }
14807 * 6ch mode
14809 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14810 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14811 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14812 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14813 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14814 { } /* end */
14818 * 8ch mode
14820 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14821 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14822 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14823 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14824 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14825 { } /* end */
14828 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14829 { 6, alc861vd_6stack_ch6_init },
14830 { 8, alc861vd_6stack_ch8_init },
14833 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14835 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14836 .name = "Channel Mode",
14837 .info = alc_ch_mode_info,
14838 .get = alc_ch_mode_get,
14839 .put = alc_ch_mode_put,
14841 { } /* end */
14844 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14845 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14847 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14848 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14849 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14851 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14852 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14854 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14855 HDA_OUTPUT),
14856 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14857 HDA_OUTPUT),
14858 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14859 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14861 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14862 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14864 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14866 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14867 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14868 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14870 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14871 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14872 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14874 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14875 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14877 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14878 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14880 { } /* end */
14883 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14884 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14885 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14889 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14893 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14894 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14895 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14897 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14898 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14903 { } /* end */
14906 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14907 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14908 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14909 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14913 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14914 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14915 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14917 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14918 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14919 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14921 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14922 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14924 { } /* end */
14927 /* Pin assignment: Speaker=0x14, HP = 0x15,
14928 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14930 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14931 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14932 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14933 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14934 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14935 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14936 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14937 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14938 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14939 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14940 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14941 { } /* end */
14944 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14945 * Front Mic=0x18, ATAPI Mic = 0x19,
14947 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14948 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14949 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14950 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14951 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14952 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14954 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14955 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14957 { } /* end */
14961 * generic initialization of ADC, input mixers and output mixers
14963 static struct hda_verb alc861vd_volume_init_verbs[] = {
14965 * Unmute ADC0 and set the default input to mic-in
14967 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14968 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14970 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14971 * the analog-loopback mixer widget
14973 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14974 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14975 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14977 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14980 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14981 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14987 * Set up output mixers (0x02 - 0x05)
14989 /* set vol=0 to output mixers */
14990 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14991 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14992 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14993 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14995 /* set up input amps for analog loopback */
14996 /* Amp Indices: DAC = 0, mixer = 1 */
14997 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14998 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14999 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15000 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15001 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15002 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15003 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15004 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15010 * 3-stack pin configuration:
15011 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15013 static struct hda_verb alc861vd_3stack_init_verbs[] = {
15015 * Set pin mode and muting
15017 /* set front pin widgets 0x14 for output */
15018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15019 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15020 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15022 /* Mic (rear) pin: input vref at 80% */
15023 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15024 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15025 /* Front Mic pin: input vref at 80% */
15026 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15027 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15028 /* Line In pin: input */
15029 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15030 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15031 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15032 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15033 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15034 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15035 /* CD pin widget for input */
15036 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15042 * 6-stack pin configuration:
15044 static struct hda_verb alc861vd_6stack_init_verbs[] = {
15046 * Set pin mode and muting
15048 /* set front pin widgets 0x14 for output */
15049 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15050 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15051 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15053 /* Rear Pin: output 1 (0x0d) */
15054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15057 /* CLFE Pin: output 2 (0x0e) */
15058 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15059 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15060 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15061 /* Side Pin: output 3 (0x0f) */
15062 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15063 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15064 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15066 /* Mic (rear) pin: input vref at 80% */
15067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15069 /* Front Mic pin: input vref at 80% */
15070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15072 /* Line In pin: input */
15073 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15074 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15075 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15076 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15077 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15078 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15079 /* CD pin widget for input */
15080 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15085 static struct hda_verb alc861vd_eapd_verbs[] = {
15086 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15090 static struct hda_verb alc660vd_eapd_verbs[] = {
15091 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15092 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15096 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15097 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15098 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15100 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15101 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15105 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15107 unsigned int present;
15108 unsigned char bits;
15110 present = snd_hda_codec_read(codec, 0x18, 0,
15111 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15112 bits = present ? HDA_AMP_MUTE : 0;
15113 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15114 HDA_AMP_MUTE, bits);
15117 static void alc861vd_lenovo_setup(struct hda_codec *codec)
15119 struct alc_spec *spec = codec->spec;
15120 spec->autocfg.hp_pins[0] = 0x1b;
15121 spec->autocfg.speaker_pins[0] = 0x14;
15124 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15126 alc_automute_amp(codec);
15127 alc861vd_lenovo_mic_automute(codec);
15130 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15131 unsigned int res)
15133 switch (res >> 26) {
15134 case ALC880_MIC_EVENT:
15135 alc861vd_lenovo_mic_automute(codec);
15136 break;
15137 default:
15138 alc_automute_amp_unsol_event(codec, res);
15139 break;
15143 static struct hda_verb alc861vd_dallas_verbs[] = {
15144 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15145 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15146 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15147 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15151 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15152 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15153 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15154 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15155 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15156 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15158 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15159 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15160 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15161 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15163 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15164 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15165 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15167 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15168 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15169 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15170 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15171 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15172 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15173 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15174 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15176 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15177 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15181 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15182 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15183 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15185 { } /* end */
15188 /* toggle speaker-output according to the hp-jack state */
15189 static void alc861vd_dallas_setup(struct hda_codec *codec)
15191 struct alc_spec *spec = codec->spec;
15193 spec->autocfg.hp_pins[0] = 0x15;
15194 spec->autocfg.speaker_pins[0] = 0x14;
15197 #ifdef CONFIG_SND_HDA_POWER_SAVE
15198 #define alc861vd_loopbacks alc880_loopbacks
15199 #endif
15201 /* pcm configuration: identical with ALC880 */
15202 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15203 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15204 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15205 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15208 * configuration and preset
15210 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15211 [ALC660VD_3ST] = "3stack-660",
15212 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15213 [ALC660VD_ASUS_V1S] = "asus-v1s",
15214 [ALC861VD_3ST] = "3stack",
15215 [ALC861VD_3ST_DIG] = "3stack-digout",
15216 [ALC861VD_6ST_DIG] = "6stack-digout",
15217 [ALC861VD_LENOVO] = "lenovo",
15218 [ALC861VD_DALLAS] = "dallas",
15219 [ALC861VD_HP] = "hp",
15220 [ALC861VD_AUTO] = "auto",
15223 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15224 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15225 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15226 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15227 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
15228 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15229 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15230 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15231 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15232 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15233 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
15234 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15235 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15236 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15237 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15238 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15242 static struct alc_config_preset alc861vd_presets[] = {
15243 [ALC660VD_3ST] = {
15244 .mixers = { alc861vd_3st_mixer },
15245 .init_verbs = { alc861vd_volume_init_verbs,
15246 alc861vd_3stack_init_verbs },
15247 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15248 .dac_nids = alc660vd_dac_nids,
15249 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15250 .channel_mode = alc861vd_3stack_2ch_modes,
15251 .input_mux = &alc861vd_capture_source,
15253 [ALC660VD_3ST_DIG] = {
15254 .mixers = { alc861vd_3st_mixer },
15255 .init_verbs = { alc861vd_volume_init_verbs,
15256 alc861vd_3stack_init_verbs },
15257 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15258 .dac_nids = alc660vd_dac_nids,
15259 .dig_out_nid = ALC861VD_DIGOUT_NID,
15260 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15261 .channel_mode = alc861vd_3stack_2ch_modes,
15262 .input_mux = &alc861vd_capture_source,
15264 [ALC861VD_3ST] = {
15265 .mixers = { alc861vd_3st_mixer },
15266 .init_verbs = { alc861vd_volume_init_verbs,
15267 alc861vd_3stack_init_verbs },
15268 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15269 .dac_nids = alc861vd_dac_nids,
15270 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15271 .channel_mode = alc861vd_3stack_2ch_modes,
15272 .input_mux = &alc861vd_capture_source,
15274 [ALC861VD_3ST_DIG] = {
15275 .mixers = { alc861vd_3st_mixer },
15276 .init_verbs = { alc861vd_volume_init_verbs,
15277 alc861vd_3stack_init_verbs },
15278 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15279 .dac_nids = alc861vd_dac_nids,
15280 .dig_out_nid = ALC861VD_DIGOUT_NID,
15281 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15282 .channel_mode = alc861vd_3stack_2ch_modes,
15283 .input_mux = &alc861vd_capture_source,
15285 [ALC861VD_6ST_DIG] = {
15286 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15287 .init_verbs = { alc861vd_volume_init_verbs,
15288 alc861vd_6stack_init_verbs },
15289 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15290 .dac_nids = alc861vd_dac_nids,
15291 .dig_out_nid = ALC861VD_DIGOUT_NID,
15292 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15293 .channel_mode = alc861vd_6stack_modes,
15294 .input_mux = &alc861vd_capture_source,
15296 [ALC861VD_LENOVO] = {
15297 .mixers = { alc861vd_lenovo_mixer },
15298 .init_verbs = { alc861vd_volume_init_verbs,
15299 alc861vd_3stack_init_verbs,
15300 alc861vd_eapd_verbs,
15301 alc861vd_lenovo_unsol_verbs },
15302 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15303 .dac_nids = alc660vd_dac_nids,
15304 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15305 .channel_mode = alc861vd_3stack_2ch_modes,
15306 .input_mux = &alc861vd_capture_source,
15307 .unsol_event = alc861vd_lenovo_unsol_event,
15308 .setup = alc861vd_lenovo_setup,
15309 .init_hook = alc861vd_lenovo_init_hook,
15311 [ALC861VD_DALLAS] = {
15312 .mixers = { alc861vd_dallas_mixer },
15313 .init_verbs = { alc861vd_dallas_verbs },
15314 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15315 .dac_nids = alc861vd_dac_nids,
15316 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15317 .channel_mode = alc861vd_3stack_2ch_modes,
15318 .input_mux = &alc861vd_dallas_capture_source,
15319 .unsol_event = alc_automute_amp_unsol_event,
15320 .setup = alc861vd_dallas_setup,
15321 .init_hook = alc_automute_amp,
15323 [ALC861VD_HP] = {
15324 .mixers = { alc861vd_hp_mixer },
15325 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15326 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15327 .dac_nids = alc861vd_dac_nids,
15328 .dig_out_nid = ALC861VD_DIGOUT_NID,
15329 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15330 .channel_mode = alc861vd_3stack_2ch_modes,
15331 .input_mux = &alc861vd_hp_capture_source,
15332 .unsol_event = alc_automute_amp_unsol_event,
15333 .setup = alc861vd_dallas_setup,
15334 .init_hook = alc_automute_amp,
15336 [ALC660VD_ASUS_V1S] = {
15337 .mixers = { alc861vd_lenovo_mixer },
15338 .init_verbs = { alc861vd_volume_init_verbs,
15339 alc861vd_3stack_init_verbs,
15340 alc861vd_eapd_verbs,
15341 alc861vd_lenovo_unsol_verbs },
15342 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15343 .dac_nids = alc660vd_dac_nids,
15344 .dig_out_nid = ALC861VD_DIGOUT_NID,
15345 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15346 .channel_mode = alc861vd_3stack_2ch_modes,
15347 .input_mux = &alc861vd_capture_source,
15348 .unsol_event = alc861vd_lenovo_unsol_event,
15349 .setup = alc861vd_lenovo_setup,
15350 .init_hook = alc861vd_lenovo_init_hook,
15355 * BIOS auto configuration
15357 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15358 const struct auto_pin_cfg *cfg)
15360 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0);
15364 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15365 hda_nid_t nid, int pin_type, int dac_idx)
15367 alc_set_pin_output(codec, nid, pin_type);
15370 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15372 struct alc_spec *spec = codec->spec;
15373 int i;
15375 for (i = 0; i <= HDA_SIDE; i++) {
15376 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15377 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15378 if (nid)
15379 alc861vd_auto_set_output_and_unmute(codec, nid,
15380 pin_type, i);
15385 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15387 struct alc_spec *spec = codec->spec;
15388 hda_nid_t pin;
15390 pin = spec->autocfg.hp_pins[0];
15391 if (pin) /* connect to front and use dac 0 */
15392 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15393 pin = spec->autocfg.speaker_pins[0];
15394 if (pin)
15395 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15398 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15400 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15402 struct alc_spec *spec = codec->spec;
15403 int i;
15405 for (i = 0; i < AUTO_PIN_LAST; i++) {
15406 hda_nid_t nid = spec->autocfg.input_pins[i];
15407 if (alc_is_input_pin(codec, nid)) {
15408 alc_set_input_pin(codec, nid, i);
15409 if (nid != ALC861VD_PIN_CD_NID &&
15410 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15411 snd_hda_codec_write(codec, nid, 0,
15412 AC_VERB_SET_AMP_GAIN_MUTE,
15413 AMP_OUT_MUTE);
15418 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
15420 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15421 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15423 /* add playback controls from the parsed DAC table */
15424 /* Based on ALC880 version. But ALC861VD has separate,
15425 * different NIDs for mute/unmute switch and volume control */
15426 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15427 const struct auto_pin_cfg *cfg)
15429 char name[32];
15430 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15431 hda_nid_t nid_v, nid_s;
15432 int i, err;
15434 for (i = 0; i < cfg->line_outs; i++) {
15435 if (!spec->multiout.dac_nids[i])
15436 continue;
15437 nid_v = alc861vd_idx_to_mixer_vol(
15438 alc880_dac_to_idx(
15439 spec->multiout.dac_nids[i]));
15440 nid_s = alc861vd_idx_to_mixer_switch(
15441 alc880_dac_to_idx(
15442 spec->multiout.dac_nids[i]));
15444 if (i == 2) {
15445 /* Center/LFE */
15446 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15447 "Center Playback Volume",
15448 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15449 HDA_OUTPUT));
15450 if (err < 0)
15451 return err;
15452 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15453 "LFE Playback Volume",
15454 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15455 HDA_OUTPUT));
15456 if (err < 0)
15457 return err;
15458 err = add_control(spec, ALC_CTL_BIND_MUTE,
15459 "Center Playback Switch",
15460 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15461 HDA_INPUT));
15462 if (err < 0)
15463 return err;
15464 err = add_control(spec, ALC_CTL_BIND_MUTE,
15465 "LFE Playback Switch",
15466 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15467 HDA_INPUT));
15468 if (err < 0)
15469 return err;
15470 } else {
15471 const char *pfx;
15472 if (cfg->line_outs == 1 &&
15473 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15474 if (!cfg->hp_pins)
15475 pfx = "Speaker";
15476 else
15477 pfx = "PCM";
15478 } else
15479 pfx = chname[i];
15480 sprintf(name, "%s Playback Volume", pfx);
15481 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15482 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15483 HDA_OUTPUT));
15484 if (err < 0)
15485 return err;
15486 if (cfg->line_outs == 1 &&
15487 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15488 pfx = "Speaker";
15489 sprintf(name, "%s Playback Switch", pfx);
15490 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15491 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15492 HDA_INPUT));
15493 if (err < 0)
15494 return err;
15497 return 0;
15500 /* add playback controls for speaker and HP outputs */
15501 /* Based on ALC880 version. But ALC861VD has separate,
15502 * different NIDs for mute/unmute switch and volume control */
15503 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15504 hda_nid_t pin, const char *pfx)
15506 hda_nid_t nid_v, nid_s;
15507 int err;
15508 char name[32];
15510 if (!pin)
15511 return 0;
15513 if (alc880_is_fixed_pin(pin)) {
15514 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15515 /* specify the DAC as the extra output */
15516 if (!spec->multiout.hp_nid)
15517 spec->multiout.hp_nid = nid_v;
15518 else
15519 spec->multiout.extra_out_nid[0] = nid_v;
15520 /* control HP volume/switch on the output mixer amp */
15521 nid_v = alc861vd_idx_to_mixer_vol(
15522 alc880_fixed_pin_idx(pin));
15523 nid_s = alc861vd_idx_to_mixer_switch(
15524 alc880_fixed_pin_idx(pin));
15526 sprintf(name, "%s Playback Volume", pfx);
15527 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15528 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15529 if (err < 0)
15530 return err;
15531 sprintf(name, "%s Playback Switch", pfx);
15532 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15533 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15534 if (err < 0)
15535 return err;
15536 } else if (alc880_is_multi_pin(pin)) {
15537 /* set manual connection */
15538 /* we have only a switch on HP-out PIN */
15539 sprintf(name, "%s Playback Switch", pfx);
15540 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15541 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15542 if (err < 0)
15543 return err;
15545 return 0;
15548 /* parse the BIOS configuration and set up the alc_spec
15549 * return 1 if successful, 0 if the proper config is not found,
15550 * or a negative error code
15551 * Based on ALC880 version - had to change it to override
15552 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15553 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15555 struct alc_spec *spec = codec->spec;
15556 int err;
15557 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15559 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15560 alc861vd_ignore);
15561 if (err < 0)
15562 return err;
15563 if (!spec->autocfg.line_outs)
15564 return 0; /* can't find valid BIOS pin config */
15566 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15567 if (err < 0)
15568 return err;
15569 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15570 if (err < 0)
15571 return err;
15572 err = alc861vd_auto_create_extra_out(spec,
15573 spec->autocfg.speaker_pins[0],
15574 "Speaker");
15575 if (err < 0)
15576 return err;
15577 err = alc861vd_auto_create_extra_out(spec,
15578 spec->autocfg.hp_pins[0],
15579 "Headphone");
15580 if (err < 0)
15581 return err;
15582 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15583 if (err < 0)
15584 return err;
15586 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15588 if (spec->autocfg.dig_outs)
15589 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15591 if (spec->kctls.list)
15592 add_mixer(spec, spec->kctls.list);
15594 add_verb(spec, alc861vd_volume_init_verbs);
15596 spec->num_mux_defs = 1;
15597 spec->input_mux = &spec->private_imux[0];
15599 err = alc_auto_add_mic_boost(codec);
15600 if (err < 0)
15601 return err;
15603 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15605 return 1;
15608 /* additional initialization for auto-configuration model */
15609 static void alc861vd_auto_init(struct hda_codec *codec)
15611 struct alc_spec *spec = codec->spec;
15612 alc861vd_auto_init_multi_out(codec);
15613 alc861vd_auto_init_hp_out(codec);
15614 alc861vd_auto_init_analog_input(codec);
15615 alc861vd_auto_init_input_src(codec);
15616 if (spec->unsol_event)
15617 alc_inithook(codec);
15620 enum {
15621 ALC660VD_FIX_ASUS_GPIO1
15624 /* reset GPIO1 */
15625 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
15626 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
15627 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
15628 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
15632 static const struct alc_fixup alc861vd_fixups[] = {
15633 [ALC660VD_FIX_ASUS_GPIO1] = {
15634 .verbs = alc660vd_fix_asus_gpio1_verbs,
15638 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
15639 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
15643 static int patch_alc861vd(struct hda_codec *codec)
15645 struct alc_spec *spec;
15646 int err, board_config;
15648 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15649 if (spec == NULL)
15650 return -ENOMEM;
15652 codec->spec = spec;
15654 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15655 alc861vd_models,
15656 alc861vd_cfg_tbl);
15658 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15659 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15660 codec->chip_name);
15661 board_config = ALC861VD_AUTO;
15664 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
15666 if (board_config == ALC861VD_AUTO) {
15667 /* automatic parse from the BIOS config */
15668 err = alc861vd_parse_auto_config(codec);
15669 if (err < 0) {
15670 alc_free(codec);
15671 return err;
15672 } else if (!err) {
15673 printk(KERN_INFO
15674 "hda_codec: Cannot set up configuration "
15675 "from BIOS. Using base mode...\n");
15676 board_config = ALC861VD_3ST;
15680 err = snd_hda_attach_beep_device(codec, 0x23);
15681 if (err < 0) {
15682 alc_free(codec);
15683 return err;
15686 if (board_config != ALC861VD_AUTO)
15687 setup_preset(codec, &alc861vd_presets[board_config]);
15689 if (codec->vendor_id == 0x10ec0660) {
15690 /* always turn on EAPD */
15691 add_verb(spec, alc660vd_eapd_verbs);
15694 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15695 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15697 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15698 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15700 if (!spec->adc_nids) {
15701 spec->adc_nids = alc861vd_adc_nids;
15702 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15704 if (!spec->capsrc_nids)
15705 spec->capsrc_nids = alc861vd_capsrc_nids;
15707 set_capture_mixer(codec);
15708 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15710 spec->vmaster_nid = 0x02;
15712 codec->patch_ops = alc_patch_ops;
15714 if (board_config == ALC861VD_AUTO)
15715 spec->init_hook = alc861vd_auto_init;
15716 #ifdef CONFIG_SND_HDA_POWER_SAVE
15717 if (!spec->loopback.amplist)
15718 spec->loopback.amplist = alc861vd_loopbacks;
15719 #endif
15720 codec->proc_widget_hook = print_realtek_coef;
15722 return 0;
15726 * ALC662 support
15728 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15729 * configuration. Each pin widget can choose any input DACs and a mixer.
15730 * Each ADC is connected from a mixer of all inputs. This makes possible
15731 * 6-channel independent captures.
15733 * In addition, an independent DAC for the multi-playback (not used in this
15734 * driver yet).
15736 #define ALC662_DIGOUT_NID 0x06
15737 #define ALC662_DIGIN_NID 0x0a
15739 static hda_nid_t alc662_dac_nids[4] = {
15740 /* front, rear, clfe, rear_surr */
15741 0x02, 0x03, 0x04
15744 static hda_nid_t alc272_dac_nids[2] = {
15745 0x02, 0x03
15748 static hda_nid_t alc662_adc_nids[2] = {
15749 /* ADC1-2 */
15750 0x09, 0x08
15753 static hda_nid_t alc272_adc_nids[1] = {
15754 /* ADC1-2 */
15755 0x08,
15758 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15759 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15762 /* input MUX */
15763 /* FIXME: should be a matrix-type input source selection */
15764 static struct hda_input_mux alc662_capture_source = {
15765 .num_items = 4,
15766 .items = {
15767 { "Mic", 0x0 },
15768 { "Front Mic", 0x1 },
15769 { "Line", 0x2 },
15770 { "CD", 0x4 },
15774 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15775 .num_items = 2,
15776 .items = {
15777 { "Mic", 0x1 },
15778 { "Line", 0x2 },
15782 static struct hda_input_mux alc663_capture_source = {
15783 .num_items = 3,
15784 .items = {
15785 { "Mic", 0x0 },
15786 { "Front Mic", 0x1 },
15787 { "Line", 0x2 },
15791 #if 0 /* set to 1 for testing other input sources below */
15792 static struct hda_input_mux alc272_nc10_capture_source = {
15793 .num_items = 16,
15794 .items = {
15795 { "Autoselect Mic", 0x0 },
15796 { "Internal Mic", 0x1 },
15797 { "In-0x02", 0x2 },
15798 { "In-0x03", 0x3 },
15799 { "In-0x04", 0x4 },
15800 { "In-0x05", 0x5 },
15801 { "In-0x06", 0x6 },
15802 { "In-0x07", 0x7 },
15803 { "In-0x08", 0x8 },
15804 { "In-0x09", 0x9 },
15805 { "In-0x0a", 0x0a },
15806 { "In-0x0b", 0x0b },
15807 { "In-0x0c", 0x0c },
15808 { "In-0x0d", 0x0d },
15809 { "In-0x0e", 0x0e },
15810 { "In-0x0f", 0x0f },
15813 #endif
15816 * 2ch mode
15818 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15819 { 2, NULL }
15823 * 2ch mode
15825 static struct hda_verb alc662_3ST_ch2_init[] = {
15826 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15827 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15828 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15829 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15830 { } /* end */
15834 * 6ch mode
15836 static struct hda_verb alc662_3ST_ch6_init[] = {
15837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15839 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15842 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15843 { } /* end */
15846 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15847 { 2, alc662_3ST_ch2_init },
15848 { 6, alc662_3ST_ch6_init },
15852 * 2ch mode
15854 static struct hda_verb alc662_sixstack_ch6_init[] = {
15855 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15856 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15857 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15858 { } /* end */
15862 * 6ch mode
15864 static struct hda_verb alc662_sixstack_ch8_init[] = {
15865 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15866 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15867 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15868 { } /* end */
15871 static struct hda_channel_mode alc662_5stack_modes[2] = {
15872 { 2, alc662_sixstack_ch6_init },
15873 { 6, alc662_sixstack_ch8_init },
15876 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15877 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15880 static struct snd_kcontrol_new alc662_base_mixer[] = {
15881 /* output mixer control */
15882 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15883 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15884 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15885 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15886 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15887 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15888 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15889 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15890 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15892 /*Input mixer control */
15893 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15894 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15895 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15896 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15897 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15898 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15899 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15900 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15901 { } /* end */
15904 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15905 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15906 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15907 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15908 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15909 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15910 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15911 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15914 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15915 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15916 { } /* end */
15919 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15920 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15921 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15922 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15923 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15924 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15925 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15926 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15927 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15928 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15929 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15930 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15937 { } /* end */
15940 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15941 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15942 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15943 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15944 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15950 { } /* end */
15953 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15954 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15955 ALC262_HIPPO_MASTER_SWITCH,
15957 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15958 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15959 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15961 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15962 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15963 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15964 { } /* end */
15967 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15968 ALC262_HIPPO_MASTER_SWITCH,
15969 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15973 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15978 { } /* end */
15981 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15982 .ops = &snd_hda_bind_vol,
15983 .values = {
15984 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15985 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15990 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15991 .ops = &snd_hda_bind_sw,
15992 .values = {
15993 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15994 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15999 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
16000 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16001 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16003 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16004 { } /* end */
16007 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16008 .ops = &snd_hda_bind_sw,
16009 .values = {
16010 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16011 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16012 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16017 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16018 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16019 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16022 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16023 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16025 { } /* end */
16028 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16029 .ops = &snd_hda_bind_sw,
16030 .values = {
16031 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16032 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16033 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16038 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16039 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16040 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16041 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16043 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16044 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16045 { } /* end */
16048 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
16049 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16050 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16051 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16054 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16055 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16056 { } /* end */
16059 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16060 .ops = &snd_hda_bind_vol,
16061 .values = {
16062 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16063 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16068 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16069 .ops = &snd_hda_bind_sw,
16070 .values = {
16071 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16072 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16077 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16078 HDA_BIND_VOL("Master Playback Volume",
16079 &alc663_asus_two_bind_master_vol),
16080 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16085 { } /* end */
16088 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16089 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16090 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16092 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16095 { } /* end */
16098 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16099 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16101 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16102 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16103 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16107 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16108 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16109 { } /* end */
16112 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16113 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16114 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16115 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16117 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16119 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16120 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16121 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16122 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16123 { } /* end */
16126 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16129 .name = "Channel Mode",
16130 .info = alc_ch_mode_info,
16131 .get = alc_ch_mode_get,
16132 .put = alc_ch_mode_put,
16134 { } /* end */
16137 static struct hda_verb alc662_init_verbs[] = {
16138 /* ADC: mute amp left and right */
16139 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16140 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16141 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16143 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16144 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16145 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16146 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16151 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16152 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16153 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16154 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16156 /* Front Pin: output 0 (0x0c) */
16157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16160 /* Rear Pin: output 1 (0x0d) */
16161 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16164 /* CLFE Pin: output 2 (0x0e) */
16165 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16168 /* Mic (rear) pin: input vref at 80% */
16169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16171 /* Front Mic pin: input vref at 80% */
16172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16174 /* Line In pin: input */
16175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16177 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16179 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16180 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16181 /* CD pin widget for input */
16182 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16184 /* FIXME: use matrix-type input source selection */
16185 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16186 /* Input mixer */
16187 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16188 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16190 /* always trun on EAPD */
16191 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16192 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16197 static struct hda_verb alc662_sue_init_verbs[] = {
16198 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16199 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16203 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16205 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16209 /* Set Unsolicited Event*/
16210 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16211 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16212 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16217 * generic initialization of ADC, input mixers and output mixers
16219 static struct hda_verb alc662_auto_init_verbs[] = {
16221 * Unmute ADC and set the default input to mic-in
16223 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16224 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16226 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16227 * mixer widget
16228 * Note: PASD motherboards uses the Line In 2 as the input for front
16229 * panel mic (mic 2)
16231 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16232 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16233 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16234 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16235 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16236 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16239 * Set up output mixers (0x0c - 0x0f)
16241 /* set vol=0 to output mixers */
16242 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16243 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16244 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16246 /* set up input amps for analog loopback */
16247 /* Amp Indices: DAC = 0, mixer = 1 */
16248 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16250 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16251 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16252 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16253 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16256 /* FIXME: use matrix-type input source selection */
16257 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16258 /* Input mixer */
16259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16260 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16264 /* additional verbs for ALC663 */
16265 static struct hda_verb alc663_auto_init_verbs[] = {
16266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16271 static struct hda_verb alc663_m51va_init_verbs[] = {
16272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16273 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16274 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16275 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16276 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16278 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16279 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16280 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16284 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16285 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16286 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16287 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16290 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16291 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16295 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16296 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16298 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16299 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16300 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16301 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16302 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16303 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16307 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16308 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16310 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16313 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16314 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16318 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16319 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16320 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16321 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16322 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16324 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16325 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16328 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16329 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16334 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16335 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16336 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16337 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16338 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16342 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16343 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16344 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16345 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16346 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16350 static struct hda_verb alc663_g71v_init_verbs[] = {
16351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16352 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16353 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16355 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16356 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16357 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16359 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16360 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16361 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16365 static struct hda_verb alc663_g50v_init_verbs[] = {
16366 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16367 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16368 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16370 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16371 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16375 static struct hda_verb alc662_ecs_init_verbs[] = {
16376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16377 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16378 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16379 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16383 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16384 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16385 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16387 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16388 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16389 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16390 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16392 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16393 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16394 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16398 static struct hda_verb alc272_dell_init_verbs[] = {
16399 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16400 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16401 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16402 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16403 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16404 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16405 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16406 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16407 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16409 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16413 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16414 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16415 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16416 { } /* end */
16419 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16420 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16421 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16422 { } /* end */
16425 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16427 unsigned int present;
16428 unsigned char bits;
16430 present = snd_hda_codec_read(codec, 0x14, 0,
16431 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16432 bits = present ? HDA_AMP_MUTE : 0;
16433 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16434 HDA_AMP_MUTE, bits);
16437 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16439 unsigned int present;
16440 unsigned char bits;
16442 present = snd_hda_codec_read(codec, 0x1b, 0,
16443 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16444 bits = present ? HDA_AMP_MUTE : 0;
16445 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16446 HDA_AMP_MUTE, bits);
16447 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16448 HDA_AMP_MUTE, bits);
16451 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16452 unsigned int res)
16454 if ((res >> 26) == ALC880_HP_EVENT)
16455 alc662_lenovo_101e_all_automute(codec);
16456 if ((res >> 26) == ALC880_FRONT_EVENT)
16457 alc662_lenovo_101e_ispeaker_automute(codec);
16460 /* unsolicited event for HP jack sensing */
16461 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16462 unsigned int res)
16464 if ((res >> 26) == ALC880_MIC_EVENT)
16465 alc_mic_automute(codec);
16466 else
16467 alc262_hippo_unsol_event(codec, res);
16470 static void alc662_eeepc_setup(struct hda_codec *codec)
16472 struct alc_spec *spec = codec->spec;
16474 alc262_hippo1_setup(codec);
16475 spec->ext_mic.pin = 0x18;
16476 spec->ext_mic.mux_idx = 0;
16477 spec->int_mic.pin = 0x19;
16478 spec->int_mic.mux_idx = 1;
16479 spec->auto_mic = 1;
16482 static void alc662_eeepc_inithook(struct hda_codec *codec)
16484 alc262_hippo_automute(codec);
16485 alc_mic_automute(codec);
16488 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16490 struct alc_spec *spec = codec->spec;
16492 spec->autocfg.hp_pins[0] = 0x14;
16493 spec->autocfg.speaker_pins[0] = 0x1b;
16496 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16498 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16500 unsigned int present;
16501 unsigned char bits;
16503 present = snd_hda_codec_read(codec, 0x21, 0,
16504 AC_VERB_GET_PIN_SENSE, 0)
16505 & AC_PINSENSE_PRESENCE;
16506 bits = present ? HDA_AMP_MUTE : 0;
16507 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16508 AMP_IN_MUTE(0), bits);
16509 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16510 AMP_IN_MUTE(0), bits);
16513 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16515 unsigned int present;
16516 unsigned char bits;
16518 present = snd_hda_codec_read(codec, 0x21, 0,
16519 AC_VERB_GET_PIN_SENSE, 0)
16520 & AC_PINSENSE_PRESENCE;
16521 bits = present ? HDA_AMP_MUTE : 0;
16522 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16523 AMP_IN_MUTE(0), bits);
16524 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16525 AMP_IN_MUTE(0), bits);
16526 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16527 AMP_IN_MUTE(0), bits);
16528 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16529 AMP_IN_MUTE(0), bits);
16532 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16534 unsigned int present;
16535 unsigned char bits;
16537 present = snd_hda_codec_read(codec, 0x15, 0,
16538 AC_VERB_GET_PIN_SENSE, 0)
16539 & AC_PINSENSE_PRESENCE;
16540 bits = present ? HDA_AMP_MUTE : 0;
16541 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16542 AMP_IN_MUTE(0), bits);
16543 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16544 AMP_IN_MUTE(0), bits);
16545 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16546 AMP_IN_MUTE(0), bits);
16547 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16548 AMP_IN_MUTE(0), bits);
16551 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16553 unsigned int present;
16554 unsigned char bits;
16556 present = snd_hda_codec_read(codec, 0x1b, 0,
16557 AC_VERB_GET_PIN_SENSE, 0)
16558 & AC_PINSENSE_PRESENCE;
16559 bits = present ? 0 : PIN_OUT;
16560 snd_hda_codec_write(codec, 0x14, 0,
16561 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16564 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16566 unsigned int present1, present2;
16568 present1 = snd_hda_codec_read(codec, 0x21, 0,
16569 AC_VERB_GET_PIN_SENSE, 0)
16570 & AC_PINSENSE_PRESENCE;
16571 present2 = snd_hda_codec_read(codec, 0x15, 0,
16572 AC_VERB_GET_PIN_SENSE, 0)
16573 & AC_PINSENSE_PRESENCE;
16575 if (present1 || present2) {
16576 snd_hda_codec_write_cache(codec, 0x14, 0,
16577 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16578 } else {
16579 snd_hda_codec_write_cache(codec, 0x14, 0,
16580 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16584 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16586 unsigned int present1, present2;
16588 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16589 AC_VERB_GET_PIN_SENSE, 0)
16590 & AC_PINSENSE_PRESENCE;
16591 present2 = snd_hda_codec_read(codec, 0x15, 0,
16592 AC_VERB_GET_PIN_SENSE, 0)
16593 & AC_PINSENSE_PRESENCE;
16595 if (present1 || present2) {
16596 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16597 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16598 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16599 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16600 } else {
16601 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16602 AMP_IN_MUTE(0), 0);
16603 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16604 AMP_IN_MUTE(0), 0);
16608 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16609 unsigned int res)
16611 switch (res >> 26) {
16612 case ALC880_HP_EVENT:
16613 alc663_m51va_speaker_automute(codec);
16614 break;
16615 case ALC880_MIC_EVENT:
16616 alc_mic_automute(codec);
16617 break;
16621 static void alc663_m51va_setup(struct hda_codec *codec)
16623 struct alc_spec *spec = codec->spec;
16624 spec->ext_mic.pin = 0x18;
16625 spec->ext_mic.mux_idx = 0;
16626 spec->int_mic.pin = 0x12;
16627 spec->int_mic.mux_idx = 1;
16628 spec->auto_mic = 1;
16631 static void alc663_m51va_inithook(struct hda_codec *codec)
16633 alc663_m51va_speaker_automute(codec);
16634 alc_mic_automute(codec);
16637 /* ***************** Mode1 ******************************/
16638 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
16639 #define alc663_mode1_setup alc663_m51va_setup
16640 #define alc663_mode1_inithook alc663_m51va_inithook
16642 /* ***************** Mode2 ******************************/
16643 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16644 unsigned int res)
16646 switch (res >> 26) {
16647 case ALC880_HP_EVENT:
16648 alc662_f5z_speaker_automute(codec);
16649 break;
16650 case ALC880_MIC_EVENT:
16651 alc_mic_automute(codec);
16652 break;
16656 #define alc662_mode2_setup alc663_m51va_setup
16658 static void alc662_mode2_inithook(struct hda_codec *codec)
16660 alc662_f5z_speaker_automute(codec);
16661 alc_mic_automute(codec);
16663 /* ***************** Mode3 ******************************/
16664 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16665 unsigned int res)
16667 switch (res >> 26) {
16668 case ALC880_HP_EVENT:
16669 alc663_two_hp_m1_speaker_automute(codec);
16670 break;
16671 case ALC880_MIC_EVENT:
16672 alc_mic_automute(codec);
16673 break;
16677 #define alc663_mode3_setup alc663_m51va_setup
16679 static void alc663_mode3_inithook(struct hda_codec *codec)
16681 alc663_two_hp_m1_speaker_automute(codec);
16682 alc_mic_automute(codec);
16684 /* ***************** Mode4 ******************************/
16685 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16686 unsigned int res)
16688 switch (res >> 26) {
16689 case ALC880_HP_EVENT:
16690 alc663_21jd_two_speaker_automute(codec);
16691 break;
16692 case ALC880_MIC_EVENT:
16693 alc_mic_automute(codec);
16694 break;
16698 #define alc663_mode4_setup alc663_m51va_setup
16700 static void alc663_mode4_inithook(struct hda_codec *codec)
16702 alc663_21jd_two_speaker_automute(codec);
16703 alc_mic_automute(codec);
16705 /* ***************** Mode5 ******************************/
16706 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16707 unsigned int res)
16709 switch (res >> 26) {
16710 case ALC880_HP_EVENT:
16711 alc663_15jd_two_speaker_automute(codec);
16712 break;
16713 case ALC880_MIC_EVENT:
16714 alc_mic_automute(codec);
16715 break;
16719 #define alc663_mode5_setup alc663_m51va_setup
16721 static void alc663_mode5_inithook(struct hda_codec *codec)
16723 alc663_15jd_two_speaker_automute(codec);
16724 alc_mic_automute(codec);
16726 /* ***************** Mode6 ******************************/
16727 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16728 unsigned int res)
16730 switch (res >> 26) {
16731 case ALC880_HP_EVENT:
16732 alc663_two_hp_m2_speaker_automute(codec);
16733 break;
16734 case ALC880_MIC_EVENT:
16735 alc_mic_automute(codec);
16736 break;
16740 #define alc663_mode6_setup alc663_m51va_setup
16742 static void alc663_mode6_inithook(struct hda_codec *codec)
16744 alc663_two_hp_m2_speaker_automute(codec);
16745 alc_mic_automute(codec);
16748 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16750 unsigned int present;
16751 unsigned char bits;
16753 present = snd_hda_codec_read(codec, 0x21, 0,
16754 AC_VERB_GET_PIN_SENSE, 0)
16755 & AC_PINSENSE_PRESENCE;
16756 bits = present ? HDA_AMP_MUTE : 0;
16757 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16758 HDA_AMP_MUTE, bits);
16759 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16760 HDA_AMP_MUTE, bits);
16763 static void alc663_g71v_front_automute(struct hda_codec *codec)
16765 unsigned int present;
16766 unsigned char bits;
16768 present = snd_hda_codec_read(codec, 0x15, 0,
16769 AC_VERB_GET_PIN_SENSE, 0)
16770 & AC_PINSENSE_PRESENCE;
16771 bits = present ? HDA_AMP_MUTE : 0;
16772 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16773 HDA_AMP_MUTE, bits);
16776 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16777 unsigned int res)
16779 switch (res >> 26) {
16780 case ALC880_HP_EVENT:
16781 alc663_g71v_hp_automute(codec);
16782 break;
16783 case ALC880_FRONT_EVENT:
16784 alc663_g71v_front_automute(codec);
16785 break;
16786 case ALC880_MIC_EVENT:
16787 alc_mic_automute(codec);
16788 break;
16792 #define alc663_g71v_setup alc663_m51va_setup
16794 static void alc663_g71v_inithook(struct hda_codec *codec)
16796 alc663_g71v_front_automute(codec);
16797 alc663_g71v_hp_automute(codec);
16798 alc_mic_automute(codec);
16801 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16802 unsigned int res)
16804 switch (res >> 26) {
16805 case ALC880_HP_EVENT:
16806 alc663_m51va_speaker_automute(codec);
16807 break;
16808 case ALC880_MIC_EVENT:
16809 alc_mic_automute(codec);
16810 break;
16814 #define alc663_g50v_setup alc663_m51va_setup
16816 static void alc663_g50v_inithook(struct hda_codec *codec)
16818 alc663_m51va_speaker_automute(codec);
16819 alc_mic_automute(codec);
16822 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16823 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16824 ALC262_HIPPO_MASTER_SWITCH,
16826 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16827 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16828 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16830 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16831 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16832 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16833 { } /* end */
16836 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16837 /* Master Playback automatically created from Speaker and Headphone */
16838 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16839 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16840 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16843 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16844 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16845 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16847 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16848 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16849 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16850 { } /* end */
16853 #ifdef CONFIG_SND_HDA_POWER_SAVE
16854 #define alc662_loopbacks alc880_loopbacks
16855 #endif
16858 /* pcm configuration: identical with ALC880 */
16859 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16860 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16861 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16862 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16865 * configuration and preset
16867 static const char *alc662_models[ALC662_MODEL_LAST] = {
16868 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16869 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16870 [ALC662_3ST_6ch] = "3stack-6ch",
16871 [ALC662_5ST_DIG] = "6stack-dig",
16872 [ALC662_LENOVO_101E] = "lenovo-101e",
16873 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16874 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16875 [ALC662_ECS] = "ecs",
16876 [ALC663_ASUS_M51VA] = "m51va",
16877 [ALC663_ASUS_G71V] = "g71v",
16878 [ALC663_ASUS_H13] = "h13",
16879 [ALC663_ASUS_G50V] = "g50v",
16880 [ALC663_ASUS_MODE1] = "asus-mode1",
16881 [ALC662_ASUS_MODE2] = "asus-mode2",
16882 [ALC663_ASUS_MODE3] = "asus-mode3",
16883 [ALC663_ASUS_MODE4] = "asus-mode4",
16884 [ALC663_ASUS_MODE5] = "asus-mode5",
16885 [ALC663_ASUS_MODE6] = "asus-mode6",
16886 [ALC272_DELL] = "dell",
16887 [ALC272_DELL_ZM1] = "dell-zm1",
16888 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16889 [ALC662_AUTO] = "auto",
16892 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16893 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16894 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16895 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16896 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16897 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16898 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16899 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16900 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16901 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16902 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16903 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16904 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16905 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16906 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16907 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16908 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16909 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16910 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16911 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16912 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16913 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16914 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16915 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16916 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16917 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16918 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16919 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16920 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16921 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16922 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16923 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16924 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16925 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16926 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16927 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16928 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16929 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16930 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16931 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16932 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16933 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16934 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16935 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16936 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16937 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16938 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16939 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16940 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16941 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16942 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16943 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16944 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16945 ALC662_3ST_6ch_DIG),
16946 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB200", ALC663_ASUS_MODE4),
16947 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16948 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16949 ALC662_3ST_6ch_DIG),
16950 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16951 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16952 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16953 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16954 ALC662_3ST_6ch_DIG),
16955 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16956 ALC663_ASUS_H13),
16960 static struct alc_config_preset alc662_presets[] = {
16961 [ALC662_3ST_2ch_DIG] = {
16962 .mixers = { alc662_3ST_2ch_mixer },
16963 .init_verbs = { alc662_init_verbs },
16964 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16965 .dac_nids = alc662_dac_nids,
16966 .dig_out_nid = ALC662_DIGOUT_NID,
16967 .dig_in_nid = ALC662_DIGIN_NID,
16968 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16969 .channel_mode = alc662_3ST_2ch_modes,
16970 .input_mux = &alc662_capture_source,
16972 [ALC662_3ST_6ch_DIG] = {
16973 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16974 .init_verbs = { alc662_init_verbs },
16975 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16976 .dac_nids = alc662_dac_nids,
16977 .dig_out_nid = ALC662_DIGOUT_NID,
16978 .dig_in_nid = ALC662_DIGIN_NID,
16979 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16980 .channel_mode = alc662_3ST_6ch_modes,
16981 .need_dac_fix = 1,
16982 .input_mux = &alc662_capture_source,
16984 [ALC662_3ST_6ch] = {
16985 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16986 .init_verbs = { alc662_init_verbs },
16987 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16988 .dac_nids = alc662_dac_nids,
16989 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16990 .channel_mode = alc662_3ST_6ch_modes,
16991 .need_dac_fix = 1,
16992 .input_mux = &alc662_capture_source,
16994 [ALC662_5ST_DIG] = {
16995 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16996 .init_verbs = { alc662_init_verbs },
16997 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16998 .dac_nids = alc662_dac_nids,
16999 .dig_out_nid = ALC662_DIGOUT_NID,
17000 .dig_in_nid = ALC662_DIGIN_NID,
17001 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17002 .channel_mode = alc662_5stack_modes,
17003 .input_mux = &alc662_capture_source,
17005 [ALC662_LENOVO_101E] = {
17006 .mixers = { alc662_lenovo_101e_mixer },
17007 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17008 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17009 .dac_nids = alc662_dac_nids,
17010 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17011 .channel_mode = alc662_3ST_2ch_modes,
17012 .input_mux = &alc662_lenovo_101e_capture_source,
17013 .unsol_event = alc662_lenovo_101e_unsol_event,
17014 .init_hook = alc662_lenovo_101e_all_automute,
17016 [ALC662_ASUS_EEEPC_P701] = {
17017 .mixers = { alc662_eeepc_p701_mixer },
17018 .init_verbs = { alc662_init_verbs,
17019 alc662_eeepc_sue_init_verbs },
17020 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17021 .dac_nids = alc662_dac_nids,
17022 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17023 .channel_mode = alc662_3ST_2ch_modes,
17024 .unsol_event = alc662_eeepc_unsol_event,
17025 .setup = alc662_eeepc_setup,
17026 .init_hook = alc662_eeepc_inithook,
17028 [ALC662_ASUS_EEEPC_EP20] = {
17029 .mixers = { alc662_eeepc_ep20_mixer,
17030 alc662_chmode_mixer },
17031 .init_verbs = { alc662_init_verbs,
17032 alc662_eeepc_ep20_sue_init_verbs },
17033 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17034 .dac_nids = alc662_dac_nids,
17035 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17036 .channel_mode = alc662_3ST_6ch_modes,
17037 .input_mux = &alc662_lenovo_101e_capture_source,
17038 .unsol_event = alc662_eeepc_unsol_event,
17039 .setup = alc662_eeepc_ep20_setup,
17040 .init_hook = alc662_eeepc_ep20_inithook,
17042 [ALC662_ECS] = {
17043 .mixers = { alc662_ecs_mixer },
17044 .init_verbs = { alc662_init_verbs,
17045 alc662_ecs_init_verbs },
17046 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17047 .dac_nids = alc662_dac_nids,
17048 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17049 .channel_mode = alc662_3ST_2ch_modes,
17050 .unsol_event = alc662_eeepc_unsol_event,
17051 .setup = alc662_eeepc_setup,
17052 .init_hook = alc662_eeepc_inithook,
17054 [ALC663_ASUS_M51VA] = {
17055 .mixers = { alc663_m51va_mixer },
17056 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17057 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17058 .dac_nids = alc662_dac_nids,
17059 .dig_out_nid = ALC662_DIGOUT_NID,
17060 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17061 .channel_mode = alc662_3ST_2ch_modes,
17062 .unsol_event = alc663_m51va_unsol_event,
17063 .setup = alc663_m51va_setup,
17064 .init_hook = alc663_m51va_inithook,
17066 [ALC663_ASUS_G71V] = {
17067 .mixers = { alc663_g71v_mixer },
17068 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17069 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17070 .dac_nids = alc662_dac_nids,
17071 .dig_out_nid = ALC662_DIGOUT_NID,
17072 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17073 .channel_mode = alc662_3ST_2ch_modes,
17074 .unsol_event = alc663_g71v_unsol_event,
17075 .setup = alc663_g71v_setup,
17076 .init_hook = alc663_g71v_inithook,
17078 [ALC663_ASUS_H13] = {
17079 .mixers = { alc663_m51va_mixer },
17080 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17081 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17082 .dac_nids = alc662_dac_nids,
17083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17084 .channel_mode = alc662_3ST_2ch_modes,
17085 .unsol_event = alc663_m51va_unsol_event,
17086 .init_hook = alc663_m51va_inithook,
17088 [ALC663_ASUS_G50V] = {
17089 .mixers = { alc663_g50v_mixer },
17090 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
17091 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17092 .dac_nids = alc662_dac_nids,
17093 .dig_out_nid = ALC662_DIGOUT_NID,
17094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17095 .channel_mode = alc662_3ST_6ch_modes,
17096 .input_mux = &alc663_capture_source,
17097 .unsol_event = alc663_g50v_unsol_event,
17098 .setup = alc663_g50v_setup,
17099 .init_hook = alc663_g50v_inithook,
17101 [ALC663_ASUS_MODE1] = {
17102 .mixers = { alc663_m51va_mixer },
17103 .cap_mixer = alc662_auto_capture_mixer,
17104 .init_verbs = { alc662_init_verbs,
17105 alc663_21jd_amic_init_verbs },
17106 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17107 .hp_nid = 0x03,
17108 .dac_nids = alc662_dac_nids,
17109 .dig_out_nid = ALC662_DIGOUT_NID,
17110 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17111 .channel_mode = alc662_3ST_2ch_modes,
17112 .unsol_event = alc663_mode1_unsol_event,
17113 .setup = alc663_mode1_setup,
17114 .init_hook = alc663_mode1_inithook,
17116 [ALC662_ASUS_MODE2] = {
17117 .mixers = { alc662_1bjd_mixer },
17118 .cap_mixer = alc662_auto_capture_mixer,
17119 .init_verbs = { alc662_init_verbs,
17120 alc662_1bjd_amic_init_verbs },
17121 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17122 .dac_nids = alc662_dac_nids,
17123 .dig_out_nid = ALC662_DIGOUT_NID,
17124 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17125 .channel_mode = alc662_3ST_2ch_modes,
17126 .unsol_event = alc662_mode2_unsol_event,
17127 .setup = alc662_mode2_setup,
17128 .init_hook = alc662_mode2_inithook,
17130 [ALC663_ASUS_MODE3] = {
17131 .mixers = { alc663_two_hp_m1_mixer },
17132 .cap_mixer = alc662_auto_capture_mixer,
17133 .init_verbs = { alc662_init_verbs,
17134 alc663_two_hp_amic_m1_init_verbs },
17135 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17136 .hp_nid = 0x03,
17137 .dac_nids = alc662_dac_nids,
17138 .dig_out_nid = ALC662_DIGOUT_NID,
17139 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17140 .channel_mode = alc662_3ST_2ch_modes,
17141 .unsol_event = alc663_mode3_unsol_event,
17142 .setup = alc663_mode3_setup,
17143 .init_hook = alc663_mode3_inithook,
17145 [ALC663_ASUS_MODE4] = {
17146 .mixers = { alc663_asus_21jd_clfe_mixer },
17147 .cap_mixer = alc662_auto_capture_mixer,
17148 .init_verbs = { alc662_init_verbs,
17149 alc663_21jd_amic_init_verbs},
17150 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17151 .hp_nid = 0x03,
17152 .dac_nids = alc662_dac_nids,
17153 .dig_out_nid = ALC662_DIGOUT_NID,
17154 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17155 .channel_mode = alc662_3ST_2ch_modes,
17156 .unsol_event = alc663_mode4_unsol_event,
17157 .setup = alc663_mode4_setup,
17158 .init_hook = alc663_mode4_inithook,
17160 [ALC663_ASUS_MODE5] = {
17161 .mixers = { alc663_asus_15jd_clfe_mixer },
17162 .cap_mixer = alc662_auto_capture_mixer,
17163 .init_verbs = { alc662_init_verbs,
17164 alc663_15jd_amic_init_verbs },
17165 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17166 .hp_nid = 0x03,
17167 .dac_nids = alc662_dac_nids,
17168 .dig_out_nid = ALC662_DIGOUT_NID,
17169 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17170 .channel_mode = alc662_3ST_2ch_modes,
17171 .unsol_event = alc663_mode5_unsol_event,
17172 .setup = alc663_mode5_setup,
17173 .init_hook = alc663_mode5_inithook,
17175 [ALC663_ASUS_MODE6] = {
17176 .mixers = { alc663_two_hp_m2_mixer },
17177 .cap_mixer = alc662_auto_capture_mixer,
17178 .init_verbs = { alc662_init_verbs,
17179 alc663_two_hp_amic_m2_init_verbs },
17180 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17181 .hp_nid = 0x03,
17182 .dac_nids = alc662_dac_nids,
17183 .dig_out_nid = ALC662_DIGOUT_NID,
17184 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17185 .channel_mode = alc662_3ST_2ch_modes,
17186 .unsol_event = alc663_mode6_unsol_event,
17187 .setup = alc663_mode6_setup,
17188 .init_hook = alc663_mode6_inithook,
17190 [ALC272_DELL] = {
17191 .mixers = { alc663_m51va_mixer },
17192 .cap_mixer = alc272_auto_capture_mixer,
17193 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17194 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17195 .dac_nids = alc662_dac_nids,
17196 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17197 .adc_nids = alc272_adc_nids,
17198 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17199 .capsrc_nids = alc272_capsrc_nids,
17200 .channel_mode = alc662_3ST_2ch_modes,
17201 .unsol_event = alc663_m51va_unsol_event,
17202 .setup = alc663_m51va_setup,
17203 .init_hook = alc663_m51va_inithook,
17205 [ALC272_DELL_ZM1] = {
17206 .mixers = { alc663_m51va_mixer },
17207 .cap_mixer = alc662_auto_capture_mixer,
17208 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17209 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17210 .dac_nids = alc662_dac_nids,
17211 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17212 .adc_nids = alc662_adc_nids,
17213 .num_adc_nids = 1,
17214 .capsrc_nids = alc662_capsrc_nids,
17215 .channel_mode = alc662_3ST_2ch_modes,
17216 .unsol_event = alc663_m51va_unsol_event,
17217 .setup = alc663_m51va_setup,
17218 .init_hook = alc663_m51va_inithook,
17220 [ALC272_SAMSUNG_NC10] = {
17221 .mixers = { alc272_nc10_mixer },
17222 .init_verbs = { alc662_init_verbs,
17223 alc663_21jd_amic_init_verbs },
17224 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17225 .dac_nids = alc272_dac_nids,
17226 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17227 .channel_mode = alc662_3ST_2ch_modes,
17228 /*.input_mux = &alc272_nc10_capture_source,*/
17229 .unsol_event = alc663_mode4_unsol_event,
17230 .setup = alc663_mode4_setup,
17231 .init_hook = alc663_mode4_inithook,
17237 * BIOS auto configuration
17240 /* convert from MIX nid to DAC */
17241 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
17243 if (nid == 0x0f)
17244 return 0x02;
17245 else if (nid >= 0x0c && nid <= 0x0e)
17246 return nid - 0x0c + 0x02;
17247 else
17248 return 0;
17251 /* get MIX nid connected to the given pin targeted to DAC */
17252 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
17253 hda_nid_t dac)
17255 hda_nid_t mix[4];
17256 int i, num;
17258 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
17259 for (i = 0; i < num; i++) {
17260 if (alc662_mix_to_dac(mix[i]) == dac)
17261 return mix[i];
17263 return 0;
17266 /* look for an empty DAC slot */
17267 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
17269 struct alc_spec *spec = codec->spec;
17270 hda_nid_t srcs[5];
17271 int i, j, num;
17273 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
17274 if (num < 0)
17275 return 0;
17276 for (i = 0; i < num; i++) {
17277 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
17278 if (!nid)
17279 continue;
17280 for (j = 0; j < spec->multiout.num_dacs; j++)
17281 if (spec->multiout.dac_nids[j] == nid)
17282 break;
17283 if (j >= spec->multiout.num_dacs)
17284 return nid;
17286 return 0;
17289 /* fill in the dac_nids table from the parsed pin configuration */
17290 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
17291 const struct auto_pin_cfg *cfg)
17293 struct alc_spec *spec = codec->spec;
17294 int i;
17295 hda_nid_t dac;
17297 spec->multiout.dac_nids = spec->private_dac_nids;
17298 for (i = 0; i < cfg->line_outs; i++) {
17299 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
17300 if (!dac)
17301 continue;
17302 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
17304 return 0;
17307 static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
17308 hda_nid_t nid, unsigned int chs)
17310 char name[32];
17311 sprintf(name, "%s Playback Volume", pfx);
17312 return add_control(spec, ALC_CTL_WIDGET_VOL, name,
17313 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
17316 static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
17317 hda_nid_t nid, unsigned int chs)
17319 char name[32];
17320 sprintf(name, "%s Playback Switch", pfx);
17321 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17322 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
17325 #define alc662_add_stereo_vol(spec, pfx, nid) \
17326 alc662_add_vol_ctl(spec, pfx, nid, 3)
17327 #define alc662_add_stereo_sw(spec, pfx, nid) \
17328 alc662_add_sw_ctl(spec, pfx, nid, 3)
17330 /* add playback controls from the parsed DAC table */
17331 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
17332 const struct auto_pin_cfg *cfg)
17334 struct alc_spec *spec = codec->spec;
17335 static const char *chname[4] = {
17336 "Front", "Surround", NULL /*CLFE*/, "Side"
17338 hda_nid_t nid, mix;
17339 int i, err;
17341 for (i = 0; i < cfg->line_outs; i++) {
17342 nid = spec->multiout.dac_nids[i];
17343 if (!nid)
17344 continue;
17345 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
17346 if (!mix)
17347 continue;
17348 if (i == 2) {
17349 /* Center/LFE */
17350 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
17351 if (err < 0)
17352 return err;
17353 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
17354 if (err < 0)
17355 return err;
17356 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
17357 if (err < 0)
17358 return err;
17359 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
17360 if (err < 0)
17361 return err;
17362 } else {
17363 const char *pfx;
17364 if (cfg->line_outs == 1 &&
17365 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17366 if (cfg->hp_outs)
17367 pfx = "Speaker";
17368 else
17369 pfx = "PCM";
17370 } else
17371 pfx = chname[i];
17372 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17373 if (err < 0)
17374 return err;
17375 if (cfg->line_outs == 1 &&
17376 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17377 pfx = "Speaker";
17378 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17379 if (err < 0)
17380 return err;
17383 return 0;
17386 /* add playback controls for speaker and HP outputs */
17387 /* return DAC nid if any new DAC is assigned */
17388 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
17389 const char *pfx)
17391 struct alc_spec *spec = codec->spec;
17392 hda_nid_t nid, mix;
17393 int err;
17395 if (!pin)
17396 return 0;
17397 nid = alc662_look_for_dac(codec, pin);
17398 if (!nid) {
17399 char name[32];
17400 /* the corresponding DAC is already occupied */
17401 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
17402 return 0; /* no way */
17403 /* create a switch only */
17404 sprintf(name, "%s Playback Switch", pfx);
17405 return add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17406 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17409 mix = alc662_dac_to_mix(codec, pin, nid);
17410 if (!mix)
17411 return 0;
17412 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
17413 if (err < 0)
17414 return err;
17415 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
17416 if (err < 0)
17417 return err;
17418 return nid;
17421 /* create playback/capture controls for input pins */
17422 #define alc662_auto_create_input_ctls \
17423 alc882_auto_create_input_ctls
17425 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17426 hda_nid_t nid, int pin_type,
17427 hda_nid_t dac)
17429 int i, num;
17430 hda_nid_t srcs[4];
17432 alc_set_pin_output(codec, nid, pin_type);
17433 /* need the manual connection? */
17434 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
17435 if (num <= 1)
17436 return;
17437 for (i = 0; i < num; i++) {
17438 if (alc662_mix_to_dac(srcs[i]) != dac)
17439 continue;
17440 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
17441 return;
17445 static void alc662_auto_init_multi_out(struct hda_codec *codec)
17447 struct alc_spec *spec = codec->spec;
17448 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17449 int i;
17451 for (i = 0; i <= HDA_SIDE; i++) {
17452 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17453 if (nid)
17454 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17455 spec->multiout.dac_nids[i]);
17459 static void alc662_auto_init_hp_out(struct hda_codec *codec)
17461 struct alc_spec *spec = codec->spec;
17462 hda_nid_t pin;
17464 pin = spec->autocfg.hp_pins[0];
17465 if (pin)
17466 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
17467 spec->multiout.hp_nid);
17468 pin = spec->autocfg.speaker_pins[0];
17469 if (pin)
17470 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
17471 spec->multiout.extra_out_nid[0]);
17474 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17476 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17478 struct alc_spec *spec = codec->spec;
17479 int i;
17481 for (i = 0; i < AUTO_PIN_LAST; i++) {
17482 hda_nid_t nid = spec->autocfg.input_pins[i];
17483 if (alc_is_input_pin(codec, nid)) {
17484 alc_set_input_pin(codec, nid, i);
17485 if (nid != ALC662_PIN_CD_NID &&
17486 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17487 snd_hda_codec_write(codec, nid, 0,
17488 AC_VERB_SET_AMP_GAIN_MUTE,
17489 AMP_OUT_MUTE);
17494 #define alc662_auto_init_input_src alc882_auto_init_input_src
17496 static int alc662_parse_auto_config(struct hda_codec *codec)
17498 struct alc_spec *spec = codec->spec;
17499 int err;
17500 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17502 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17503 alc662_ignore);
17504 if (err < 0)
17505 return err;
17506 if (!spec->autocfg.line_outs)
17507 return 0; /* can't find valid BIOS pin config */
17509 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
17510 if (err < 0)
17511 return err;
17512 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
17513 if (err < 0)
17514 return err;
17515 err = alc662_auto_create_extra_out(codec,
17516 spec->autocfg.speaker_pins[0],
17517 "Speaker");
17518 if (err < 0)
17519 return err;
17520 if (err)
17521 spec->multiout.extra_out_nid[0] = err;
17522 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
17523 "Headphone");
17524 if (err < 0)
17525 return err;
17526 if (err)
17527 spec->multiout.hp_nid = err;
17528 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17529 if (err < 0)
17530 return err;
17532 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17534 if (spec->autocfg.dig_outs)
17535 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17537 if (spec->kctls.list)
17538 add_mixer(spec, spec->kctls.list);
17540 spec->num_mux_defs = 1;
17541 spec->input_mux = &spec->private_imux[0];
17543 add_verb(spec, alc662_auto_init_verbs);
17544 if (codec->vendor_id == 0x10ec0663)
17545 add_verb(spec, alc663_auto_init_verbs);
17547 err = alc_auto_add_mic_boost(codec);
17548 if (err < 0)
17549 return err;
17551 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17553 return 1;
17556 /* additional initialization for auto-configuration model */
17557 static void alc662_auto_init(struct hda_codec *codec)
17559 struct alc_spec *spec = codec->spec;
17560 alc662_auto_init_multi_out(codec);
17561 alc662_auto_init_hp_out(codec);
17562 alc662_auto_init_analog_input(codec);
17563 alc662_auto_init_input_src(codec);
17564 if (spec->unsol_event)
17565 alc_inithook(codec);
17568 static int patch_alc662(struct hda_codec *codec)
17570 struct alc_spec *spec;
17571 int err, board_config;
17573 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17574 if (!spec)
17575 return -ENOMEM;
17577 codec->spec = spec;
17579 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17581 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17582 alc662_models,
17583 alc662_cfg_tbl);
17584 if (board_config < 0) {
17585 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17586 codec->chip_name);
17587 board_config = ALC662_AUTO;
17590 if (board_config == ALC662_AUTO) {
17591 /* automatic parse from the BIOS config */
17592 err = alc662_parse_auto_config(codec);
17593 if (err < 0) {
17594 alc_free(codec);
17595 return err;
17596 } else if (!err) {
17597 printk(KERN_INFO
17598 "hda_codec: Cannot set up configuration "
17599 "from BIOS. Using base mode...\n");
17600 board_config = ALC662_3ST_2ch_DIG;
17604 err = snd_hda_attach_beep_device(codec, 0x1);
17605 if (err < 0) {
17606 alc_free(codec);
17607 return err;
17610 if (board_config != ALC662_AUTO)
17611 setup_preset(codec, &alc662_presets[board_config]);
17613 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17614 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17616 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17617 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17619 if (!spec->adc_nids) {
17620 spec->adc_nids = alc662_adc_nids;
17621 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17623 if (!spec->capsrc_nids)
17624 spec->capsrc_nids = alc662_capsrc_nids;
17626 if (!spec->cap_mixer)
17627 set_capture_mixer(codec);
17628 if (codec->vendor_id == 0x10ec0662)
17629 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17630 else
17631 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17633 spec->vmaster_nid = 0x02;
17635 codec->patch_ops = alc_patch_ops;
17636 if (board_config == ALC662_AUTO)
17637 spec->init_hook = alc662_auto_init;
17638 #ifdef CONFIG_SND_HDA_POWER_SAVE
17639 if (!spec->loopback.amplist)
17640 spec->loopback.amplist = alc662_loopbacks;
17641 #endif
17642 codec->proc_widget_hook = print_realtek_coef;
17644 return 0;
17648 * patch entries
17650 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17651 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17652 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17653 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17654 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17655 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17656 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17657 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17658 .patch = patch_alc861 },
17659 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17660 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17661 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17662 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17663 .patch = patch_alc882 },
17664 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17665 .patch = patch_alc662 },
17666 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17667 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17668 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17669 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17670 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17671 .patch = patch_alc882 },
17672 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17673 .patch = patch_alc882 },
17674 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17675 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17676 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17677 .patch = patch_alc882 },
17678 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17679 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17680 {} /* terminator */
17683 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17685 MODULE_LICENSE("GPL");
17686 MODULE_DESCRIPTION("Realtek HD-audio codec");
17688 static struct hda_codec_preset_list realtek_list = {
17689 .preset = snd_hda_preset_realtek,
17690 .owner = THIS_MODULE,
17693 static int __init patch_realtek_init(void)
17695 return snd_hda_add_codec_preset(&realtek_list);
17698 static void __exit patch_realtek_exit(void)
17700 snd_hda_delete_codec_preset(&realtek_list);
17703 module_init(patch_realtek_init)
17704 module_exit(patch_realtek_exit)