eeepc-laptop: right parent device
[linux-2.6/linux-acpi-2.6.git] / sound / pci / hda / patch_realtek.c
blob33453319742508251d3b9a96d2ca1c26312cdcd8
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 ALC882_AUTO,
212 ALC882_MODEL_LAST,
215 /* ALC883 models */
216 enum {
217 ALC883_3ST_2ch_DIG,
218 ALC883_3ST_6ch_DIG,
219 ALC883_3ST_6ch,
220 ALC883_6ST_DIG,
221 ALC883_TARGA_DIG,
222 ALC883_TARGA_2ch_DIG,
223 ALC883_TARGA_8ch_DIG,
224 ALC883_ACER,
225 ALC883_ACER_ASPIRE,
226 ALC888_ACER_ASPIRE_4930G,
227 ALC888_ACER_ASPIRE_6530G,
228 ALC888_ACER_ASPIRE_8930G,
229 ALC883_MEDION,
230 ALC883_MEDION_MD2,
231 ALC883_LAPTOP_EAPD,
232 ALC883_LENOVO_101E_2ch,
233 ALC883_LENOVO_NB0763,
234 ALC888_LENOVO_MS7195_DIG,
235 ALC888_LENOVO_SKY,
236 ALC883_HAIER_W66,
237 ALC888_3ST_HP,
238 ALC888_6ST_DELL,
239 ALC883_MITAC,
240 ALC883_CLEVO_M720,
241 ALC883_FUJITSU_PI2515,
242 ALC888_FUJITSU_XA3530,
243 ALC883_3ST_6ch_INTEL,
244 ALC888_ASUS_M90V,
245 ALC888_ASUS_EEE1601,
246 ALC889A_MB31,
247 ALC1200_ASUS_P5Q,
248 ALC883_SONY_VAIO_TT,
249 ALC883_AUTO,
250 ALC883_MODEL_LAST,
253 /* for GPIO Poll */
254 #define GPIO_MASK 0x03
256 /* extra amp-initialization sequence types */
257 enum {
258 ALC_INIT_NONE,
259 ALC_INIT_DEFAULT,
260 ALC_INIT_GPIO1,
261 ALC_INIT_GPIO2,
262 ALC_INIT_GPIO3,
265 struct alc_spec {
266 /* codec parameterization */
267 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
268 unsigned int num_mixers;
269 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
270 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
272 const struct hda_verb *init_verbs[5]; /* initialization verbs
273 * don't forget NULL
274 * termination!
276 unsigned int num_init_verbs;
278 char stream_name_analog[16]; /* analog PCM stream */
279 struct hda_pcm_stream *stream_analog_playback;
280 struct hda_pcm_stream *stream_analog_capture;
281 struct hda_pcm_stream *stream_analog_alt_playback;
282 struct hda_pcm_stream *stream_analog_alt_capture;
284 char stream_name_digital[16]; /* digital PCM stream */
285 struct hda_pcm_stream *stream_digital_playback;
286 struct hda_pcm_stream *stream_digital_capture;
288 /* playback */
289 struct hda_multi_out multiout; /* playback set-up
290 * max_channels, dacs must be set
291 * dig_out_nid and hp_nid are optional
293 hda_nid_t alt_dac_nid;
294 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
295 int dig_out_type;
297 /* capture */
298 unsigned int num_adc_nids;
299 hda_nid_t *adc_nids;
300 hda_nid_t *capsrc_nids;
301 hda_nid_t dig_in_nid; /* digital-in NID; optional */
303 /* capture source */
304 unsigned int num_mux_defs;
305 const struct hda_input_mux *input_mux;
306 unsigned int cur_mux[3];
308 /* channel model */
309 const struct hda_channel_mode *channel_mode;
310 int num_channel_mode;
311 int need_dac_fix;
312 int const_channel_count;
313 int ext_channel_count;
315 /* PCM information */
316 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
318 /* dynamic controls, init_verbs and input_mux */
319 struct auto_pin_cfg autocfg;
320 struct snd_array kctls;
321 struct hda_input_mux private_imux[3];
322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
324 /* hooks */
325 void (*init_hook)(struct hda_codec *codec);
326 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
328 /* for pin sensing */
329 unsigned int sense_updated: 1;
330 unsigned int jack_present: 1;
331 unsigned int master_sw: 1;
333 /* other flags */
334 unsigned int no_analog :1; /* digital I/O only */
335 int init_amp;
337 /* for virtual master */
338 hda_nid_t vmaster_nid;
339 #ifdef CONFIG_SND_HDA_POWER_SAVE
340 struct hda_loopback_check loopback;
341 #endif
343 /* for PLL fix */
344 hda_nid_t pll_nid;
345 unsigned int pll_coef_idx, pll_coef_bit;
349 * configuration template - to be copied to the spec instance
351 struct alc_config_preset {
352 struct snd_kcontrol_new *mixers[5]; /* should be identical size
353 * with spec
355 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
356 const struct hda_verb *init_verbs[5];
357 unsigned int num_dacs;
358 hda_nid_t *dac_nids;
359 hda_nid_t dig_out_nid; /* optional */
360 hda_nid_t hp_nid; /* optional */
361 hda_nid_t *slave_dig_outs;
362 unsigned int num_adc_nids;
363 hda_nid_t *adc_nids;
364 hda_nid_t *capsrc_nids;
365 hda_nid_t dig_in_nid;
366 unsigned int num_channel_mode;
367 const struct hda_channel_mode *channel_mode;
368 int need_dac_fix;
369 int const_channel_count;
370 unsigned int num_mux_defs;
371 const struct hda_input_mux *input_mux;
372 void (*unsol_event)(struct hda_codec *, unsigned int);
373 void (*init_hook)(struct hda_codec *);
374 #ifdef CONFIG_SND_HDA_POWER_SAVE
375 struct hda_amp_list *loopbacks;
376 #endif
381 * input MUX handling
383 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_info *uinfo)
386 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
387 struct alc_spec *spec = codec->spec;
388 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
389 if (mux_idx >= spec->num_mux_defs)
390 mux_idx = 0;
391 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
394 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
395 struct snd_ctl_elem_value *ucontrol)
397 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
398 struct alc_spec *spec = codec->spec;
399 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
401 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
402 return 0;
405 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
406 struct snd_ctl_elem_value *ucontrol)
408 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
409 struct alc_spec *spec = codec->spec;
410 const struct hda_input_mux *imux;
411 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
412 unsigned int mux_idx;
413 hda_nid_t nid = spec->capsrc_nids ?
414 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
415 unsigned int type;
417 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
418 imux = &spec->input_mux[mux_idx];
420 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
421 if (type == AC_WID_AUD_MIX) {
422 /* Matrix-mixer style (e.g. ALC882) */
423 unsigned int *cur_val = &spec->cur_mux[adc_idx];
424 unsigned int i, idx;
426 idx = ucontrol->value.enumerated.item[0];
427 if (idx >= imux->num_items)
428 idx = imux->num_items - 1;
429 if (*cur_val == idx)
430 return 0;
431 for (i = 0; i < imux->num_items; i++) {
432 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
433 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
434 imux->items[i].index,
435 HDA_AMP_MUTE, v);
437 *cur_val = idx;
438 return 1;
439 } else {
440 /* MUX style (e.g. ALC880) */
441 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
442 &spec->cur_mux[adc_idx]);
447 * channel mode setting
449 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
450 struct snd_ctl_elem_info *uinfo)
452 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
453 struct alc_spec *spec = codec->spec;
454 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
455 spec->num_channel_mode);
458 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
461 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct alc_spec *spec = codec->spec;
463 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
464 spec->num_channel_mode,
465 spec->ext_channel_count);
468 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
469 struct snd_ctl_elem_value *ucontrol)
471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
472 struct alc_spec *spec = codec->spec;
473 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
474 spec->num_channel_mode,
475 &spec->ext_channel_count);
476 if (err >= 0 && !spec->const_channel_count) {
477 spec->multiout.max_channels = spec->ext_channel_count;
478 if (spec->need_dac_fix)
479 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
481 return err;
485 * Control the mode of pin widget settings via the mixer. "pc" is used
486 * instead of "%" to avoid consequences of accidently treating the % as
487 * being part of a format specifier. Maximum allowed length of a value is
488 * 63 characters plus NULL terminator.
490 * Note: some retasking pin complexes seem to ignore requests for input
491 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
492 * are requested. Therefore order this list so that this behaviour will not
493 * cause problems when mixer clients move through the enum sequentially.
494 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
495 * March 2006.
497 static char *alc_pin_mode_names[] = {
498 "Mic 50pc bias", "Mic 80pc bias",
499 "Line in", "Line out", "Headphone out",
501 static unsigned char alc_pin_mode_values[] = {
502 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
504 /* The control can present all 5 options, or it can limit the options based
505 * in the pin being assumed to be exclusively an input or an output pin. In
506 * addition, "input" pins may or may not process the mic bias option
507 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
508 * accept requests for bias as of chip versions up to March 2006) and/or
509 * wiring in the computer.
511 #define ALC_PIN_DIR_IN 0x00
512 #define ALC_PIN_DIR_OUT 0x01
513 #define ALC_PIN_DIR_INOUT 0x02
514 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
515 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
517 /* Info about the pin modes supported by the different pin direction modes.
518 * For each direction the minimum and maximum values are given.
520 static signed char alc_pin_mode_dir_info[5][2] = {
521 { 0, 2 }, /* ALC_PIN_DIR_IN */
522 { 3, 4 }, /* ALC_PIN_DIR_OUT */
523 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
524 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
525 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
527 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
528 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
529 #define alc_pin_mode_n_items(_dir) \
530 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
532 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
533 struct snd_ctl_elem_info *uinfo)
535 unsigned int item_num = uinfo->value.enumerated.item;
536 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
538 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
539 uinfo->count = 1;
540 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
542 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
543 item_num = alc_pin_mode_min(dir);
544 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
545 return 0;
548 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
549 struct snd_ctl_elem_value *ucontrol)
551 unsigned int i;
552 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
553 hda_nid_t nid = kcontrol->private_value & 0xffff;
554 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
555 long *valp = ucontrol->value.integer.value;
556 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
557 AC_VERB_GET_PIN_WIDGET_CONTROL,
558 0x00);
560 /* Find enumerated value for current pinctl setting */
561 i = alc_pin_mode_min(dir);
562 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
563 i++;
564 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
565 return 0;
568 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
569 struct snd_ctl_elem_value *ucontrol)
571 signed int change;
572 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
573 hda_nid_t nid = kcontrol->private_value & 0xffff;
574 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
575 long val = *ucontrol->value.integer.value;
576 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
577 AC_VERB_GET_PIN_WIDGET_CONTROL,
578 0x00);
580 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
581 val = alc_pin_mode_min(dir);
583 change = pinctl != alc_pin_mode_values[val];
584 if (change) {
585 /* Set pin mode to that requested */
586 snd_hda_codec_write_cache(codec, nid, 0,
587 AC_VERB_SET_PIN_WIDGET_CONTROL,
588 alc_pin_mode_values[val]);
590 /* Also enable the retasking pin's input/output as required
591 * for the requested pin mode. Enum values of 2 or less are
592 * input modes.
594 * Dynamically switching the input/output buffers probably
595 * reduces noise slightly (particularly on input) so we'll
596 * do it. However, having both input and output buffers
597 * enabled simultaneously doesn't seem to be problematic if
598 * this turns out to be necessary in the future.
600 if (val <= 2) {
601 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
602 HDA_AMP_MUTE, HDA_AMP_MUTE);
603 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
604 HDA_AMP_MUTE, 0);
605 } else {
606 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
607 HDA_AMP_MUTE, HDA_AMP_MUTE);
608 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
609 HDA_AMP_MUTE, 0);
612 return change;
615 #define ALC_PIN_MODE(xname, nid, dir) \
616 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
617 .info = alc_pin_mode_info, \
618 .get = alc_pin_mode_get, \
619 .put = alc_pin_mode_put, \
620 .private_value = nid | (dir<<16) }
622 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
623 * together using a mask with more than one bit set. This control is
624 * currently used only by the ALC260 test model. At this stage they are not
625 * needed for any "production" models.
627 #ifdef CONFIG_SND_DEBUG
628 #define alc_gpio_data_info snd_ctl_boolean_mono_info
630 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
631 struct snd_ctl_elem_value *ucontrol)
633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
634 hda_nid_t nid = kcontrol->private_value & 0xffff;
635 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
636 long *valp = ucontrol->value.integer.value;
637 unsigned int val = snd_hda_codec_read(codec, nid, 0,
638 AC_VERB_GET_GPIO_DATA, 0x00);
640 *valp = (val & mask) != 0;
641 return 0;
643 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
646 signed int change;
647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
648 hda_nid_t nid = kcontrol->private_value & 0xffff;
649 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
650 long val = *ucontrol->value.integer.value;
651 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
652 AC_VERB_GET_GPIO_DATA,
653 0x00);
655 /* Set/unset the masked GPIO bit(s) as needed */
656 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
657 if (val == 0)
658 gpio_data &= ~mask;
659 else
660 gpio_data |= mask;
661 snd_hda_codec_write_cache(codec, nid, 0,
662 AC_VERB_SET_GPIO_DATA, gpio_data);
664 return change;
666 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
667 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
668 .info = alc_gpio_data_info, \
669 .get = alc_gpio_data_get, \
670 .put = alc_gpio_data_put, \
671 .private_value = nid | (mask<<16) }
672 #endif /* CONFIG_SND_DEBUG */
674 /* A switch control to allow the enabling of the digital IO pins on the
675 * ALC260. This is incredibly simplistic; the intention of this control is
676 * to provide something in the test model allowing digital outputs to be
677 * identified if present. If models are found which can utilise these
678 * outputs a more complete mixer control can be devised for those models if
679 * necessary.
681 #ifdef CONFIG_SND_DEBUG
682 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
684 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
687 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
688 hda_nid_t nid = kcontrol->private_value & 0xffff;
689 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
690 long *valp = ucontrol->value.integer.value;
691 unsigned int val = snd_hda_codec_read(codec, nid, 0,
692 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
694 *valp = (val & mask) != 0;
695 return 0;
697 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
698 struct snd_ctl_elem_value *ucontrol)
700 signed int change;
701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
702 hda_nid_t nid = kcontrol->private_value & 0xffff;
703 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
704 long val = *ucontrol->value.integer.value;
705 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
706 AC_VERB_GET_DIGI_CONVERT_1,
707 0x00);
709 /* Set/unset the masked control bit(s) as needed */
710 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
711 if (val==0)
712 ctrl_data &= ~mask;
713 else
714 ctrl_data |= mask;
715 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
716 ctrl_data);
718 return change;
720 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
721 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
722 .info = alc_spdif_ctrl_info, \
723 .get = alc_spdif_ctrl_get, \
724 .put = alc_spdif_ctrl_put, \
725 .private_value = nid | (mask<<16) }
726 #endif /* CONFIG_SND_DEBUG */
728 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
729 * Again, this is only used in the ALC26x test models to help identify when
730 * the EAPD line must be asserted for features to work.
732 #ifdef CONFIG_SND_DEBUG
733 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
735 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *ucontrol)
738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
739 hda_nid_t nid = kcontrol->private_value & 0xffff;
740 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
741 long *valp = ucontrol->value.integer.value;
742 unsigned int val = snd_hda_codec_read(codec, nid, 0,
743 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
745 *valp = (val & mask) != 0;
746 return 0;
749 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
750 struct snd_ctl_elem_value *ucontrol)
752 int change;
753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
754 hda_nid_t nid = kcontrol->private_value & 0xffff;
755 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
756 long val = *ucontrol->value.integer.value;
757 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
758 AC_VERB_GET_EAPD_BTLENABLE,
759 0x00);
761 /* Set/unset the masked control bit(s) as needed */
762 change = (!val ? 0 : mask) != (ctrl_data & mask);
763 if (!val)
764 ctrl_data &= ~mask;
765 else
766 ctrl_data |= mask;
767 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
768 ctrl_data);
770 return change;
773 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
774 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
775 .info = alc_eapd_ctrl_info, \
776 .get = alc_eapd_ctrl_get, \
777 .put = alc_eapd_ctrl_put, \
778 .private_value = nid | (mask<<16) }
779 #endif /* CONFIG_SND_DEBUG */
782 * set up the input pin config (depending on the given auto-pin type)
784 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
785 int auto_pin_type)
787 unsigned int val = PIN_IN;
789 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
790 unsigned int pincap;
791 pincap = snd_hda_query_pin_caps(codec, nid);
792 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
793 if (pincap & AC_PINCAP_VREF_80)
794 val = PIN_VREF80;
795 else if (pincap & AC_PINCAP_VREF_50)
796 val = PIN_VREF50;
797 else if (pincap & AC_PINCAP_VREF_100)
798 val = PIN_VREF100;
799 else if (pincap & AC_PINCAP_VREF_GRD)
800 val = PIN_VREFGRD;
802 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
807 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
809 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
810 return;
811 spec->mixers[spec->num_mixers++] = mix;
814 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
816 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
817 return;
818 spec->init_verbs[spec->num_init_verbs++] = verb;
821 #ifdef CONFIG_PROC_FS
823 * hook for proc
825 static void print_realtek_coef(struct snd_info_buffer *buffer,
826 struct hda_codec *codec, hda_nid_t nid)
828 int coeff;
830 if (nid != 0x20)
831 return;
832 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
833 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
834 coeff = snd_hda_codec_read(codec, nid, 0,
835 AC_VERB_GET_COEF_INDEX, 0);
836 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
838 #else
839 #define print_realtek_coef NULL
840 #endif
843 * set up from the preset table
845 static void setup_preset(struct alc_spec *spec,
846 const struct alc_config_preset *preset)
848 int i;
850 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
851 add_mixer(spec, preset->mixers[i]);
852 spec->cap_mixer = preset->cap_mixer;
853 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
854 i++)
855 add_verb(spec, preset->init_verbs[i]);
857 spec->channel_mode = preset->channel_mode;
858 spec->num_channel_mode = preset->num_channel_mode;
859 spec->need_dac_fix = preset->need_dac_fix;
860 spec->const_channel_count = preset->const_channel_count;
862 if (preset->const_channel_count)
863 spec->multiout.max_channels = preset->const_channel_count;
864 else
865 spec->multiout.max_channels = spec->channel_mode[0].channels;
866 spec->ext_channel_count = spec->channel_mode[0].channels;
868 spec->multiout.num_dacs = preset->num_dacs;
869 spec->multiout.dac_nids = preset->dac_nids;
870 spec->multiout.dig_out_nid = preset->dig_out_nid;
871 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
872 spec->multiout.hp_nid = preset->hp_nid;
874 spec->num_mux_defs = preset->num_mux_defs;
875 if (!spec->num_mux_defs)
876 spec->num_mux_defs = 1;
877 spec->input_mux = preset->input_mux;
879 spec->num_adc_nids = preset->num_adc_nids;
880 spec->adc_nids = preset->adc_nids;
881 spec->capsrc_nids = preset->capsrc_nids;
882 spec->dig_in_nid = preset->dig_in_nid;
884 spec->unsol_event = preset->unsol_event;
885 spec->init_hook = preset->init_hook;
886 #ifdef CONFIG_SND_HDA_POWER_SAVE
887 spec->loopback.amplist = preset->loopbacks;
888 #endif
891 /* Enable GPIO mask and set output */
892 static struct hda_verb alc_gpio1_init_verbs[] = {
893 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
894 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
895 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
899 static struct hda_verb alc_gpio2_init_verbs[] = {
900 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
901 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
902 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
906 static struct hda_verb alc_gpio3_init_verbs[] = {
907 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
908 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
909 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
914 * Fix hardware PLL issue
915 * On some codecs, the analog PLL gating control must be off while
916 * the default value is 1.
918 static void alc_fix_pll(struct hda_codec *codec)
920 struct alc_spec *spec = codec->spec;
921 unsigned int val;
923 if (!spec->pll_nid)
924 return;
925 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
926 spec->pll_coef_idx);
927 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
928 AC_VERB_GET_PROC_COEF, 0);
929 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
930 spec->pll_coef_idx);
931 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
932 val & ~(1 << spec->pll_coef_bit));
935 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
936 unsigned int coef_idx, unsigned int coef_bit)
938 struct alc_spec *spec = codec->spec;
939 spec->pll_nid = nid;
940 spec->pll_coef_idx = coef_idx;
941 spec->pll_coef_bit = coef_bit;
942 alc_fix_pll(codec);
945 static void alc_automute_pin(struct hda_codec *codec)
947 struct alc_spec *spec = codec->spec;
948 unsigned int present;
949 unsigned int nid = spec->autocfg.hp_pins[0];
950 int i;
952 /* need to execute and sync at first */
953 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
954 present = snd_hda_codec_read(codec, nid, 0,
955 AC_VERB_GET_PIN_SENSE, 0);
956 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
957 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
958 nid = spec->autocfg.speaker_pins[i];
959 if (!nid)
960 break;
961 snd_hda_codec_write(codec, nid, 0,
962 AC_VERB_SET_PIN_WIDGET_CONTROL,
963 spec->jack_present ? 0 : PIN_OUT);
967 #if 0 /* it's broken in some cases -- temporarily disabled */
968 static void alc_mic_automute(struct hda_codec *codec)
970 struct alc_spec *spec = codec->spec;
971 unsigned int present;
972 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
973 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
974 unsigned int mix_nid = spec->capsrc_nids[0];
975 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
977 capsrc_idx_mic = mic_nid - 0x18;
978 capsrc_idx_fmic = fmic_nid - 0x18;
979 present = snd_hda_codec_read(codec, mic_nid, 0,
980 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
981 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
982 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
983 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
984 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
985 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
986 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
988 #else
989 #define alc_mic_automute(codec) do {} while(0) /* NOP */
990 #endif /* disabled */
992 /* unsolicited event for HP jack sensing */
993 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
995 if (codec->vendor_id == 0x10ec0880)
996 res >>= 28;
997 else
998 res >>= 26;
999 switch (res) {
1000 case ALC880_HP_EVENT:
1001 alc_automute_pin(codec);
1002 break;
1003 case ALC880_MIC_EVENT:
1004 alc_mic_automute(codec);
1005 break;
1009 static void alc_inithook(struct hda_codec *codec)
1011 alc_automute_pin(codec);
1012 alc_mic_automute(codec);
1015 /* additional initialization for ALC888 variants */
1016 static void alc888_coef_init(struct hda_codec *codec)
1018 unsigned int tmp;
1020 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1021 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1022 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1023 if ((tmp & 0xf0) == 0x20)
1024 /* alc888S-VC */
1025 snd_hda_codec_read(codec, 0x20, 0,
1026 AC_VERB_SET_PROC_COEF, 0x830);
1027 else
1028 /* alc888-VB */
1029 snd_hda_codec_read(codec, 0x20, 0,
1030 AC_VERB_SET_PROC_COEF, 0x3030);
1033 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1035 unsigned int tmp;
1037 switch (type) {
1038 case ALC_INIT_GPIO1:
1039 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1040 break;
1041 case ALC_INIT_GPIO2:
1042 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1043 break;
1044 case ALC_INIT_GPIO3:
1045 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1046 break;
1047 case ALC_INIT_DEFAULT:
1048 switch (codec->vendor_id) {
1049 case 0x10ec0260:
1050 snd_hda_codec_write(codec, 0x0f, 0,
1051 AC_VERB_SET_EAPD_BTLENABLE, 2);
1052 snd_hda_codec_write(codec, 0x10, 0,
1053 AC_VERB_SET_EAPD_BTLENABLE, 2);
1054 break;
1055 case 0x10ec0262:
1056 case 0x10ec0267:
1057 case 0x10ec0268:
1058 case 0x10ec0269:
1059 case 0x10ec0272:
1060 case 0x10ec0660:
1061 case 0x10ec0662:
1062 case 0x10ec0663:
1063 case 0x10ec0862:
1064 case 0x10ec0889:
1065 snd_hda_codec_write(codec, 0x14, 0,
1066 AC_VERB_SET_EAPD_BTLENABLE, 2);
1067 snd_hda_codec_write(codec, 0x15, 0,
1068 AC_VERB_SET_EAPD_BTLENABLE, 2);
1069 break;
1071 switch (codec->vendor_id) {
1072 case 0x10ec0260:
1073 snd_hda_codec_write(codec, 0x1a, 0,
1074 AC_VERB_SET_COEF_INDEX, 7);
1075 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1076 AC_VERB_GET_PROC_COEF, 0);
1077 snd_hda_codec_write(codec, 0x1a, 0,
1078 AC_VERB_SET_COEF_INDEX, 7);
1079 snd_hda_codec_write(codec, 0x1a, 0,
1080 AC_VERB_SET_PROC_COEF,
1081 tmp | 0x2010);
1082 break;
1083 case 0x10ec0262:
1084 case 0x10ec0880:
1085 case 0x10ec0882:
1086 case 0x10ec0883:
1087 case 0x10ec0885:
1088 case 0x10ec0887:
1089 case 0x10ec0889:
1090 snd_hda_codec_write(codec, 0x20, 0,
1091 AC_VERB_SET_COEF_INDEX, 7);
1092 tmp = snd_hda_codec_read(codec, 0x20, 0,
1093 AC_VERB_GET_PROC_COEF, 0);
1094 snd_hda_codec_write(codec, 0x20, 0,
1095 AC_VERB_SET_COEF_INDEX, 7);
1096 snd_hda_codec_write(codec, 0x20, 0,
1097 AC_VERB_SET_PROC_COEF,
1098 tmp | 0x2010);
1099 break;
1100 case 0x10ec0888:
1101 alc888_coef_init(codec);
1102 break;
1103 case 0x10ec0267:
1104 case 0x10ec0268:
1105 snd_hda_codec_write(codec, 0x20, 0,
1106 AC_VERB_SET_COEF_INDEX, 7);
1107 tmp = snd_hda_codec_read(codec, 0x20, 0,
1108 AC_VERB_GET_PROC_COEF, 0);
1109 snd_hda_codec_write(codec, 0x20, 0,
1110 AC_VERB_SET_COEF_INDEX, 7);
1111 snd_hda_codec_write(codec, 0x20, 0,
1112 AC_VERB_SET_PROC_COEF,
1113 tmp | 0x3000);
1114 break;
1116 break;
1120 static void alc_init_auto_hp(struct hda_codec *codec)
1122 struct alc_spec *spec = codec->spec;
1124 if (!spec->autocfg.hp_pins[0])
1125 return;
1127 if (!spec->autocfg.speaker_pins[0]) {
1128 if (spec->autocfg.line_out_pins[0] &&
1129 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1130 spec->autocfg.speaker_pins[0] =
1131 spec->autocfg.line_out_pins[0];
1132 else
1133 return;
1136 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1137 spec->autocfg.hp_pins[0]);
1138 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1139 AC_VERB_SET_UNSOLICITED_ENABLE,
1140 AC_USRSP_EN | ALC880_HP_EVENT);
1141 spec->unsol_event = alc_sku_unsol_event;
1144 /* check subsystem ID and set up device-specific initialization;
1145 * return 1 if initialized, 0 if invalid SSID
1147 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1148 * 31 ~ 16 : Manufacture ID
1149 * 15 ~ 8 : SKU ID
1150 * 7 ~ 0 : Assembly ID
1151 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1153 static int alc_subsystem_id(struct hda_codec *codec,
1154 hda_nid_t porta, hda_nid_t porte,
1155 hda_nid_t portd)
1157 unsigned int ass, tmp, i;
1158 unsigned nid;
1159 struct alc_spec *spec = codec->spec;
1161 ass = codec->subsystem_id & 0xffff;
1162 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1163 goto do_sku;
1165 /* invalid SSID, check the special NID pin defcfg instead */
1167 * 31~30 : port connectivity
1168 * 29~21 : reserve
1169 * 20 : PCBEEP input
1170 * 19~16 : Check sum (15:1)
1171 * 15~1 : Custom
1172 * 0 : override
1174 nid = 0x1d;
1175 if (codec->vendor_id == 0x10ec0260)
1176 nid = 0x17;
1177 ass = snd_hda_codec_get_pincfg(codec, nid);
1178 snd_printd("realtek: No valid SSID, "
1179 "checking pincfg 0x%08x for NID 0x%x\n",
1180 ass, nid);
1181 if (!(ass & 1) && !(ass & 0x100000))
1182 return 0;
1183 if ((ass >> 30) != 1) /* no physical connection */
1184 return 0;
1186 /* check sum */
1187 tmp = 0;
1188 for (i = 1; i < 16; i++) {
1189 if ((ass >> i) & 1)
1190 tmp++;
1192 if (((ass >> 16) & 0xf) != tmp)
1193 return 0;
1194 do_sku:
1195 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1196 ass & 0xffff, codec->vendor_id);
1198 * 0 : override
1199 * 1 : Swap Jack
1200 * 2 : 0 --> Desktop, 1 --> Laptop
1201 * 3~5 : External Amplifier control
1202 * 7~6 : Reserved
1204 tmp = (ass & 0x38) >> 3; /* external Amp control */
1205 switch (tmp) {
1206 case 1:
1207 spec->init_amp = ALC_INIT_GPIO1;
1208 break;
1209 case 3:
1210 spec->init_amp = ALC_INIT_GPIO2;
1211 break;
1212 case 7:
1213 spec->init_amp = ALC_INIT_GPIO3;
1214 break;
1215 case 5:
1216 spec->init_amp = ALC_INIT_DEFAULT;
1217 break;
1220 /* is laptop or Desktop and enable the function "Mute internal speaker
1221 * when the external headphone out jack is plugged"
1223 if (!(ass & 0x8000))
1224 return 1;
1226 * 10~8 : Jack location
1227 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1228 * 14~13: Resvered
1229 * 15 : 1 --> enable the function "Mute internal speaker
1230 * when the external headphone out jack is plugged"
1232 if (!spec->autocfg.hp_pins[0]) {
1233 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1234 if (tmp == 0)
1235 spec->autocfg.hp_pins[0] = porta;
1236 else if (tmp == 1)
1237 spec->autocfg.hp_pins[0] = porte;
1238 else if (tmp == 2)
1239 spec->autocfg.hp_pins[0] = portd;
1240 else
1241 return 1;
1244 alc_init_auto_hp(codec);
1245 return 1;
1248 static void alc_ssid_check(struct hda_codec *codec,
1249 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1251 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1252 struct alc_spec *spec = codec->spec;
1253 snd_printd("realtek: "
1254 "Enable default setup for auto mode as fallback\n");
1255 spec->init_amp = ALC_INIT_DEFAULT;
1256 alc_init_auto_hp(codec);
1261 * Fix-up pin default configurations
1264 struct alc_pincfg {
1265 hda_nid_t nid;
1266 u32 val;
1269 static void alc_fix_pincfg(struct hda_codec *codec,
1270 const struct snd_pci_quirk *quirk,
1271 const struct alc_pincfg **pinfix)
1273 const struct alc_pincfg *cfg;
1275 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1276 if (!quirk)
1277 return;
1279 cfg = pinfix[quirk->value];
1280 for (; cfg->nid; cfg++)
1281 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1285 * ALC888
1289 * 2ch mode
1291 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1292 /* Mic-in jack as mic in */
1293 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1294 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1295 /* Line-in jack as Line in */
1296 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1297 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1298 /* Line-Out as Front */
1299 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1300 { } /* end */
1304 * 4ch mode
1306 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1307 /* Mic-in jack as mic in */
1308 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1309 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1310 /* Line-in jack as Surround */
1311 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1312 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1313 /* Line-Out as Front */
1314 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1315 { } /* end */
1319 * 6ch mode
1321 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1322 /* Mic-in jack as CLFE */
1323 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1324 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1325 /* Line-in jack as Surround */
1326 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1327 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1328 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1329 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1330 { } /* end */
1334 * 8ch mode
1336 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1337 /* Mic-in jack as CLFE */
1338 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1339 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1340 /* Line-in jack as Surround */
1341 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1342 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1343 /* Line-Out as Side */
1344 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1345 { } /* end */
1348 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1349 { 2, alc888_4ST_ch2_intel_init },
1350 { 4, alc888_4ST_ch4_intel_init },
1351 { 6, alc888_4ST_ch6_intel_init },
1352 { 8, alc888_4ST_ch8_intel_init },
1356 * ALC888 Fujitsu Siemens Amillo xa3530
1359 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1360 /* Front Mic: set to PIN_IN (empty by default) */
1361 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1362 /* Connect Internal HP to Front */
1363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1366 /* Connect Bass HP to Front */
1367 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1370 /* Connect Line-Out side jack (SPDIF) to Side */
1371 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1372 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1373 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1374 /* Connect Mic jack to CLFE */
1375 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1376 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1377 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1378 /* Connect Line-in jack to Surround */
1379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1381 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1382 /* Connect HP out jack to Front */
1383 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1384 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1385 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1386 /* Enable unsolicited event for HP jack and Line-out jack */
1387 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1388 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1392 static void alc_automute_amp(struct hda_codec *codec)
1394 struct alc_spec *spec = codec->spec;
1395 unsigned int val, mute;
1396 hda_nid_t nid;
1397 int i;
1399 spec->jack_present = 0;
1400 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1401 nid = spec->autocfg.hp_pins[i];
1402 if (!nid)
1403 break;
1404 val = snd_hda_codec_read(codec, nid, 0,
1405 AC_VERB_GET_PIN_SENSE, 0);
1406 if (val & AC_PINSENSE_PRESENCE) {
1407 spec->jack_present = 1;
1408 break;
1412 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1413 /* Toggle internal speakers muting */
1414 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1415 nid = spec->autocfg.speaker_pins[i];
1416 if (!nid)
1417 break;
1418 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1419 HDA_AMP_MUTE, mute);
1423 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1424 unsigned int res)
1426 if (codec->vendor_id == 0x10ec0880)
1427 res >>= 28;
1428 else
1429 res >>= 26;
1430 if (res == ALC880_HP_EVENT)
1431 alc_automute_amp(codec);
1434 static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1436 struct alc_spec *spec = codec->spec;
1438 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1439 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1440 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1441 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1442 alc_automute_amp(codec);
1446 * ALC888 Acer Aspire 4930G model
1449 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1450 /* Front Mic: set to PIN_IN (empty by default) */
1451 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1452 /* Unselect Front Mic by default in input mixer 3 */
1453 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1454 /* Enable unsolicited event for HP jack */
1455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1456 /* Connect Internal HP to front */
1457 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1459 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1460 /* Connect HP out to front */
1461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1468 * ALC888 Acer Aspire 6530G model
1471 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1472 /* Bias voltage on for external mic port */
1473 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1474 /* Enable unsolicited event for HP jack */
1475 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1476 /* Enable speaker output */
1477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479 /* Enable headphone output */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1487 * ALC889 Acer Aspire 8930G model
1490 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1491 /* Front Mic: set to PIN_IN (empty by default) */
1492 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1493 /* Unselect Front Mic by default in input mixer 3 */
1494 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1495 /* Enable unsolicited event for HP jack */
1496 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1497 /* Connect Internal Front to Front */
1498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1500 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1501 /* Connect Internal Rear to Rear */
1502 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1503 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1504 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1505 /* Connect Internal CLFE to CLFE */
1506 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1507 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1508 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1509 /* Connect HP out to Front */
1510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1513 /* Enable all DACs */
1514 /* DAC DISABLE/MUTE 1? */
1515 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1516 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1517 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1518 /* DAC DISABLE/MUTE 2? */
1519 /* some bit here disables the other DACs. Init=0x4900 */
1520 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1521 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1522 /* Enable amplifiers */
1523 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1524 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
1525 /* DMIC fix
1526 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1527 * which makes the stereo useless. However, either the mic or the ALC889
1528 * makes the signal become a difference/sum signal instead of standard
1529 * stereo, which is annoying. So instead we flip this bit which makes the
1530 * codec replicate the sum signal to both channels, turning it into a
1531 * normal mono mic.
1533 /* DMIC_CONTROL? Init value = 0x0001 */
1534 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1535 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1539 static struct hda_input_mux alc888_2_capture_sources[2] = {
1540 /* Front mic only available on one ADC */
1542 .num_items = 4,
1543 .items = {
1544 { "Mic", 0x0 },
1545 { "Line", 0x2 },
1546 { "CD", 0x4 },
1547 { "Front Mic", 0xb },
1551 .num_items = 3,
1552 .items = {
1553 { "Mic", 0x0 },
1554 { "Line", 0x2 },
1555 { "CD", 0x4 },
1560 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1561 /* Interal mic only available on one ADC */
1563 .num_items = 3,
1564 .items = {
1565 { "Ext Mic", 0x0 },
1566 { "CD", 0x4 },
1567 { "Int Mic", 0xb },
1571 .num_items = 2,
1572 .items = {
1573 { "Ext Mic", 0x0 },
1574 { "CD", 0x4 },
1579 static struct hda_input_mux alc889_capture_sources[3] = {
1580 /* Digital mic only available on first "ADC" */
1582 .num_items = 5,
1583 .items = {
1584 { "Mic", 0x0 },
1585 { "Line", 0x2 },
1586 { "CD", 0x4 },
1587 { "Front Mic", 0xb },
1588 { "Input Mix", 0xa },
1592 .num_items = 4,
1593 .items = {
1594 { "Mic", 0x0 },
1595 { "Line", 0x2 },
1596 { "CD", 0x4 },
1597 { "Input Mix", 0xa },
1601 .num_items = 4,
1602 .items = {
1603 { "Mic", 0x0 },
1604 { "Line", 0x2 },
1605 { "CD", 0x4 },
1606 { "Input Mix", 0xa },
1611 static struct snd_kcontrol_new alc888_base_mixer[] = {
1612 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1613 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1614 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1615 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1616 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1617 HDA_OUTPUT),
1618 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1619 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1620 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1621 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1622 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1623 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1624 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1625 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1626 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1627 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1628 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1630 { } /* end */
1633 static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec)
1635 struct alc_spec *spec = codec->spec;
1637 spec->autocfg.hp_pins[0] = 0x15;
1638 spec->autocfg.speaker_pins[0] = 0x14;
1639 alc_automute_amp(codec);
1642 static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1644 struct alc_spec *spec = codec->spec;
1646 spec->autocfg.hp_pins[0] = 0x15;
1647 spec->autocfg.speaker_pins[0] = 0x14;
1648 spec->autocfg.speaker_pins[1] = 0x16;
1649 spec->autocfg.speaker_pins[2] = 0x1b;
1650 alc_automute_amp(codec);
1654 * ALC880 3-stack model
1656 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1657 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1658 * F-Mic = 0x1b, HP = 0x19
1661 static hda_nid_t alc880_dac_nids[4] = {
1662 /* front, rear, clfe, rear_surr */
1663 0x02, 0x05, 0x04, 0x03
1666 static hda_nid_t alc880_adc_nids[3] = {
1667 /* ADC0-2 */
1668 0x07, 0x08, 0x09,
1671 /* The datasheet says the node 0x07 is connected from inputs,
1672 * but it shows zero connection in the real implementation on some devices.
1673 * Note: this is a 915GAV bug, fixed on 915GLV
1675 static hda_nid_t alc880_adc_nids_alt[2] = {
1676 /* ADC1-2 */
1677 0x08, 0x09,
1680 #define ALC880_DIGOUT_NID 0x06
1681 #define ALC880_DIGIN_NID 0x0a
1683 static struct hda_input_mux alc880_capture_source = {
1684 .num_items = 4,
1685 .items = {
1686 { "Mic", 0x0 },
1687 { "Front Mic", 0x3 },
1688 { "Line", 0x2 },
1689 { "CD", 0x4 },
1693 /* channel source setting (2/6 channel selection for 3-stack) */
1694 /* 2ch mode */
1695 static struct hda_verb alc880_threestack_ch2_init[] = {
1696 /* set line-in to input, mute it */
1697 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1698 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1699 /* set mic-in to input vref 80%, mute it */
1700 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1701 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1702 { } /* end */
1705 /* 6ch mode */
1706 static struct hda_verb alc880_threestack_ch6_init[] = {
1707 /* set line-in to output, unmute it */
1708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1710 /* set mic-in to output, unmute it */
1711 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1712 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1713 { } /* end */
1716 static struct hda_channel_mode alc880_threestack_modes[2] = {
1717 { 2, alc880_threestack_ch2_init },
1718 { 6, alc880_threestack_ch6_init },
1721 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1722 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1723 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1724 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1725 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1726 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1727 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1728 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1729 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1730 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1731 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1732 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1733 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1734 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1735 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1736 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1737 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1738 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1741 .name = "Channel Mode",
1742 .info = alc_ch_mode_info,
1743 .get = alc_ch_mode_get,
1744 .put = alc_ch_mode_put,
1746 { } /* end */
1749 /* capture mixer elements */
1750 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1751 struct snd_ctl_elem_info *uinfo)
1753 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1754 struct alc_spec *spec = codec->spec;
1755 int err;
1757 mutex_lock(&codec->control_mutex);
1758 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1759 HDA_INPUT);
1760 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1761 mutex_unlock(&codec->control_mutex);
1762 return err;
1765 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1766 unsigned int size, unsigned int __user *tlv)
1768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1769 struct alc_spec *spec = codec->spec;
1770 int err;
1772 mutex_lock(&codec->control_mutex);
1773 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1774 HDA_INPUT);
1775 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1776 mutex_unlock(&codec->control_mutex);
1777 return err;
1780 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1781 struct snd_ctl_elem_value *ucontrol);
1783 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1784 struct snd_ctl_elem_value *ucontrol,
1785 getput_call_t func)
1787 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1788 struct alc_spec *spec = codec->spec;
1789 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1790 int err;
1792 mutex_lock(&codec->control_mutex);
1793 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1794 3, 0, HDA_INPUT);
1795 err = func(kcontrol, ucontrol);
1796 mutex_unlock(&codec->control_mutex);
1797 return err;
1800 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1801 struct snd_ctl_elem_value *ucontrol)
1803 return alc_cap_getput_caller(kcontrol, ucontrol,
1804 snd_hda_mixer_amp_volume_get);
1807 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1808 struct snd_ctl_elem_value *ucontrol)
1810 return alc_cap_getput_caller(kcontrol, ucontrol,
1811 snd_hda_mixer_amp_volume_put);
1814 /* capture mixer elements */
1815 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
1817 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1818 struct snd_ctl_elem_value *ucontrol)
1820 return alc_cap_getput_caller(kcontrol, ucontrol,
1821 snd_hda_mixer_amp_switch_get);
1824 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1825 struct snd_ctl_elem_value *ucontrol)
1827 return alc_cap_getput_caller(kcontrol, ucontrol,
1828 snd_hda_mixer_amp_switch_put);
1831 #define _DEFINE_CAPMIX(num) \
1833 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1834 .name = "Capture Switch", \
1835 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1836 .count = num, \
1837 .info = alc_cap_sw_info, \
1838 .get = alc_cap_sw_get, \
1839 .put = alc_cap_sw_put, \
1840 }, \
1842 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1843 .name = "Capture Volume", \
1844 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1845 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1846 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1847 .count = num, \
1848 .info = alc_cap_vol_info, \
1849 .get = alc_cap_vol_get, \
1850 .put = alc_cap_vol_put, \
1851 .tlv = { .c = alc_cap_vol_tlv }, \
1854 #define _DEFINE_CAPSRC(num) \
1856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1857 /* .name = "Capture Source", */ \
1858 .name = "Input Source", \
1859 .count = num, \
1860 .info = alc_mux_enum_info, \
1861 .get = alc_mux_enum_get, \
1862 .put = alc_mux_enum_put, \
1865 #define DEFINE_CAPMIX(num) \
1866 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1867 _DEFINE_CAPMIX(num), \
1868 _DEFINE_CAPSRC(num), \
1869 { } /* end */ \
1872 #define DEFINE_CAPMIX_NOSRC(num) \
1873 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
1874 _DEFINE_CAPMIX(num), \
1875 { } /* end */ \
1878 /* up to three ADCs */
1879 DEFINE_CAPMIX(1);
1880 DEFINE_CAPMIX(2);
1881 DEFINE_CAPMIX(3);
1882 DEFINE_CAPMIX_NOSRC(1);
1883 DEFINE_CAPMIX_NOSRC(2);
1884 DEFINE_CAPMIX_NOSRC(3);
1887 * ALC880 5-stack model
1889 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1890 * Side = 0x02 (0xd)
1891 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1892 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1895 /* additional mixers to alc880_three_stack_mixer */
1896 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1897 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1898 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1899 { } /* end */
1902 /* channel source setting (6/8 channel selection for 5-stack) */
1903 /* 6ch mode */
1904 static struct hda_verb alc880_fivestack_ch6_init[] = {
1905 /* set line-in to input, mute it */
1906 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1907 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1908 { } /* end */
1911 /* 8ch mode */
1912 static struct hda_verb alc880_fivestack_ch8_init[] = {
1913 /* set line-in to output, unmute it */
1914 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1915 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1916 { } /* end */
1919 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1920 { 6, alc880_fivestack_ch6_init },
1921 { 8, alc880_fivestack_ch8_init },
1926 * ALC880 6-stack model
1928 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1929 * Side = 0x05 (0x0f)
1930 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1931 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1934 static hda_nid_t alc880_6st_dac_nids[4] = {
1935 /* front, rear, clfe, rear_surr */
1936 0x02, 0x03, 0x04, 0x05
1939 static struct hda_input_mux alc880_6stack_capture_source = {
1940 .num_items = 4,
1941 .items = {
1942 { "Mic", 0x0 },
1943 { "Front Mic", 0x1 },
1944 { "Line", 0x2 },
1945 { "CD", 0x4 },
1949 /* fixed 8-channels */
1950 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1951 { 8, NULL },
1954 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1955 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1956 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1957 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1958 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1959 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1960 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1961 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1962 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1963 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1964 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1966 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1971 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1972 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1975 .name = "Channel Mode",
1976 .info = alc_ch_mode_info,
1977 .get = alc_ch_mode_get,
1978 .put = alc_ch_mode_put,
1980 { } /* end */
1985 * ALC880 W810 model
1987 * W810 has rear IO for:
1988 * Front (DAC 02)
1989 * Surround (DAC 03)
1990 * Center/LFE (DAC 04)
1991 * Digital out (06)
1993 * The system also has a pair of internal speakers, and a headphone jack.
1994 * These are both connected to Line2 on the codec, hence to DAC 02.
1996 * There is a variable resistor to control the speaker or headphone
1997 * volume. This is a hardware-only device without a software API.
1999 * Plugging headphones in will disable the internal speakers. This is
2000 * implemented in hardware, not via the driver using jack sense. In
2001 * a similar fashion, plugging into the rear socket marked "front" will
2002 * disable both the speakers and headphones.
2004 * For input, there's a microphone jack, and an "audio in" jack.
2005 * These may not do anything useful with this driver yet, because I
2006 * haven't setup any initialization verbs for these yet...
2009 static hda_nid_t alc880_w810_dac_nids[3] = {
2010 /* front, rear/surround, clfe */
2011 0x02, 0x03, 0x04
2014 /* fixed 6 channels */
2015 static struct hda_channel_mode alc880_w810_modes[1] = {
2016 { 6, NULL }
2019 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2020 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2021 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2022 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2023 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2024 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2025 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2026 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2027 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2028 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2030 { } /* end */
2035 * Z710V model
2037 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2038 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2039 * Line = 0x1a
2042 static hda_nid_t alc880_z71v_dac_nids[1] = {
2043 0x02
2045 #define ALC880_Z71V_HP_DAC 0x03
2047 /* fixed 2 channels */
2048 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2049 { 2, NULL }
2052 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2055 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2056 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2060 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2061 { } /* end */
2066 * ALC880 F1734 model
2068 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2069 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2072 static hda_nid_t alc880_f1734_dac_nids[1] = {
2073 0x03
2075 #define ALC880_F1734_HP_DAC 0x02
2077 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2079 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2082 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2083 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2086 { } /* end */
2089 static struct hda_input_mux alc880_f1734_capture_source = {
2090 .num_items = 2,
2091 .items = {
2092 { "Mic", 0x1 },
2093 { "CD", 0x4 },
2099 * ALC880 ASUS model
2101 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2102 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2103 * Mic = 0x18, Line = 0x1a
2106 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2107 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2109 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2110 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2111 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2112 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2113 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2114 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2115 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2116 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2117 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2118 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2119 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2120 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2121 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2126 .name = "Channel Mode",
2127 .info = alc_ch_mode_info,
2128 .get = alc_ch_mode_get,
2129 .put = alc_ch_mode_put,
2131 { } /* end */
2135 * ALC880 ASUS W1V model
2137 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2138 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2139 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2142 /* additional mixers to alc880_asus_mixer */
2143 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2144 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2145 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2146 { } /* end */
2149 /* TCL S700 */
2150 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2151 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2152 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2153 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2154 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2155 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2158 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2159 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2160 { } /* end */
2163 /* Uniwill */
2164 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2168 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2169 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2170 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2171 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2172 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2173 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2174 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2175 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2176 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2180 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2183 .name = "Channel Mode",
2184 .info = alc_ch_mode_info,
2185 .get = alc_ch_mode_get,
2186 .put = alc_ch_mode_put,
2188 { } /* end */
2191 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2193 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2194 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2195 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2196 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2197 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2198 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2199 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2201 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2202 { } /* end */
2205 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2206 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2207 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2208 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2209 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2212 { } /* end */
2216 * virtual master controls
2220 * slave controls for virtual master
2222 static const char *alc_slave_vols[] = {
2223 "Front Playback Volume",
2224 "Surround Playback Volume",
2225 "Center Playback Volume",
2226 "LFE Playback Volume",
2227 "Side Playback Volume",
2228 "Headphone Playback Volume",
2229 "Speaker Playback Volume",
2230 "Mono Playback Volume",
2231 "Line-Out Playback Volume",
2232 "PCM Playback Volume",
2233 NULL,
2236 static const char *alc_slave_sws[] = {
2237 "Front Playback Switch",
2238 "Surround Playback Switch",
2239 "Center Playback Switch",
2240 "LFE Playback Switch",
2241 "Side Playback Switch",
2242 "Headphone Playback Switch",
2243 "Speaker Playback Switch",
2244 "Mono Playback Switch",
2245 "IEC958 Playback Switch",
2246 NULL,
2250 * build control elements
2253 static void alc_free_kctls(struct hda_codec *codec);
2255 /* additional beep mixers; the actual parameters are overwritten at build */
2256 static struct snd_kcontrol_new alc_beep_mixer[] = {
2257 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2258 HDA_CODEC_MUTE("Beep Playback Switch", 0, 0, HDA_INPUT),
2259 { } /* end */
2262 static int alc_build_controls(struct hda_codec *codec)
2264 struct alc_spec *spec = codec->spec;
2265 int err;
2266 int i;
2268 for (i = 0; i < spec->num_mixers; i++) {
2269 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2270 if (err < 0)
2271 return err;
2273 if (spec->cap_mixer) {
2274 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2275 if (err < 0)
2276 return err;
2278 if (spec->multiout.dig_out_nid) {
2279 err = snd_hda_create_spdif_out_ctls(codec,
2280 spec->multiout.dig_out_nid);
2281 if (err < 0)
2282 return err;
2283 if (!spec->no_analog) {
2284 err = snd_hda_create_spdif_share_sw(codec,
2285 &spec->multiout);
2286 if (err < 0)
2287 return err;
2288 spec->multiout.share_spdif = 1;
2291 if (spec->dig_in_nid) {
2292 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2293 if (err < 0)
2294 return err;
2297 /* create beep controls if needed */
2298 if (spec->beep_amp) {
2299 struct snd_kcontrol_new *knew;
2300 for (knew = alc_beep_mixer; knew->name; knew++) {
2301 struct snd_kcontrol *kctl;
2302 kctl = snd_ctl_new1(knew, codec);
2303 if (!kctl)
2304 return -ENOMEM;
2305 kctl->private_value = spec->beep_amp;
2306 err = snd_hda_ctl_add(codec, kctl);
2307 if (err < 0)
2308 return err;
2312 /* if we have no master control, let's create it */
2313 if (!spec->no_analog &&
2314 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2315 unsigned int vmaster_tlv[4];
2316 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2317 HDA_OUTPUT, vmaster_tlv);
2318 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2319 vmaster_tlv, alc_slave_vols);
2320 if (err < 0)
2321 return err;
2323 if (!spec->no_analog &&
2324 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2325 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2326 NULL, alc_slave_sws);
2327 if (err < 0)
2328 return err;
2331 alc_free_kctls(codec); /* no longer needed */
2332 return 0;
2337 * initialize the codec volumes, etc
2341 * generic initialization of ADC, input mixers and output mixers
2343 static struct hda_verb alc880_volume_init_verbs[] = {
2345 * Unmute ADC0-2 and set the default input to mic-in
2347 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2348 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2349 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2351 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2354 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2355 * mixer widget
2356 * Note: PASD motherboards uses the Line In 2 as the input for front
2357 * panel mic (mic 2)
2359 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2360 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2361 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2362 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2363 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2364 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2365 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2366 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2369 * Set up output mixers (0x0c - 0x0f)
2371 /* set vol=0 to output mixers */
2372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2375 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2376 /* set up input amps for analog loopback */
2377 /* Amp Indices: DAC = 0, mixer = 1 */
2378 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2379 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2380 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2381 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2382 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2383 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2385 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2391 * 3-stack pin configuration:
2392 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2394 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2396 * preset connection lists of input pins
2397 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2399 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2400 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2401 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2404 * Set pin mode and muting
2406 /* set front pin widgets 0x14 for output */
2407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2408 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2409 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2410 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2411 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2412 /* Mic2 (as headphone out) for HP output */
2413 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2414 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2415 /* Line In pin widget for input */
2416 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2418 /* Line2 (as front mic) pin widget for input and vref at 80% */
2419 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2420 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2421 /* CD pin widget for input */
2422 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2428 * 5-stack pin configuration:
2429 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2430 * line-in/side = 0x1a, f-mic = 0x1b
2432 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2434 * preset connection lists of input pins
2435 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2437 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2438 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2441 * Set pin mode and muting
2443 /* set pin widgets 0x14-0x17 for output */
2444 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2445 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2446 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2447 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2448 /* unmute pins for output (no gain on this amp) */
2449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2450 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2451 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2452 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2454 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2455 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2456 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 /* Mic2 (as headphone out) for HP output */
2458 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2459 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2460 /* Line In pin widget for input */
2461 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2463 /* Line2 (as front mic) pin widget for input and vref at 80% */
2464 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2465 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2466 /* CD pin widget for input */
2467 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2473 * W810 pin configuration:
2474 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2476 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2477 /* hphone/speaker input selector: front DAC */
2478 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2483 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2484 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2485 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2487 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2488 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2494 * Z71V pin configuration:
2495 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2497 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2503 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2504 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2505 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2506 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2512 * 6-stack pin configuration:
2513 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2514 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2516 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2517 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2522 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2524 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2525 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2526 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2529 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2531 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2532 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2533 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2534 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2535 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2536 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2542 * Uniwill pin configuration:
2543 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2544 * line = 0x1a
2546 static struct hda_verb alc880_uniwill_init_verbs[] = {
2547 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2549 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2550 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2551 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2552 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2554 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2556 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2561 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2562 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2564 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2565 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2566 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2567 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2568 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2569 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2570 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2571 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2572 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2574 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2575 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2581 * Uniwill P53
2582 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2584 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2585 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2587 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2594 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2595 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2596 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2597 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2598 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2600 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2601 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2602 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2603 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2604 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2605 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2607 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2608 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2613 static struct hda_verb alc880_beep_init_verbs[] = {
2614 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2618 /* auto-toggle front mic */
2619 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2621 unsigned int present;
2622 unsigned char bits;
2624 present = snd_hda_codec_read(codec, 0x18, 0,
2625 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2626 bits = present ? HDA_AMP_MUTE : 0;
2627 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2630 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2632 struct alc_spec *spec = codec->spec;
2634 spec->autocfg.hp_pins[0] = 0x14;
2635 spec->autocfg.speaker_pins[0] = 0x15;
2636 spec->autocfg.speaker_pins[0] = 0x16;
2637 alc_automute_amp(codec);
2638 alc880_uniwill_mic_automute(codec);
2641 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2642 unsigned int res)
2644 /* Looks like the unsol event is incompatible with the standard
2645 * definition. 4bit tag is placed at 28 bit!
2647 switch (res >> 28) {
2648 case ALC880_MIC_EVENT:
2649 alc880_uniwill_mic_automute(codec);
2650 break;
2651 default:
2652 alc_automute_amp_unsol_event(codec, res);
2653 break;
2657 static void alc880_uniwill_p53_init_hook(struct hda_codec *codec)
2659 struct alc_spec *spec = codec->spec;
2661 spec->autocfg.hp_pins[0] = 0x14;
2662 spec->autocfg.speaker_pins[0] = 0x15;
2663 alc_automute_amp(codec);
2666 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2668 unsigned int present;
2670 present = snd_hda_codec_read(codec, 0x21, 0,
2671 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2672 present &= HDA_AMP_VOLMASK;
2673 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2674 HDA_AMP_VOLMASK, present);
2675 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2676 HDA_AMP_VOLMASK, present);
2679 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2680 unsigned int res)
2682 /* Looks like the unsol event is incompatible with the standard
2683 * definition. 4bit tag is placed at 28 bit!
2685 if ((res >> 28) == ALC880_DCVOL_EVENT)
2686 alc880_uniwill_p53_dcvol_automute(codec);
2687 else
2688 alc_automute_amp_unsol_event(codec, res);
2692 * F1734 pin configuration:
2693 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2695 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2696 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2697 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2698 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2699 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2700 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2703 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2704 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2705 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2707 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2709 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2711 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2712 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2713 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2714 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2715 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2717 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2718 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2724 * ASUS pin configuration:
2725 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2727 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2728 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2729 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2730 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2731 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2733 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2735 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2736 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2739 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2742 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2750 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2755 /* Enable GPIO mask and set output */
2756 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2757 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2758 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
2760 /* Clevo m520g init */
2761 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2762 /* headphone output */
2763 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2764 /* line-out */
2765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2767 /* Line-in */
2768 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2770 /* CD */
2771 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2772 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2773 /* Mic1 (rear panel) */
2774 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2776 /* Mic2 (front panel) */
2777 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2778 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2779 /* headphone */
2780 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2781 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2782 /* change to EAPD mode */
2783 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2784 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2789 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2790 /* change to EAPD mode */
2791 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2792 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2794 /* Headphone output */
2795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2796 /* Front output*/
2797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2798 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2800 /* Line In pin widget for input */
2801 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2802 /* CD pin widget for input */
2803 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2804 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2805 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2807 /* change to EAPD mode */
2808 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2809 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2815 * LG m1 express dual
2817 * Pin assignment:
2818 * Rear Line-In/Out (blue): 0x14
2819 * Build-in Mic-In: 0x15
2820 * Speaker-out: 0x17
2821 * HP-Out (green): 0x1b
2822 * Mic-In/Out (red): 0x19
2823 * SPDIF-Out: 0x1e
2826 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2827 static hda_nid_t alc880_lg_dac_nids[3] = {
2828 0x05, 0x02, 0x03
2831 /* seems analog CD is not working */
2832 static struct hda_input_mux alc880_lg_capture_source = {
2833 .num_items = 3,
2834 .items = {
2835 { "Mic", 0x1 },
2836 { "Line", 0x5 },
2837 { "Internal Mic", 0x6 },
2841 /* 2,4,6 channel modes */
2842 static struct hda_verb alc880_lg_ch2_init[] = {
2843 /* set line-in and mic-in to input */
2844 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2845 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2849 static struct hda_verb alc880_lg_ch4_init[] = {
2850 /* set line-in to out and mic-in to input */
2851 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2852 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2856 static struct hda_verb alc880_lg_ch6_init[] = {
2857 /* set line-in and mic-in to output */
2858 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2859 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2863 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2864 { 2, alc880_lg_ch2_init },
2865 { 4, alc880_lg_ch4_init },
2866 { 6, alc880_lg_ch6_init },
2869 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2870 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2871 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2872 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2873 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2874 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2875 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2876 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2877 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2880 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2881 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2882 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2883 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2885 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2886 .name = "Channel Mode",
2887 .info = alc_ch_mode_info,
2888 .get = alc_ch_mode_get,
2889 .put = alc_ch_mode_put,
2891 { } /* end */
2894 static struct hda_verb alc880_lg_init_verbs[] = {
2895 /* set capture source to mic-in */
2896 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2897 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2898 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2899 /* mute all amp mixer inputs */
2900 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2901 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2902 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2903 /* line-in to input */
2904 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2905 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2906 /* built-in mic */
2907 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2909 /* speaker-out */
2910 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2911 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2912 /* mic-in to input */
2913 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2914 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2915 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2916 /* HP-out */
2917 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2918 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2919 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2920 /* jack sense */
2921 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2925 /* toggle speaker-output according to the hp-jack state */
2926 static void alc880_lg_init_hook(struct hda_codec *codec)
2928 struct alc_spec *spec = codec->spec;
2930 spec->autocfg.hp_pins[0] = 0x1b;
2931 spec->autocfg.speaker_pins[0] = 0x17;
2932 alc_automute_amp(codec);
2936 * LG LW20
2938 * Pin assignment:
2939 * Speaker-out: 0x14
2940 * Mic-In: 0x18
2941 * Built-in Mic-In: 0x19
2942 * Line-In: 0x1b
2943 * HP-Out: 0x1a
2944 * SPDIF-Out: 0x1e
2947 static struct hda_input_mux alc880_lg_lw_capture_source = {
2948 .num_items = 3,
2949 .items = {
2950 { "Mic", 0x0 },
2951 { "Internal Mic", 0x1 },
2952 { "Line In", 0x2 },
2956 #define alc880_lg_lw_modes alc880_threestack_modes
2958 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2959 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2960 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2961 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2962 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2963 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2964 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2965 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2966 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2967 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2968 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2971 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2972 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2975 .name = "Channel Mode",
2976 .info = alc_ch_mode_info,
2977 .get = alc_ch_mode_get,
2978 .put = alc_ch_mode_put,
2980 { } /* end */
2983 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2984 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2985 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2986 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2988 /* set capture source to mic-in */
2989 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2990 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2991 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2992 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2993 /* speaker-out */
2994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2995 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2996 /* HP-out */
2997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2998 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2999 /* mic-in to input */
3000 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3001 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3002 /* built-in mic */
3003 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3004 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3005 /* jack sense */
3006 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3010 /* toggle speaker-output according to the hp-jack state */
3011 static void alc880_lg_lw_init_hook(struct hda_codec *codec)
3013 struct alc_spec *spec = codec->spec;
3015 spec->autocfg.hp_pins[0] = 0x1b;
3016 spec->autocfg.speaker_pins[0] = 0x14;
3017 alc_automute_amp(codec);
3020 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3021 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3022 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3024 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3025 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3026 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3027 { } /* end */
3030 static struct hda_input_mux alc880_medion_rim_capture_source = {
3031 .num_items = 2,
3032 .items = {
3033 { "Mic", 0x0 },
3034 { "Internal Mic", 0x1 },
3038 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3039 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3041 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3042 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3044 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3045 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3046 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3047 /* Mic2 (as headphone out) for HP output */
3048 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3049 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3050 /* Internal Speaker */
3051 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3052 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3054 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3055 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3057 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3061 /* toggle speaker-output according to the hp-jack state */
3062 static void alc880_medion_rim_automute(struct hda_codec *codec)
3064 struct alc_spec *spec = codec->spec;
3065 alc_automute_amp(codec);
3066 /* toggle EAPD */
3067 if (spec->jack_present)
3068 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3069 else
3070 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3073 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3074 unsigned int res)
3076 /* Looks like the unsol event is incompatible with the standard
3077 * definition. 4bit tag is placed at 28 bit!
3079 if ((res >> 28) == ALC880_HP_EVENT)
3080 alc880_medion_rim_automute(codec);
3083 static void alc880_medion_rim_init_hook(struct hda_codec *codec)
3085 struct alc_spec *spec = codec->spec;
3087 spec->autocfg.hp_pins[0] = 0x14;
3088 spec->autocfg.speaker_pins[0] = 0x1b;
3089 alc880_medion_rim_automute(codec);
3092 #ifdef CONFIG_SND_HDA_POWER_SAVE
3093 static struct hda_amp_list alc880_loopbacks[] = {
3094 { 0x0b, HDA_INPUT, 0 },
3095 { 0x0b, HDA_INPUT, 1 },
3096 { 0x0b, HDA_INPUT, 2 },
3097 { 0x0b, HDA_INPUT, 3 },
3098 { 0x0b, HDA_INPUT, 4 },
3099 { } /* end */
3102 static struct hda_amp_list alc880_lg_loopbacks[] = {
3103 { 0x0b, HDA_INPUT, 1 },
3104 { 0x0b, HDA_INPUT, 6 },
3105 { 0x0b, HDA_INPUT, 7 },
3106 { } /* end */
3108 #endif
3111 * Common callbacks
3114 static int alc_init(struct hda_codec *codec)
3116 struct alc_spec *spec = codec->spec;
3117 unsigned int i;
3119 alc_fix_pll(codec);
3120 alc_auto_init_amp(codec, spec->init_amp);
3122 for (i = 0; i < spec->num_init_verbs; i++)
3123 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3125 if (spec->init_hook)
3126 spec->init_hook(codec);
3128 return 0;
3131 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3133 struct alc_spec *spec = codec->spec;
3135 if (spec->unsol_event)
3136 spec->unsol_event(codec, res);
3139 #ifdef CONFIG_SND_HDA_POWER_SAVE
3140 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3142 struct alc_spec *spec = codec->spec;
3143 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3145 #endif
3148 * Analog playback callbacks
3150 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3151 struct hda_codec *codec,
3152 struct snd_pcm_substream *substream)
3154 struct alc_spec *spec = codec->spec;
3155 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3156 hinfo);
3159 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3160 struct hda_codec *codec,
3161 unsigned int stream_tag,
3162 unsigned int format,
3163 struct snd_pcm_substream *substream)
3165 struct alc_spec *spec = codec->spec;
3166 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3167 stream_tag, format, substream);
3170 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3171 struct hda_codec *codec,
3172 struct snd_pcm_substream *substream)
3174 struct alc_spec *spec = codec->spec;
3175 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3179 * Digital out
3181 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3182 struct hda_codec *codec,
3183 struct snd_pcm_substream *substream)
3185 struct alc_spec *spec = codec->spec;
3186 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3189 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3190 struct hda_codec *codec,
3191 unsigned int stream_tag,
3192 unsigned int format,
3193 struct snd_pcm_substream *substream)
3195 struct alc_spec *spec = codec->spec;
3196 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3197 stream_tag, format, substream);
3200 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3201 struct hda_codec *codec,
3202 struct snd_pcm_substream *substream)
3204 struct alc_spec *spec = codec->spec;
3205 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3208 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3209 struct hda_codec *codec,
3210 struct snd_pcm_substream *substream)
3212 struct alc_spec *spec = codec->spec;
3213 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3217 * Analog capture
3219 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3220 struct hda_codec *codec,
3221 unsigned int stream_tag,
3222 unsigned int format,
3223 struct snd_pcm_substream *substream)
3225 struct alc_spec *spec = codec->spec;
3227 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3228 stream_tag, 0, format);
3229 return 0;
3232 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3233 struct hda_codec *codec,
3234 struct snd_pcm_substream *substream)
3236 struct alc_spec *spec = codec->spec;
3238 snd_hda_codec_cleanup_stream(codec,
3239 spec->adc_nids[substream->number + 1]);
3240 return 0;
3246 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3247 .substreams = 1,
3248 .channels_min = 2,
3249 .channels_max = 8,
3250 /* NID is set in alc_build_pcms */
3251 .ops = {
3252 .open = alc880_playback_pcm_open,
3253 .prepare = alc880_playback_pcm_prepare,
3254 .cleanup = alc880_playback_pcm_cleanup
3258 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3259 .substreams = 1,
3260 .channels_min = 2,
3261 .channels_max = 2,
3262 /* NID is set in alc_build_pcms */
3265 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3266 .substreams = 1,
3267 .channels_min = 2,
3268 .channels_max = 2,
3269 /* NID is set in alc_build_pcms */
3272 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3273 .substreams = 2, /* can be overridden */
3274 .channels_min = 2,
3275 .channels_max = 2,
3276 /* NID is set in alc_build_pcms */
3277 .ops = {
3278 .prepare = alc880_alt_capture_pcm_prepare,
3279 .cleanup = alc880_alt_capture_pcm_cleanup
3283 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3284 .substreams = 1,
3285 .channels_min = 2,
3286 .channels_max = 2,
3287 /* NID is set in alc_build_pcms */
3288 .ops = {
3289 .open = alc880_dig_playback_pcm_open,
3290 .close = alc880_dig_playback_pcm_close,
3291 .prepare = alc880_dig_playback_pcm_prepare,
3292 .cleanup = alc880_dig_playback_pcm_cleanup
3296 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3297 .substreams = 1,
3298 .channels_min = 2,
3299 .channels_max = 2,
3300 /* NID is set in alc_build_pcms */
3303 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3304 static struct hda_pcm_stream alc_pcm_null_stream = {
3305 .substreams = 0,
3306 .channels_min = 0,
3307 .channels_max = 0,
3310 static int alc_build_pcms(struct hda_codec *codec)
3312 struct alc_spec *spec = codec->spec;
3313 struct hda_pcm *info = spec->pcm_rec;
3314 int i;
3316 codec->num_pcms = 1;
3317 codec->pcm_info = info;
3319 if (spec->no_analog)
3320 goto skip_analog;
3322 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3323 "%s Analog", codec->chip_name);
3324 info->name = spec->stream_name_analog;
3326 if (spec->stream_analog_playback) {
3327 if (snd_BUG_ON(!spec->multiout.dac_nids))
3328 return -EINVAL;
3329 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3330 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3332 if (spec->stream_analog_capture) {
3333 if (snd_BUG_ON(!spec->adc_nids))
3334 return -EINVAL;
3335 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3336 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3339 if (spec->channel_mode) {
3340 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3341 for (i = 0; i < spec->num_channel_mode; i++) {
3342 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3343 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3348 skip_analog:
3349 /* SPDIF for stream index #1 */
3350 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3351 snprintf(spec->stream_name_digital,
3352 sizeof(spec->stream_name_digital),
3353 "%s Digital", codec->chip_name);
3354 codec->num_pcms = 2;
3355 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3356 info = spec->pcm_rec + 1;
3357 info->name = spec->stream_name_digital;
3358 if (spec->dig_out_type)
3359 info->pcm_type = spec->dig_out_type;
3360 else
3361 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3362 if (spec->multiout.dig_out_nid &&
3363 spec->stream_digital_playback) {
3364 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3365 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3367 if (spec->dig_in_nid &&
3368 spec->stream_digital_capture) {
3369 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3370 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3372 /* FIXME: do we need this for all Realtek codec models? */
3373 codec->spdif_status_reset = 1;
3376 if (spec->no_analog)
3377 return 0;
3379 /* If the use of more than one ADC is requested for the current
3380 * model, configure a second analog capture-only PCM.
3382 /* Additional Analaog capture for index #2 */
3383 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3384 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3385 codec->num_pcms = 3;
3386 info = spec->pcm_rec + 2;
3387 info->name = spec->stream_name_analog;
3388 if (spec->alt_dac_nid) {
3389 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3390 *spec->stream_analog_alt_playback;
3391 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3392 spec->alt_dac_nid;
3393 } else {
3394 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3395 alc_pcm_null_stream;
3396 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3398 if (spec->num_adc_nids > 1) {
3399 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3400 *spec->stream_analog_alt_capture;
3401 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3402 spec->adc_nids[1];
3403 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3404 spec->num_adc_nids - 1;
3405 } else {
3406 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3407 alc_pcm_null_stream;
3408 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3412 return 0;
3415 static void alc_free_kctls(struct hda_codec *codec)
3417 struct alc_spec *spec = codec->spec;
3419 if (spec->kctls.list) {
3420 struct snd_kcontrol_new *kctl = spec->kctls.list;
3421 int i;
3422 for (i = 0; i < spec->kctls.used; i++)
3423 kfree(kctl[i].name);
3425 snd_array_free(&spec->kctls);
3428 static void alc_free(struct hda_codec *codec)
3430 struct alc_spec *spec = codec->spec;
3432 if (!spec)
3433 return;
3435 alc_free_kctls(codec);
3436 kfree(spec);
3437 snd_hda_detach_beep_device(codec);
3440 #ifdef SND_HDA_NEEDS_RESUME
3441 static int alc_resume(struct hda_codec *codec)
3443 codec->patch_ops.init(codec);
3444 snd_hda_codec_resume_amp(codec);
3445 snd_hda_codec_resume_cache(codec);
3446 return 0;
3448 #endif
3452 static struct hda_codec_ops alc_patch_ops = {
3453 .build_controls = alc_build_controls,
3454 .build_pcms = alc_build_pcms,
3455 .init = alc_init,
3456 .free = alc_free,
3457 .unsol_event = alc_unsol_event,
3458 #ifdef SND_HDA_NEEDS_RESUME
3459 .resume = alc_resume,
3460 #endif
3461 #ifdef CONFIG_SND_HDA_POWER_SAVE
3462 .check_power_status = alc_check_power_status,
3463 #endif
3468 * Test configuration for debugging
3470 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3471 * enum controls.
3473 #ifdef CONFIG_SND_DEBUG
3474 static hda_nid_t alc880_test_dac_nids[4] = {
3475 0x02, 0x03, 0x04, 0x05
3478 static struct hda_input_mux alc880_test_capture_source = {
3479 .num_items = 7,
3480 .items = {
3481 { "In-1", 0x0 },
3482 { "In-2", 0x1 },
3483 { "In-3", 0x2 },
3484 { "In-4", 0x3 },
3485 { "CD", 0x4 },
3486 { "Front", 0x5 },
3487 { "Surround", 0x6 },
3491 static struct hda_channel_mode alc880_test_modes[4] = {
3492 { 2, NULL },
3493 { 4, NULL },
3494 { 6, NULL },
3495 { 8, NULL },
3498 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3499 struct snd_ctl_elem_info *uinfo)
3501 static char *texts[] = {
3502 "N/A", "Line Out", "HP Out",
3503 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3505 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3506 uinfo->count = 1;
3507 uinfo->value.enumerated.items = 8;
3508 if (uinfo->value.enumerated.item >= 8)
3509 uinfo->value.enumerated.item = 7;
3510 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3511 return 0;
3514 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3515 struct snd_ctl_elem_value *ucontrol)
3517 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3518 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3519 unsigned int pin_ctl, item = 0;
3521 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3522 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3523 if (pin_ctl & AC_PINCTL_OUT_EN) {
3524 if (pin_ctl & AC_PINCTL_HP_EN)
3525 item = 2;
3526 else
3527 item = 1;
3528 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3529 switch (pin_ctl & AC_PINCTL_VREFEN) {
3530 case AC_PINCTL_VREF_HIZ: item = 3; break;
3531 case AC_PINCTL_VREF_50: item = 4; break;
3532 case AC_PINCTL_VREF_GRD: item = 5; break;
3533 case AC_PINCTL_VREF_80: item = 6; break;
3534 case AC_PINCTL_VREF_100: item = 7; break;
3537 ucontrol->value.enumerated.item[0] = item;
3538 return 0;
3541 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3542 struct snd_ctl_elem_value *ucontrol)
3544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3545 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3546 static unsigned int ctls[] = {
3547 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3548 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3549 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3550 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3551 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3552 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3554 unsigned int old_ctl, new_ctl;
3556 old_ctl = snd_hda_codec_read(codec, nid, 0,
3557 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3558 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3559 if (old_ctl != new_ctl) {
3560 int val;
3561 snd_hda_codec_write_cache(codec, nid, 0,
3562 AC_VERB_SET_PIN_WIDGET_CONTROL,
3563 new_ctl);
3564 val = ucontrol->value.enumerated.item[0] >= 3 ?
3565 HDA_AMP_MUTE : 0;
3566 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3567 HDA_AMP_MUTE, val);
3568 return 1;
3570 return 0;
3573 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3574 struct snd_ctl_elem_info *uinfo)
3576 static char *texts[] = {
3577 "Front", "Surround", "CLFE", "Side"
3579 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3580 uinfo->count = 1;
3581 uinfo->value.enumerated.items = 4;
3582 if (uinfo->value.enumerated.item >= 4)
3583 uinfo->value.enumerated.item = 3;
3584 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3585 return 0;
3588 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3589 struct snd_ctl_elem_value *ucontrol)
3591 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3592 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3593 unsigned int sel;
3595 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3596 ucontrol->value.enumerated.item[0] = sel & 3;
3597 return 0;
3600 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3601 struct snd_ctl_elem_value *ucontrol)
3603 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3604 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3605 unsigned int sel;
3607 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3608 if (ucontrol->value.enumerated.item[0] != sel) {
3609 sel = ucontrol->value.enumerated.item[0] & 3;
3610 snd_hda_codec_write_cache(codec, nid, 0,
3611 AC_VERB_SET_CONNECT_SEL, sel);
3612 return 1;
3614 return 0;
3617 #define PIN_CTL_TEST(xname,nid) { \
3618 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3619 .name = xname, \
3620 .info = alc_test_pin_ctl_info, \
3621 .get = alc_test_pin_ctl_get, \
3622 .put = alc_test_pin_ctl_put, \
3623 .private_value = nid \
3626 #define PIN_SRC_TEST(xname,nid) { \
3627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3628 .name = xname, \
3629 .info = alc_test_pin_src_info, \
3630 .get = alc_test_pin_src_get, \
3631 .put = alc_test_pin_src_put, \
3632 .private_value = nid \
3635 static struct snd_kcontrol_new alc880_test_mixer[] = {
3636 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3637 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3638 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3639 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3640 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3641 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3642 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3643 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3644 PIN_CTL_TEST("Front Pin Mode", 0x14),
3645 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3646 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3647 PIN_CTL_TEST("Side Pin Mode", 0x17),
3648 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3649 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3650 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3651 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3652 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3653 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3654 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3655 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3656 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3657 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3658 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3659 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3660 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3661 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3662 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3663 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3664 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3665 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3667 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3668 .name = "Channel Mode",
3669 .info = alc_ch_mode_info,
3670 .get = alc_ch_mode_get,
3671 .put = alc_ch_mode_put,
3673 { } /* end */
3676 static struct hda_verb alc880_test_init_verbs[] = {
3677 /* Unmute inputs of 0x0c - 0x0f */
3678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3680 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3686 /* Vol output for 0x0c-0x0f */
3687 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3688 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3690 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3691 /* Set output pins 0x14-0x17 */
3692 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3694 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3695 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3696 /* Unmute output pins 0x14-0x17 */
3697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3698 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3700 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3701 /* Set input pins 0x18-0x1c */
3702 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3704 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3705 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3706 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3707 /* Mute input pins 0x18-0x1b */
3708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3709 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3710 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3711 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3712 /* ADC set up */
3713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3714 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3716 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3717 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3718 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3719 /* Analog input/passthru */
3720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3727 #endif
3732 static const char *alc880_models[ALC880_MODEL_LAST] = {
3733 [ALC880_3ST] = "3stack",
3734 [ALC880_TCL_S700] = "tcl",
3735 [ALC880_3ST_DIG] = "3stack-digout",
3736 [ALC880_CLEVO] = "clevo",
3737 [ALC880_5ST] = "5stack",
3738 [ALC880_5ST_DIG] = "5stack-digout",
3739 [ALC880_W810] = "w810",
3740 [ALC880_Z71V] = "z71v",
3741 [ALC880_6ST] = "6stack",
3742 [ALC880_6ST_DIG] = "6stack-digout",
3743 [ALC880_ASUS] = "asus",
3744 [ALC880_ASUS_W1V] = "asus-w1v",
3745 [ALC880_ASUS_DIG] = "asus-dig",
3746 [ALC880_ASUS_DIG2] = "asus-dig2",
3747 [ALC880_UNIWILL_DIG] = "uniwill",
3748 [ALC880_UNIWILL_P53] = "uniwill-p53",
3749 [ALC880_FUJITSU] = "fujitsu",
3750 [ALC880_F1734] = "F1734",
3751 [ALC880_LG] = "lg",
3752 [ALC880_LG_LW] = "lg-lw",
3753 [ALC880_MEDION_RIM] = "medion",
3754 #ifdef CONFIG_SND_DEBUG
3755 [ALC880_TEST] = "test",
3756 #endif
3757 [ALC880_AUTO] = "auto",
3760 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3761 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3762 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3763 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3764 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3765 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3766 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3767 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3768 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3769 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3770 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3771 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3772 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3773 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3774 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3775 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3776 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3777 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3778 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3779 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3780 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3781 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3782 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3783 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3784 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3785 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3786 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
3787 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3788 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3789 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3790 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3791 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3792 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3793 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3794 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3795 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3796 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3797 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3798 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3799 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3800 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3801 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3802 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3803 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3804 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3805 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3806 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3807 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3808 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3809 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3810 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3811 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3812 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3813 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3814 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3815 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3816 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3817 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3818 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3819 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3820 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3821 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3822 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3823 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3824 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3825 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3826 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3827 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3828 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3829 /* default Intel */
3830 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
3831 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3832 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3837 * ALC880 codec presets
3839 static struct alc_config_preset alc880_presets[] = {
3840 [ALC880_3ST] = {
3841 .mixers = { alc880_three_stack_mixer },
3842 .init_verbs = { alc880_volume_init_verbs,
3843 alc880_pin_3stack_init_verbs },
3844 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3845 .dac_nids = alc880_dac_nids,
3846 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3847 .channel_mode = alc880_threestack_modes,
3848 .need_dac_fix = 1,
3849 .input_mux = &alc880_capture_source,
3851 [ALC880_3ST_DIG] = {
3852 .mixers = { alc880_three_stack_mixer },
3853 .init_verbs = { alc880_volume_init_verbs,
3854 alc880_pin_3stack_init_verbs },
3855 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3856 .dac_nids = alc880_dac_nids,
3857 .dig_out_nid = ALC880_DIGOUT_NID,
3858 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3859 .channel_mode = alc880_threestack_modes,
3860 .need_dac_fix = 1,
3861 .input_mux = &alc880_capture_source,
3863 [ALC880_TCL_S700] = {
3864 .mixers = { alc880_tcl_s700_mixer },
3865 .init_verbs = { alc880_volume_init_verbs,
3866 alc880_pin_tcl_S700_init_verbs,
3867 alc880_gpio2_init_verbs },
3868 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3869 .dac_nids = alc880_dac_nids,
3870 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3871 .num_adc_nids = 1, /* single ADC */
3872 .hp_nid = 0x03,
3873 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3874 .channel_mode = alc880_2_jack_modes,
3875 .input_mux = &alc880_capture_source,
3877 [ALC880_5ST] = {
3878 .mixers = { alc880_three_stack_mixer,
3879 alc880_five_stack_mixer},
3880 .init_verbs = { alc880_volume_init_verbs,
3881 alc880_pin_5stack_init_verbs },
3882 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3883 .dac_nids = alc880_dac_nids,
3884 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3885 .channel_mode = alc880_fivestack_modes,
3886 .input_mux = &alc880_capture_source,
3888 [ALC880_5ST_DIG] = {
3889 .mixers = { alc880_three_stack_mixer,
3890 alc880_five_stack_mixer },
3891 .init_verbs = { alc880_volume_init_verbs,
3892 alc880_pin_5stack_init_verbs },
3893 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3894 .dac_nids = alc880_dac_nids,
3895 .dig_out_nid = ALC880_DIGOUT_NID,
3896 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3897 .channel_mode = alc880_fivestack_modes,
3898 .input_mux = &alc880_capture_source,
3900 [ALC880_6ST] = {
3901 .mixers = { alc880_six_stack_mixer },
3902 .init_verbs = { alc880_volume_init_verbs,
3903 alc880_pin_6stack_init_verbs },
3904 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3905 .dac_nids = alc880_6st_dac_nids,
3906 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3907 .channel_mode = alc880_sixstack_modes,
3908 .input_mux = &alc880_6stack_capture_source,
3910 [ALC880_6ST_DIG] = {
3911 .mixers = { alc880_six_stack_mixer },
3912 .init_verbs = { alc880_volume_init_verbs,
3913 alc880_pin_6stack_init_verbs },
3914 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3915 .dac_nids = alc880_6st_dac_nids,
3916 .dig_out_nid = ALC880_DIGOUT_NID,
3917 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3918 .channel_mode = alc880_sixstack_modes,
3919 .input_mux = &alc880_6stack_capture_source,
3921 [ALC880_W810] = {
3922 .mixers = { alc880_w810_base_mixer },
3923 .init_verbs = { alc880_volume_init_verbs,
3924 alc880_pin_w810_init_verbs,
3925 alc880_gpio2_init_verbs },
3926 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3927 .dac_nids = alc880_w810_dac_nids,
3928 .dig_out_nid = ALC880_DIGOUT_NID,
3929 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3930 .channel_mode = alc880_w810_modes,
3931 .input_mux = &alc880_capture_source,
3933 [ALC880_Z71V] = {
3934 .mixers = { alc880_z71v_mixer },
3935 .init_verbs = { alc880_volume_init_verbs,
3936 alc880_pin_z71v_init_verbs },
3937 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3938 .dac_nids = alc880_z71v_dac_nids,
3939 .dig_out_nid = ALC880_DIGOUT_NID,
3940 .hp_nid = 0x03,
3941 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3942 .channel_mode = alc880_2_jack_modes,
3943 .input_mux = &alc880_capture_source,
3945 [ALC880_F1734] = {
3946 .mixers = { alc880_f1734_mixer },
3947 .init_verbs = { alc880_volume_init_verbs,
3948 alc880_pin_f1734_init_verbs },
3949 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3950 .dac_nids = alc880_f1734_dac_nids,
3951 .hp_nid = 0x02,
3952 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3953 .channel_mode = alc880_2_jack_modes,
3954 .input_mux = &alc880_f1734_capture_source,
3955 .unsol_event = alc880_uniwill_p53_unsol_event,
3956 .init_hook = alc880_uniwill_p53_init_hook,
3958 [ALC880_ASUS] = {
3959 .mixers = { alc880_asus_mixer },
3960 .init_verbs = { alc880_volume_init_verbs,
3961 alc880_pin_asus_init_verbs,
3962 alc880_gpio1_init_verbs },
3963 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3964 .dac_nids = alc880_asus_dac_nids,
3965 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3966 .channel_mode = alc880_asus_modes,
3967 .need_dac_fix = 1,
3968 .input_mux = &alc880_capture_source,
3970 [ALC880_ASUS_DIG] = {
3971 .mixers = { alc880_asus_mixer },
3972 .init_verbs = { alc880_volume_init_verbs,
3973 alc880_pin_asus_init_verbs,
3974 alc880_gpio1_init_verbs },
3975 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3976 .dac_nids = alc880_asus_dac_nids,
3977 .dig_out_nid = ALC880_DIGOUT_NID,
3978 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3979 .channel_mode = alc880_asus_modes,
3980 .need_dac_fix = 1,
3981 .input_mux = &alc880_capture_source,
3983 [ALC880_ASUS_DIG2] = {
3984 .mixers = { alc880_asus_mixer },
3985 .init_verbs = { alc880_volume_init_verbs,
3986 alc880_pin_asus_init_verbs,
3987 alc880_gpio2_init_verbs }, /* use GPIO2 */
3988 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3989 .dac_nids = alc880_asus_dac_nids,
3990 .dig_out_nid = ALC880_DIGOUT_NID,
3991 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3992 .channel_mode = alc880_asus_modes,
3993 .need_dac_fix = 1,
3994 .input_mux = &alc880_capture_source,
3996 [ALC880_ASUS_W1V] = {
3997 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3998 .init_verbs = { alc880_volume_init_verbs,
3999 alc880_pin_asus_init_verbs,
4000 alc880_gpio1_init_verbs },
4001 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4002 .dac_nids = alc880_asus_dac_nids,
4003 .dig_out_nid = ALC880_DIGOUT_NID,
4004 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4005 .channel_mode = alc880_asus_modes,
4006 .need_dac_fix = 1,
4007 .input_mux = &alc880_capture_source,
4009 [ALC880_UNIWILL_DIG] = {
4010 .mixers = { alc880_asus_mixer },
4011 .init_verbs = { alc880_volume_init_verbs,
4012 alc880_pin_asus_init_verbs },
4013 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4014 .dac_nids = alc880_asus_dac_nids,
4015 .dig_out_nid = ALC880_DIGOUT_NID,
4016 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4017 .channel_mode = alc880_asus_modes,
4018 .need_dac_fix = 1,
4019 .input_mux = &alc880_capture_source,
4021 [ALC880_UNIWILL] = {
4022 .mixers = { alc880_uniwill_mixer },
4023 .init_verbs = { alc880_volume_init_verbs,
4024 alc880_uniwill_init_verbs },
4025 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4026 .dac_nids = alc880_asus_dac_nids,
4027 .dig_out_nid = ALC880_DIGOUT_NID,
4028 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4029 .channel_mode = alc880_threestack_modes,
4030 .need_dac_fix = 1,
4031 .input_mux = &alc880_capture_source,
4032 .unsol_event = alc880_uniwill_unsol_event,
4033 .init_hook = alc880_uniwill_init_hook,
4035 [ALC880_UNIWILL_P53] = {
4036 .mixers = { alc880_uniwill_p53_mixer },
4037 .init_verbs = { alc880_volume_init_verbs,
4038 alc880_uniwill_p53_init_verbs },
4039 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4040 .dac_nids = alc880_asus_dac_nids,
4041 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4042 .channel_mode = alc880_threestack_modes,
4043 .input_mux = &alc880_capture_source,
4044 .unsol_event = alc880_uniwill_p53_unsol_event,
4045 .init_hook = alc880_uniwill_p53_init_hook,
4047 [ALC880_FUJITSU] = {
4048 .mixers = { alc880_fujitsu_mixer },
4049 .init_verbs = { alc880_volume_init_verbs,
4050 alc880_uniwill_p53_init_verbs,
4051 alc880_beep_init_verbs },
4052 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4053 .dac_nids = alc880_dac_nids,
4054 .dig_out_nid = ALC880_DIGOUT_NID,
4055 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4056 .channel_mode = alc880_2_jack_modes,
4057 .input_mux = &alc880_capture_source,
4058 .unsol_event = alc880_uniwill_p53_unsol_event,
4059 .init_hook = alc880_uniwill_p53_init_hook,
4061 [ALC880_CLEVO] = {
4062 .mixers = { alc880_three_stack_mixer },
4063 .init_verbs = { alc880_volume_init_verbs,
4064 alc880_pin_clevo_init_verbs },
4065 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4066 .dac_nids = alc880_dac_nids,
4067 .hp_nid = 0x03,
4068 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4069 .channel_mode = alc880_threestack_modes,
4070 .need_dac_fix = 1,
4071 .input_mux = &alc880_capture_source,
4073 [ALC880_LG] = {
4074 .mixers = { alc880_lg_mixer },
4075 .init_verbs = { alc880_volume_init_verbs,
4076 alc880_lg_init_verbs },
4077 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4078 .dac_nids = alc880_lg_dac_nids,
4079 .dig_out_nid = ALC880_DIGOUT_NID,
4080 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4081 .channel_mode = alc880_lg_ch_modes,
4082 .need_dac_fix = 1,
4083 .input_mux = &alc880_lg_capture_source,
4084 .unsol_event = alc_automute_amp_unsol_event,
4085 .init_hook = alc880_lg_init_hook,
4086 #ifdef CONFIG_SND_HDA_POWER_SAVE
4087 .loopbacks = alc880_lg_loopbacks,
4088 #endif
4090 [ALC880_LG_LW] = {
4091 .mixers = { alc880_lg_lw_mixer },
4092 .init_verbs = { alc880_volume_init_verbs,
4093 alc880_lg_lw_init_verbs },
4094 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4095 .dac_nids = alc880_dac_nids,
4096 .dig_out_nid = ALC880_DIGOUT_NID,
4097 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4098 .channel_mode = alc880_lg_lw_modes,
4099 .input_mux = &alc880_lg_lw_capture_source,
4100 .unsol_event = alc_automute_amp_unsol_event,
4101 .init_hook = alc880_lg_lw_init_hook,
4103 [ALC880_MEDION_RIM] = {
4104 .mixers = { alc880_medion_rim_mixer },
4105 .init_verbs = { alc880_volume_init_verbs,
4106 alc880_medion_rim_init_verbs,
4107 alc_gpio2_init_verbs },
4108 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4109 .dac_nids = alc880_dac_nids,
4110 .dig_out_nid = ALC880_DIGOUT_NID,
4111 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4112 .channel_mode = alc880_2_jack_modes,
4113 .input_mux = &alc880_medion_rim_capture_source,
4114 .unsol_event = alc880_medion_rim_unsol_event,
4115 .init_hook = alc880_medion_rim_init_hook,
4117 #ifdef CONFIG_SND_DEBUG
4118 [ALC880_TEST] = {
4119 .mixers = { alc880_test_mixer },
4120 .init_verbs = { alc880_test_init_verbs },
4121 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4122 .dac_nids = alc880_test_dac_nids,
4123 .dig_out_nid = ALC880_DIGOUT_NID,
4124 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4125 .channel_mode = alc880_test_modes,
4126 .input_mux = &alc880_test_capture_source,
4128 #endif
4132 * Automatic parse of I/O pins from the BIOS configuration
4135 enum {
4136 ALC_CTL_WIDGET_VOL,
4137 ALC_CTL_WIDGET_MUTE,
4138 ALC_CTL_BIND_MUTE,
4140 static struct snd_kcontrol_new alc880_control_templates[] = {
4141 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4142 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4143 HDA_BIND_MUTE(NULL, 0, 0, 0),
4146 /* add dynamic controls */
4147 static int add_control(struct alc_spec *spec, int type, const char *name,
4148 unsigned long val)
4150 struct snd_kcontrol_new *knew;
4152 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4153 knew = snd_array_new(&spec->kctls);
4154 if (!knew)
4155 return -ENOMEM;
4156 *knew = alc880_control_templates[type];
4157 knew->name = kstrdup(name, GFP_KERNEL);
4158 if (!knew->name)
4159 return -ENOMEM;
4160 knew->private_value = val;
4161 return 0;
4164 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4165 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4166 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4167 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4168 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
4169 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
4170 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4171 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4172 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4173 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4174 #define ALC880_PIN_CD_NID 0x1c
4176 /* fill in the dac_nids table from the parsed pin configuration */
4177 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4178 const struct auto_pin_cfg *cfg)
4180 hda_nid_t nid;
4181 int assigned[4];
4182 int i, j;
4184 memset(assigned, 0, sizeof(assigned));
4185 spec->multiout.dac_nids = spec->private_dac_nids;
4187 /* check the pins hardwired to audio widget */
4188 for (i = 0; i < cfg->line_outs; i++) {
4189 nid = cfg->line_out_pins[i];
4190 if (alc880_is_fixed_pin(nid)) {
4191 int idx = alc880_fixed_pin_idx(nid);
4192 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4193 assigned[idx] = 1;
4196 /* left pins can be connect to any audio widget */
4197 for (i = 0; i < cfg->line_outs; i++) {
4198 nid = cfg->line_out_pins[i];
4199 if (alc880_is_fixed_pin(nid))
4200 continue;
4201 /* search for an empty channel */
4202 for (j = 0; j < cfg->line_outs; j++) {
4203 if (!assigned[j]) {
4204 spec->multiout.dac_nids[i] =
4205 alc880_idx_to_dac(j);
4206 assigned[j] = 1;
4207 break;
4211 spec->multiout.num_dacs = cfg->line_outs;
4212 return 0;
4215 /* add playback controls from the parsed DAC table */
4216 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4217 const struct auto_pin_cfg *cfg)
4219 char name[32];
4220 static const char *chname[4] = {
4221 "Front", "Surround", NULL /*CLFE*/, "Side"
4223 hda_nid_t nid;
4224 int i, err;
4226 for (i = 0; i < cfg->line_outs; i++) {
4227 if (!spec->multiout.dac_nids[i])
4228 continue;
4229 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4230 if (i == 2) {
4231 /* Center/LFE */
4232 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4233 "Center Playback Volume",
4234 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4235 HDA_OUTPUT));
4236 if (err < 0)
4237 return err;
4238 err = add_control(spec, ALC_CTL_WIDGET_VOL,
4239 "LFE Playback Volume",
4240 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4241 HDA_OUTPUT));
4242 if (err < 0)
4243 return err;
4244 err = add_control(spec, ALC_CTL_BIND_MUTE,
4245 "Center Playback Switch",
4246 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4247 HDA_INPUT));
4248 if (err < 0)
4249 return err;
4250 err = add_control(spec, ALC_CTL_BIND_MUTE,
4251 "LFE Playback Switch",
4252 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4253 HDA_INPUT));
4254 if (err < 0)
4255 return err;
4256 } else {
4257 sprintf(name, "%s Playback Volume", chname[i]);
4258 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4259 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4260 HDA_OUTPUT));
4261 if (err < 0)
4262 return err;
4263 sprintf(name, "%s Playback Switch", chname[i]);
4264 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4265 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4266 HDA_INPUT));
4267 if (err < 0)
4268 return err;
4271 return 0;
4274 /* add playback controls for speaker and HP outputs */
4275 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4276 const char *pfx)
4278 hda_nid_t nid;
4279 int err;
4280 char name[32];
4282 if (!pin)
4283 return 0;
4285 if (alc880_is_fixed_pin(pin)) {
4286 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4287 /* specify the DAC as the extra output */
4288 if (!spec->multiout.hp_nid)
4289 spec->multiout.hp_nid = nid;
4290 else
4291 spec->multiout.extra_out_nid[0] = nid;
4292 /* control HP volume/switch on the output mixer amp */
4293 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4294 sprintf(name, "%s Playback Volume", pfx);
4295 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4296 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4297 if (err < 0)
4298 return err;
4299 sprintf(name, "%s Playback Switch", pfx);
4300 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4301 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4302 if (err < 0)
4303 return err;
4304 } else if (alc880_is_multi_pin(pin)) {
4305 /* set manual connection */
4306 /* we have only a switch on HP-out PIN */
4307 sprintf(name, "%s Playback Switch", pfx);
4308 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4309 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4310 if (err < 0)
4311 return err;
4313 return 0;
4316 /* create input playback/capture controls for the given pin */
4317 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4318 const char *ctlname,
4319 int idx, hda_nid_t mix_nid)
4321 char name[32];
4322 int err;
4324 sprintf(name, "%s Playback Volume", ctlname);
4325 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4326 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4327 if (err < 0)
4328 return err;
4329 sprintf(name, "%s Playback Switch", ctlname);
4330 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
4331 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4332 if (err < 0)
4333 return err;
4334 return 0;
4337 /* create playback/capture controls for input pins */
4338 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
4339 const struct auto_pin_cfg *cfg)
4341 struct hda_input_mux *imux = &spec->private_imux[0];
4342 int i, err, idx;
4344 for (i = 0; i < AUTO_PIN_LAST; i++) {
4345 if (alc880_is_input_pin(cfg->input_pins[i])) {
4346 idx = alc880_input_pin_idx(cfg->input_pins[i]);
4347 err = new_analog_input(spec, cfg->input_pins[i],
4348 auto_pin_cfg_labels[i],
4349 idx, 0x0b);
4350 if (err < 0)
4351 return err;
4352 imux->items[imux->num_items].label =
4353 auto_pin_cfg_labels[i];
4354 imux->items[imux->num_items].index =
4355 alc880_input_pin_idx(cfg->input_pins[i]);
4356 imux->num_items++;
4359 return 0;
4362 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4363 unsigned int pin_type)
4365 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4366 pin_type);
4367 /* unmute pin */
4368 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4369 AMP_OUT_UNMUTE);
4372 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4373 hda_nid_t nid, int pin_type,
4374 int dac_idx)
4376 alc_set_pin_output(codec, nid, pin_type);
4377 /* need the manual connection? */
4378 if (alc880_is_multi_pin(nid)) {
4379 struct alc_spec *spec = codec->spec;
4380 int idx = alc880_multi_pin_idx(nid);
4381 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4382 AC_VERB_SET_CONNECT_SEL,
4383 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4387 static int get_pin_type(int line_out_type)
4389 if (line_out_type == AUTO_PIN_HP_OUT)
4390 return PIN_HP;
4391 else
4392 return PIN_OUT;
4395 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4397 struct alc_spec *spec = codec->spec;
4398 int i;
4400 for (i = 0; i < spec->autocfg.line_outs; i++) {
4401 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4402 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4403 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4407 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4409 struct alc_spec *spec = codec->spec;
4410 hda_nid_t pin;
4412 pin = spec->autocfg.speaker_pins[0];
4413 if (pin) /* connect to front */
4414 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4415 pin = spec->autocfg.hp_pins[0];
4416 if (pin) /* connect to front */
4417 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4420 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4422 struct alc_spec *spec = codec->spec;
4423 int i;
4425 for (i = 0; i < AUTO_PIN_LAST; i++) {
4426 hda_nid_t nid = spec->autocfg.input_pins[i];
4427 if (alc880_is_input_pin(nid)) {
4428 alc_set_input_pin(codec, nid, i);
4429 if (nid != ALC880_PIN_CD_NID &&
4430 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4431 snd_hda_codec_write(codec, nid, 0,
4432 AC_VERB_SET_AMP_GAIN_MUTE,
4433 AMP_OUT_MUTE);
4438 /* parse the BIOS configuration and set up the alc_spec */
4439 /* return 1 if successful, 0 if the proper config is not found,
4440 * or a negative error code
4442 static int alc880_parse_auto_config(struct hda_codec *codec)
4444 struct alc_spec *spec = codec->spec;
4445 int i, err;
4446 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4448 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4449 alc880_ignore);
4450 if (err < 0)
4451 return err;
4452 if (!spec->autocfg.line_outs)
4453 return 0; /* can't find valid BIOS pin config */
4455 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4456 if (err < 0)
4457 return err;
4458 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4459 if (err < 0)
4460 return err;
4461 err = alc880_auto_create_extra_out(spec,
4462 spec->autocfg.speaker_pins[0],
4463 "Speaker");
4464 if (err < 0)
4465 return err;
4466 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4467 "Headphone");
4468 if (err < 0)
4469 return err;
4470 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
4471 if (err < 0)
4472 return err;
4474 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4476 /* check multiple SPDIF-out (for recent codecs) */
4477 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4478 hda_nid_t dig_nid;
4479 err = snd_hda_get_connections(codec,
4480 spec->autocfg.dig_out_pins[i],
4481 &dig_nid, 1);
4482 if (err < 0)
4483 continue;
4484 if (!i)
4485 spec->multiout.dig_out_nid = dig_nid;
4486 else {
4487 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4488 spec->slave_dig_outs[i - 1] = dig_nid;
4489 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
4490 break;
4493 if (spec->autocfg.dig_in_pin)
4494 spec->dig_in_nid = ALC880_DIGIN_NID;
4496 if (spec->kctls.list)
4497 add_mixer(spec, spec->kctls.list);
4499 add_verb(spec, alc880_volume_init_verbs);
4501 spec->num_mux_defs = 1;
4502 spec->input_mux = &spec->private_imux[0];
4504 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4506 return 1;
4509 /* additional initialization for auto-configuration model */
4510 static void alc880_auto_init(struct hda_codec *codec)
4512 struct alc_spec *spec = codec->spec;
4513 alc880_auto_init_multi_out(codec);
4514 alc880_auto_init_extra_out(codec);
4515 alc880_auto_init_analog_input(codec);
4516 if (spec->unsol_event)
4517 alc_inithook(codec);
4520 static void set_capture_mixer(struct alc_spec *spec)
4522 static struct snd_kcontrol_new *caps[2][3] = {
4523 { alc_capture_mixer_nosrc1,
4524 alc_capture_mixer_nosrc2,
4525 alc_capture_mixer_nosrc3 },
4526 { alc_capture_mixer1,
4527 alc_capture_mixer2,
4528 alc_capture_mixer3 },
4530 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4531 int mux;
4532 if (spec->input_mux && spec->input_mux->num_items > 1)
4533 mux = 1;
4534 else
4535 mux = 0;
4536 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
4540 #define set_beep_amp(spec, nid, idx, dir) \
4541 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
4544 * OK, here we have finally the patch for ALC880
4547 static int patch_alc880(struct hda_codec *codec)
4549 struct alc_spec *spec;
4550 int board_config;
4551 int err;
4553 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4554 if (spec == NULL)
4555 return -ENOMEM;
4557 codec->spec = spec;
4559 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
4560 alc880_models,
4561 alc880_cfg_tbl);
4562 if (board_config < 0) {
4563 printk(KERN_INFO "hda_codec: Unknown model for %s, "
4564 "trying auto-probe from BIOS...\n", codec->chip_name);
4565 board_config = ALC880_AUTO;
4568 if (board_config == ALC880_AUTO) {
4569 /* automatic parse from the BIOS config */
4570 err = alc880_parse_auto_config(codec);
4571 if (err < 0) {
4572 alc_free(codec);
4573 return err;
4574 } else if (!err) {
4575 printk(KERN_INFO
4576 "hda_codec: Cannot set up configuration "
4577 "from BIOS. Using 3-stack mode...\n");
4578 board_config = ALC880_3ST;
4582 err = snd_hda_attach_beep_device(codec, 0x1);
4583 if (err < 0) {
4584 alc_free(codec);
4585 return err;
4588 if (board_config != ALC880_AUTO)
4589 setup_preset(spec, &alc880_presets[board_config]);
4591 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4592 spec->stream_analog_capture = &alc880_pcm_analog_capture;
4593 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
4595 spec->stream_digital_playback = &alc880_pcm_digital_playback;
4596 spec->stream_digital_capture = &alc880_pcm_digital_capture;
4598 if (!spec->adc_nids && spec->input_mux) {
4599 /* check whether NID 0x07 is valid */
4600 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4601 /* get type */
4602 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
4603 if (wcap != AC_WID_AUD_IN) {
4604 spec->adc_nids = alc880_adc_nids_alt;
4605 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
4606 } else {
4607 spec->adc_nids = alc880_adc_nids;
4608 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4611 set_capture_mixer(spec);
4612 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4614 spec->vmaster_nid = 0x0c;
4616 codec->patch_ops = alc_patch_ops;
4617 if (board_config == ALC880_AUTO)
4618 spec->init_hook = alc880_auto_init;
4619 #ifdef CONFIG_SND_HDA_POWER_SAVE
4620 if (!spec->loopback.amplist)
4621 spec->loopback.amplist = alc880_loopbacks;
4622 #endif
4623 codec->proc_widget_hook = print_realtek_coef;
4625 return 0;
4630 * ALC260 support
4633 static hda_nid_t alc260_dac_nids[1] = {
4634 /* front */
4635 0x02,
4638 static hda_nid_t alc260_adc_nids[1] = {
4639 /* ADC0 */
4640 0x04,
4643 static hda_nid_t alc260_adc_nids_alt[1] = {
4644 /* ADC1 */
4645 0x05,
4648 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4649 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4651 static hda_nid_t alc260_dual_adc_nids[2] = {
4652 /* ADC0, ADC1 */
4653 0x04, 0x05
4656 #define ALC260_DIGOUT_NID 0x03
4657 #define ALC260_DIGIN_NID 0x06
4659 static struct hda_input_mux alc260_capture_source = {
4660 .num_items = 4,
4661 .items = {
4662 { "Mic", 0x0 },
4663 { "Front Mic", 0x1 },
4664 { "Line", 0x2 },
4665 { "CD", 0x4 },
4669 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4670 * headphone jack and the internal CD lines since these are the only pins at
4671 * which audio can appear. For flexibility, also allow the option of
4672 * recording the mixer output on the second ADC (ADC0 doesn't have a
4673 * connection to the mixer output).
4675 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4677 .num_items = 3,
4678 .items = {
4679 { "Mic/Line", 0x0 },
4680 { "CD", 0x4 },
4681 { "Headphone", 0x2 },
4685 .num_items = 4,
4686 .items = {
4687 { "Mic/Line", 0x0 },
4688 { "CD", 0x4 },
4689 { "Headphone", 0x2 },
4690 { "Mixer", 0x5 },
4696 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4697 * the Fujitsu S702x, but jacks are marked differently.
4699 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4701 .num_items = 4,
4702 .items = {
4703 { "Mic", 0x0 },
4704 { "Line", 0x2 },
4705 { "CD", 0x4 },
4706 { "Headphone", 0x5 },
4710 .num_items = 5,
4711 .items = {
4712 { "Mic", 0x0 },
4713 { "Line", 0x2 },
4714 { "CD", 0x4 },
4715 { "Headphone", 0x6 },
4716 { "Mixer", 0x5 },
4721 /* Maxdata Favorit 100XS */
4722 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
4724 .num_items = 2,
4725 .items = {
4726 { "Line/Mic", 0x0 },
4727 { "CD", 0x4 },
4731 .num_items = 3,
4732 .items = {
4733 { "Line/Mic", 0x0 },
4734 { "CD", 0x4 },
4735 { "Mixer", 0x5 },
4741 * This is just place-holder, so there's something for alc_build_pcms to look
4742 * at when it calculates the maximum number of channels. ALC260 has no mixer
4743 * element which allows changing the channel mode, so the verb list is
4744 * never used.
4746 static struct hda_channel_mode alc260_modes[1] = {
4747 { 2, NULL },
4751 /* Mixer combinations
4753 * basic: base_output + input + pc_beep + capture
4754 * HP: base_output + input + capture_alt
4755 * HP_3013: hp_3013 + input + capture
4756 * fujitsu: fujitsu + capture
4757 * acer: acer + capture
4760 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4761 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4762 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4763 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4764 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4765 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4766 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4767 { } /* end */
4770 static struct snd_kcontrol_new alc260_input_mixer[] = {
4771 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4772 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4773 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4774 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4776 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4777 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4778 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4779 { } /* end */
4782 /* update HP, line and mono out pins according to the master switch */
4783 static void alc260_hp_master_update(struct hda_codec *codec,
4784 hda_nid_t hp, hda_nid_t line,
4785 hda_nid_t mono)
4787 struct alc_spec *spec = codec->spec;
4788 unsigned int val = spec->master_sw ? PIN_HP : 0;
4789 /* change HP and line-out pins */
4790 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4791 val);
4792 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4793 val);
4794 /* mono (speaker) depending on the HP jack sense */
4795 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4796 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4797 val);
4800 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4801 struct snd_ctl_elem_value *ucontrol)
4803 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4804 struct alc_spec *spec = codec->spec;
4805 *ucontrol->value.integer.value = spec->master_sw;
4806 return 0;
4809 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4810 struct snd_ctl_elem_value *ucontrol)
4812 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4813 struct alc_spec *spec = codec->spec;
4814 int val = !!*ucontrol->value.integer.value;
4815 hda_nid_t hp, line, mono;
4817 if (val == spec->master_sw)
4818 return 0;
4819 spec->master_sw = val;
4820 hp = (kcontrol->private_value >> 16) & 0xff;
4821 line = (kcontrol->private_value >> 8) & 0xff;
4822 mono = kcontrol->private_value & 0xff;
4823 alc260_hp_master_update(codec, hp, line, mono);
4824 return 1;
4827 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4830 .name = "Master Playback Switch",
4831 .info = snd_ctl_boolean_mono_info,
4832 .get = alc260_hp_master_sw_get,
4833 .put = alc260_hp_master_sw_put,
4834 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4836 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4837 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4838 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4839 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4840 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4841 HDA_OUTPUT),
4842 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4843 { } /* end */
4846 static struct hda_verb alc260_hp_unsol_verbs[] = {
4847 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4851 static void alc260_hp_automute(struct hda_codec *codec)
4853 struct alc_spec *spec = codec->spec;
4854 unsigned int present;
4856 present = snd_hda_codec_read(codec, 0x10, 0,
4857 AC_VERB_GET_PIN_SENSE, 0);
4858 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4859 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4862 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4864 if ((res >> 26) == ALC880_HP_EVENT)
4865 alc260_hp_automute(codec);
4868 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4871 .name = "Master Playback Switch",
4872 .info = snd_ctl_boolean_mono_info,
4873 .get = alc260_hp_master_sw_get,
4874 .put = alc260_hp_master_sw_put,
4875 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4877 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4878 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4879 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4880 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4881 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4883 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4884 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4885 { } /* end */
4888 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4889 .ops = &snd_hda_bind_vol,
4890 .values = {
4891 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4892 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4893 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4898 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4899 .ops = &snd_hda_bind_sw,
4900 .values = {
4901 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4902 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4907 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4908 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4909 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4910 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4911 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4912 { } /* end */
4915 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4916 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4920 static void alc260_hp_3013_automute(struct hda_codec *codec)
4922 struct alc_spec *spec = codec->spec;
4923 unsigned int present;
4925 present = snd_hda_codec_read(codec, 0x15, 0,
4926 AC_VERB_GET_PIN_SENSE, 0);
4927 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4928 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4931 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4932 unsigned int res)
4934 if ((res >> 26) == ALC880_HP_EVENT)
4935 alc260_hp_3013_automute(codec);
4938 static void alc260_hp_3012_automute(struct hda_codec *codec)
4940 unsigned int present, bits;
4942 present = snd_hda_codec_read(codec, 0x10, 0,
4943 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4945 bits = present ? 0 : PIN_OUT;
4946 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4947 bits);
4948 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4949 bits);
4950 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4951 bits);
4954 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4955 unsigned int res)
4957 if ((res >> 26) == ALC880_HP_EVENT)
4958 alc260_hp_3012_automute(codec);
4961 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4962 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4964 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4965 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4966 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4967 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4968 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4969 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4970 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4971 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4972 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4973 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4974 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4975 { } /* end */
4978 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4979 * versions of the ALC260 don't act on requests to enable mic bias from NID
4980 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4981 * datasheet doesn't mention this restriction. At this stage it's not clear
4982 * whether this behaviour is intentional or is a hardware bug in chip
4983 * revisions available in early 2006. Therefore for now allow the
4984 * "Headphone Jack Mode" control to span all choices, but if it turns out
4985 * that the lack of mic bias for this NID is intentional we could change the
4986 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4988 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4989 * don't appear to make the mic bias available from the "line" jack, even
4990 * though the NID used for this jack (0x14) can supply it. The theory is
4991 * that perhaps Acer have included blocking capacitors between the ALC260
4992 * and the output jack. If this turns out to be the case for all such
4993 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4994 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4996 * The C20x Tablet series have a mono internal speaker which is controlled
4997 * via the chip's Mono sum widget and pin complex, so include the necessary
4998 * controls for such models. On models without a "mono speaker" the control
4999 * won't do anything.
5001 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5002 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5003 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5004 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5005 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5006 HDA_OUTPUT),
5007 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5008 HDA_INPUT),
5009 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5010 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5012 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5013 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5014 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5015 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5016 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5017 { } /* end */
5020 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5022 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5023 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5024 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5025 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5026 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5027 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5028 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5029 { } /* end */
5032 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5033 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5035 static struct snd_kcontrol_new alc260_will_mixer[] = {
5036 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5037 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5039 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5040 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5041 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5042 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5043 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5044 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5045 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5046 { } /* end */
5049 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5050 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5052 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5053 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5054 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5056 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5057 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5058 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5059 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5060 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5061 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5062 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5063 { } /* end */
5067 * initialization verbs
5069 static struct hda_verb alc260_init_verbs[] = {
5070 /* Line In pin widget for input */
5071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5072 /* CD pin widget for input */
5073 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5074 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5075 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5076 /* Mic2 (front panel) pin widget for input and vref at 80% */
5077 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5078 /* LINE-2 is used for line-out in rear */
5079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5080 /* select line-out */
5081 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5082 /* LINE-OUT pin */
5083 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5084 /* enable HP */
5085 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5086 /* enable Mono */
5087 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5088 /* mute capture amp left and right */
5089 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5090 /* set connection select to line in (default select for this ADC) */
5091 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5092 /* mute capture amp left and right */
5093 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5094 /* set connection select to line in (default select for this ADC) */
5095 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5096 /* set vol=0 Line-Out mixer amp left and right */
5097 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5098 /* unmute pin widget amp left and right (no gain on this amp) */
5099 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5100 /* set vol=0 HP mixer amp left and right */
5101 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5102 /* unmute pin widget amp left and right (no gain on this amp) */
5103 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5104 /* set vol=0 Mono mixer amp left and right */
5105 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5106 /* unmute pin widget amp left and right (no gain on this amp) */
5107 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5108 /* unmute LINE-2 out pin */
5109 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5110 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5111 * Line In 2 = 0x03
5113 /* mute analog inputs */
5114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5119 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5120 /* mute Front out path */
5121 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5122 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5123 /* mute Headphone out path */
5124 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5125 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5126 /* mute Mono out path */
5127 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5128 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5132 #if 0 /* should be identical with alc260_init_verbs? */
5133 static struct hda_verb alc260_hp_init_verbs[] = {
5134 /* Headphone and output */
5135 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5136 /* mono output */
5137 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5138 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5139 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5140 /* Mic2 (front panel) pin widget for input and vref at 80% */
5141 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5142 /* Line In pin widget for input */
5143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5144 /* Line-2 pin widget for output */
5145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5146 /* CD pin widget for input */
5147 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5148 /* unmute amp left and right */
5149 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5150 /* set connection select to line in (default select for this ADC) */
5151 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5152 /* unmute Line-Out mixer amp left and right (volume = 0) */
5153 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5154 /* mute pin widget amp left and right (no gain on this amp) */
5155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5156 /* unmute HP mixer amp left and right (volume = 0) */
5157 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5158 /* mute pin widget amp left and right (no gain on this amp) */
5159 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5160 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5161 * Line In 2 = 0x03
5163 /* mute analog inputs */
5164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5169 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5170 /* Unmute Front out path */
5171 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5172 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5173 /* Unmute Headphone out path */
5174 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5175 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5176 /* Unmute Mono out path */
5177 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5178 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5181 #endif
5183 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5184 /* Line out and output */
5185 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5186 /* mono output */
5187 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5188 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5189 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5190 /* Mic2 (front panel) pin widget for input and vref at 80% */
5191 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5192 /* Line In pin widget for input */
5193 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5194 /* Headphone pin widget for output */
5195 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5196 /* CD pin widget for input */
5197 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5198 /* unmute amp left and right */
5199 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5200 /* set connection select to line in (default select for this ADC) */
5201 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5202 /* unmute Line-Out mixer amp left and right (volume = 0) */
5203 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5204 /* mute pin widget amp left and right (no gain on this amp) */
5205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5206 /* unmute HP mixer amp left and right (volume = 0) */
5207 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5208 /* mute pin widget amp left and right (no gain on this amp) */
5209 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5210 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5211 * Line In 2 = 0x03
5213 /* mute analog inputs */
5214 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5216 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5217 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5218 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5219 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5220 /* Unmute Front out path */
5221 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5222 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5223 /* Unmute Headphone out path */
5224 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5225 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5226 /* Unmute Mono out path */
5227 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5228 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5232 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5233 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5234 * audio = 0x16, internal speaker = 0x10.
5236 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5237 /* Disable all GPIOs */
5238 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5239 /* Internal speaker is connected to headphone pin */
5240 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5241 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5242 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5243 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5244 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5245 /* Ensure all other unused pins are disabled and muted. */
5246 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5247 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5248 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5249 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5250 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5251 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5255 /* Disable digital (SPDIF) pins */
5256 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5257 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5259 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5260 * when acting as an output.
5262 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5264 /* Start with output sum widgets muted and their output gains at min */
5265 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5266 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5267 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5268 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5270 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5271 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5273 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5275 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5276 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5277 /* Unmute Line1 pin widget output buffer since it starts as an output.
5278 * If the pin mode is changed by the user the pin mode control will
5279 * take care of enabling the pin's input/output buffers as needed.
5280 * Therefore there's no need to enable the input buffer at this
5281 * stage.
5283 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5284 /* Unmute input buffer of pin widget used for Line-in (no equiv
5285 * mixer ctrl)
5287 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5289 /* Mute capture amp left and right */
5290 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5291 /* Set ADC connection select to match default mixer setting - line
5292 * in (on mic1 pin)
5294 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5296 /* Do the same for the second ADC: mute capture input amp and
5297 * set ADC connection to line in (on mic1 pin)
5299 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5300 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5302 /* Mute all inputs to mixer widget (even unconnected ones) */
5303 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5304 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5305 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5306 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5315 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5316 * similar laptops (adapted from Fujitsu init verbs).
5318 static struct hda_verb alc260_acer_init_verbs[] = {
5319 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5320 * the headphone jack. Turn this on and rely on the standard mute
5321 * methods whenever the user wants to turn these outputs off.
5323 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5324 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5325 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5326 /* Internal speaker/Headphone jack is connected to Line-out pin */
5327 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5328 /* Internal microphone/Mic jack is connected to Mic1 pin */
5329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5330 /* Line In jack is connected to Line1 pin */
5331 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5332 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5333 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5334 /* Ensure all other unused pins are disabled and muted. */
5335 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5336 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5337 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5338 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5341 /* Disable digital (SPDIF) pins */
5342 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5343 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5345 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5346 * bus when acting as outputs.
5348 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5349 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5351 /* Start with output sum widgets muted and their output gains at min */
5352 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5353 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5354 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5355 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5356 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5357 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5358 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5359 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5360 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5362 /* Unmute Line-out pin widget amp left and right
5363 * (no equiv mixer ctrl)
5365 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5366 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5367 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5368 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5369 * inputs. If the pin mode is changed by the user the pin mode control
5370 * will take care of enabling the pin's input/output buffers as needed.
5371 * Therefore there's no need to enable the input buffer at this
5372 * stage.
5374 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5375 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5377 /* Mute capture amp left and right */
5378 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5379 /* Set ADC connection select to match default mixer setting - mic
5380 * (on mic1 pin)
5382 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5384 /* Do similar with the second ADC: mute capture input amp and
5385 * set ADC connection to mic to match ALSA's default state.
5387 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5388 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5390 /* Mute all inputs to mixer widget (even unconnected ones) */
5391 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5392 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5393 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5394 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5395 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5397 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5403 /* Initialisation sequence for Maxdata Favorit 100XS
5404 * (adapted from Acer init verbs).
5406 static struct hda_verb alc260_favorit100_init_verbs[] = {
5407 /* GPIO 0 enables the output jack.
5408 * Turn this on and rely on the standard mute
5409 * methods whenever the user wants to turn these outputs off.
5411 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5412 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5413 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5414 /* Line/Mic input jack is connected to Mic1 pin */
5415 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5416 /* Ensure all other unused pins are disabled and muted. */
5417 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5418 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5419 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5420 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5421 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5422 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5424 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5425 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5427 /* Disable digital (SPDIF) pins */
5428 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5429 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5431 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5432 * bus when acting as outputs.
5434 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5435 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5437 /* Start with output sum widgets muted and their output gains at min */
5438 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5439 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5440 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5442 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5444 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5445 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5446 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5448 /* Unmute Line-out pin widget amp left and right
5449 * (no equiv mixer ctrl)
5451 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5452 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5453 * inputs. If the pin mode is changed by the user the pin mode control
5454 * will take care of enabling the pin's input/output buffers as needed.
5455 * Therefore there's no need to enable the input buffer at this
5456 * stage.
5458 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5460 /* Mute capture amp left and right */
5461 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5462 /* Set ADC connection select to match default mixer setting - mic
5463 * (on mic1 pin)
5465 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5467 /* Do similar with the second ADC: mute capture input amp and
5468 * set ADC connection to mic to match ALSA's default state.
5470 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5471 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5473 /* Mute all inputs to mixer widget (even unconnected ones) */
5474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5476 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5486 static struct hda_verb alc260_will_verbs[] = {
5487 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5488 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
5489 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
5490 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5491 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5492 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
5496 static struct hda_verb alc260_replacer_672v_verbs[] = {
5497 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
5498 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
5499 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
5501 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5502 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5503 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5505 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5509 /* toggle speaker-output according to the hp-jack state */
5510 static void alc260_replacer_672v_automute(struct hda_codec *codec)
5512 unsigned int present;
5514 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
5515 present = snd_hda_codec_read(codec, 0x0f, 0,
5516 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5517 if (present) {
5518 snd_hda_codec_write_cache(codec, 0x01, 0,
5519 AC_VERB_SET_GPIO_DATA, 1);
5520 snd_hda_codec_write_cache(codec, 0x0f, 0,
5521 AC_VERB_SET_PIN_WIDGET_CONTROL,
5522 PIN_HP);
5523 } else {
5524 snd_hda_codec_write_cache(codec, 0x01, 0,
5525 AC_VERB_SET_GPIO_DATA, 0);
5526 snd_hda_codec_write_cache(codec, 0x0f, 0,
5527 AC_VERB_SET_PIN_WIDGET_CONTROL,
5528 PIN_OUT);
5532 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
5533 unsigned int res)
5535 if ((res >> 26) == ALC880_HP_EVENT)
5536 alc260_replacer_672v_automute(codec);
5539 static struct hda_verb alc260_hp_dc7600_verbs[] = {
5540 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
5541 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5542 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5543 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5544 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5546 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5547 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5548 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5549 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5553 /* Test configuration for debugging, modelled after the ALC880 test
5554 * configuration.
5556 #ifdef CONFIG_SND_DEBUG
5557 static hda_nid_t alc260_test_dac_nids[1] = {
5558 0x02,
5560 static hda_nid_t alc260_test_adc_nids[2] = {
5561 0x04, 0x05,
5563 /* For testing the ALC260, each input MUX needs its own definition since
5564 * the signal assignments are different. This assumes that the first ADC
5565 * is NID 0x04.
5567 static struct hda_input_mux alc260_test_capture_sources[2] = {
5569 .num_items = 7,
5570 .items = {
5571 { "MIC1 pin", 0x0 },
5572 { "MIC2 pin", 0x1 },
5573 { "LINE1 pin", 0x2 },
5574 { "LINE2 pin", 0x3 },
5575 { "CD pin", 0x4 },
5576 { "LINE-OUT pin", 0x5 },
5577 { "HP-OUT pin", 0x6 },
5581 .num_items = 8,
5582 .items = {
5583 { "MIC1 pin", 0x0 },
5584 { "MIC2 pin", 0x1 },
5585 { "LINE1 pin", 0x2 },
5586 { "LINE2 pin", 0x3 },
5587 { "CD pin", 0x4 },
5588 { "Mixer", 0x5 },
5589 { "LINE-OUT pin", 0x6 },
5590 { "HP-OUT pin", 0x7 },
5594 static struct snd_kcontrol_new alc260_test_mixer[] = {
5595 /* Output driver widgets */
5596 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5597 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5598 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5599 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
5600 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5601 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
5603 /* Modes for retasking pin widgets
5604 * Note: the ALC260 doesn't seem to act on requests to enable mic
5605 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
5606 * mention this restriction. At this stage it's not clear whether
5607 * this behaviour is intentional or is a hardware bug in chip
5608 * revisions available at least up until early 2006. Therefore for
5609 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
5610 * choices, but if it turns out that the lack of mic bias for these
5611 * NIDs is intentional we could change their modes from
5612 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5614 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
5615 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
5616 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
5617 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
5618 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
5619 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
5621 /* Loopback mixer controls */
5622 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
5623 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
5624 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
5625 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
5626 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
5627 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
5628 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
5629 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
5630 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5631 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5632 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
5633 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
5634 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
5635 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5637 /* Controls for GPIO pins, assuming they are configured as outputs */
5638 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
5639 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
5640 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
5641 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
5643 /* Switches to allow the digital IO pins to be enabled. The datasheet
5644 * is ambigious as to which NID is which; testing on laptops which
5645 * make this output available should provide clarification.
5647 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
5648 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
5650 /* A switch allowing EAPD to be enabled. Some laptops seem to use
5651 * this output to turn on an external amplifier.
5653 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
5654 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
5656 { } /* end */
5658 static struct hda_verb alc260_test_init_verbs[] = {
5659 /* Enable all GPIOs as outputs with an initial value of 0 */
5660 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
5661 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
5662 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
5664 /* Enable retasking pins as output, initially without power amp */
5665 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5666 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5667 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5669 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5670 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5672 /* Disable digital (SPDIF) pins initially, but users can enable
5673 * them via a mixer switch. In the case of SPDIF-out, this initverb
5674 * payload also sets the generation to 0, output to be in "consumer"
5675 * PCM format, copyright asserted, no pre-emphasis and no validity
5676 * control.
5678 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5679 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5681 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5682 * OUT1 sum bus when acting as an output.
5684 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5685 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5686 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5687 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5689 /* Start with output sum widgets muted and their output gains at min */
5690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5691 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5693 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5694 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5695 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5696 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5697 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5698 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5700 /* Unmute retasking pin widget output buffers since the default
5701 * state appears to be output. As the pin mode is changed by the
5702 * user the pin mode control will take care of enabling the pin's
5703 * input/output buffers as needed.
5705 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5706 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5709 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5710 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5711 /* Also unmute the mono-out pin widget */
5712 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5714 /* Mute capture amp left and right */
5715 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5716 /* Set ADC connection select to match default mixer setting (mic1
5717 * pin)
5719 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5721 /* Do the same for the second ADC: mute capture input amp and
5722 * set ADC connection to mic1 pin
5724 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5725 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5727 /* Mute all inputs to mixer widget (even unconnected ones) */
5728 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5729 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5732 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5734 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5739 #endif
5741 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5742 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5744 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5745 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5748 * for BIOS auto-configuration
5751 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5752 const char *pfx, int *vol_bits)
5754 hda_nid_t nid_vol;
5755 unsigned long vol_val, sw_val;
5756 char name[32];
5757 int err;
5759 if (nid >= 0x0f && nid < 0x11) {
5760 nid_vol = nid - 0x7;
5761 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5762 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5763 } else if (nid == 0x11) {
5764 nid_vol = nid - 0x7;
5765 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5766 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5767 } else if (nid >= 0x12 && nid <= 0x15) {
5768 nid_vol = 0x08;
5769 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5770 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5771 } else
5772 return 0; /* N/A */
5774 if (!(*vol_bits & (1 << nid_vol))) {
5775 /* first control for the volume widget */
5776 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5777 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5778 if (err < 0)
5779 return err;
5780 *vol_bits |= (1 << nid_vol);
5782 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5783 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5784 if (err < 0)
5785 return err;
5786 return 1;
5789 /* add playback controls from the parsed DAC table */
5790 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5791 const struct auto_pin_cfg *cfg)
5793 hda_nid_t nid;
5794 int err;
5795 int vols = 0;
5797 spec->multiout.num_dacs = 1;
5798 spec->multiout.dac_nids = spec->private_dac_nids;
5799 spec->multiout.dac_nids[0] = 0x02;
5801 nid = cfg->line_out_pins[0];
5802 if (nid) {
5803 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5804 if (err < 0)
5805 return err;
5808 nid = cfg->speaker_pins[0];
5809 if (nid) {
5810 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5811 if (err < 0)
5812 return err;
5815 nid = cfg->hp_pins[0];
5816 if (nid) {
5817 err = alc260_add_playback_controls(spec, nid, "Headphone",
5818 &vols);
5819 if (err < 0)
5820 return err;
5822 return 0;
5825 /* create playback/capture controls for input pins */
5826 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5827 const struct auto_pin_cfg *cfg)
5829 struct hda_input_mux *imux = &spec->private_imux[0];
5830 int i, err, idx;
5832 for (i = 0; i < AUTO_PIN_LAST; i++) {
5833 if (cfg->input_pins[i] >= 0x12) {
5834 idx = cfg->input_pins[i] - 0x12;
5835 err = new_analog_input(spec, cfg->input_pins[i],
5836 auto_pin_cfg_labels[i], idx,
5837 0x07);
5838 if (err < 0)
5839 return err;
5840 imux->items[imux->num_items].label =
5841 auto_pin_cfg_labels[i];
5842 imux->items[imux->num_items].index = idx;
5843 imux->num_items++;
5845 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5846 idx = cfg->input_pins[i] - 0x09;
5847 err = new_analog_input(spec, cfg->input_pins[i],
5848 auto_pin_cfg_labels[i], idx,
5849 0x07);
5850 if (err < 0)
5851 return err;
5852 imux->items[imux->num_items].label =
5853 auto_pin_cfg_labels[i];
5854 imux->items[imux->num_items].index = idx;
5855 imux->num_items++;
5858 return 0;
5861 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5862 hda_nid_t nid, int pin_type,
5863 int sel_idx)
5865 alc_set_pin_output(codec, nid, pin_type);
5866 /* need the manual connection? */
5867 if (nid >= 0x12) {
5868 int idx = nid - 0x12;
5869 snd_hda_codec_write(codec, idx + 0x0b, 0,
5870 AC_VERB_SET_CONNECT_SEL, sel_idx);
5874 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5876 struct alc_spec *spec = codec->spec;
5877 hda_nid_t nid;
5879 nid = spec->autocfg.line_out_pins[0];
5880 if (nid) {
5881 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5882 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5885 nid = spec->autocfg.speaker_pins[0];
5886 if (nid)
5887 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5889 nid = spec->autocfg.hp_pins[0];
5890 if (nid)
5891 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5894 #define ALC260_PIN_CD_NID 0x16
5895 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5897 struct alc_spec *spec = codec->spec;
5898 int i;
5900 for (i = 0; i < AUTO_PIN_LAST; i++) {
5901 hda_nid_t nid = spec->autocfg.input_pins[i];
5902 if (nid >= 0x12) {
5903 alc_set_input_pin(codec, nid, i);
5904 if (nid != ALC260_PIN_CD_NID &&
5905 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5906 snd_hda_codec_write(codec, nid, 0,
5907 AC_VERB_SET_AMP_GAIN_MUTE,
5908 AMP_OUT_MUTE);
5914 * generic initialization of ADC, input mixers and output mixers
5916 static struct hda_verb alc260_volume_init_verbs[] = {
5918 * Unmute ADC0-1 and set the default input to mic-in
5920 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5921 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5922 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5923 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5925 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5926 * mixer widget
5927 * Note: PASD motherboards uses the Line In 2 as the input for
5928 * front panel mic (mic 2)
5930 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5931 /* mute analog inputs */
5932 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5933 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5934 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5935 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5939 * Set up output mixers (0x08 - 0x0a)
5941 /* set vol=0 to output mixers */
5942 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5943 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5944 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5945 /* set up input amps for analog loopback */
5946 /* Amp Indices: DAC = 0, mixer = 1 */
5947 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5948 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5949 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5950 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5951 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5952 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5957 static int alc260_parse_auto_config(struct hda_codec *codec)
5959 struct alc_spec *spec = codec->spec;
5960 int err;
5961 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5963 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5964 alc260_ignore);
5965 if (err < 0)
5966 return err;
5967 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5968 if (err < 0)
5969 return err;
5970 if (!spec->kctls.list)
5971 return 0; /* can't find valid BIOS pin config */
5972 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5973 if (err < 0)
5974 return err;
5976 spec->multiout.max_channels = 2;
5978 if (spec->autocfg.dig_outs)
5979 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5980 if (spec->kctls.list)
5981 add_mixer(spec, spec->kctls.list);
5983 add_verb(spec, alc260_volume_init_verbs);
5985 spec->num_mux_defs = 1;
5986 spec->input_mux = &spec->private_imux[0];
5988 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5990 return 1;
5993 /* additional initialization for auto-configuration model */
5994 static void alc260_auto_init(struct hda_codec *codec)
5996 struct alc_spec *spec = codec->spec;
5997 alc260_auto_init_multi_out(codec);
5998 alc260_auto_init_analog_input(codec);
5999 if (spec->unsol_event)
6000 alc_inithook(codec);
6003 #ifdef CONFIG_SND_HDA_POWER_SAVE
6004 static struct hda_amp_list alc260_loopbacks[] = {
6005 { 0x07, HDA_INPUT, 0 },
6006 { 0x07, HDA_INPUT, 1 },
6007 { 0x07, HDA_INPUT, 2 },
6008 { 0x07, HDA_INPUT, 3 },
6009 { 0x07, HDA_INPUT, 4 },
6010 { } /* end */
6012 #endif
6015 * ALC260 configurations
6017 static const char *alc260_models[ALC260_MODEL_LAST] = {
6018 [ALC260_BASIC] = "basic",
6019 [ALC260_HP] = "hp",
6020 [ALC260_HP_3013] = "hp-3013",
6021 [ALC260_HP_DC7600] = "hp-dc7600",
6022 [ALC260_FUJITSU_S702X] = "fujitsu",
6023 [ALC260_ACER] = "acer",
6024 [ALC260_WILL] = "will",
6025 [ALC260_REPLACER_672V] = "replacer",
6026 [ALC260_FAVORIT100] = "favorit100",
6027 #ifdef CONFIG_SND_DEBUG
6028 [ALC260_TEST] = "test",
6029 #endif
6030 [ALC260_AUTO] = "auto",
6033 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6034 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6035 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6036 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6037 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6038 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
6039 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6040 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6041 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6042 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6043 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6044 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6045 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6046 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6047 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6048 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6049 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6050 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6051 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6052 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6056 static struct alc_config_preset alc260_presets[] = {
6057 [ALC260_BASIC] = {
6058 .mixers = { alc260_base_output_mixer,
6059 alc260_input_mixer },
6060 .init_verbs = { alc260_init_verbs },
6061 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6062 .dac_nids = alc260_dac_nids,
6063 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6064 .adc_nids = alc260_adc_nids,
6065 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6066 .channel_mode = alc260_modes,
6067 .input_mux = &alc260_capture_source,
6069 [ALC260_HP] = {
6070 .mixers = { alc260_hp_output_mixer,
6071 alc260_input_mixer },
6072 .init_verbs = { alc260_init_verbs,
6073 alc260_hp_unsol_verbs },
6074 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6075 .dac_nids = alc260_dac_nids,
6076 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6077 .adc_nids = alc260_adc_nids_alt,
6078 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6079 .channel_mode = alc260_modes,
6080 .input_mux = &alc260_capture_source,
6081 .unsol_event = alc260_hp_unsol_event,
6082 .init_hook = alc260_hp_automute,
6084 [ALC260_HP_DC7600] = {
6085 .mixers = { alc260_hp_dc7600_mixer,
6086 alc260_input_mixer },
6087 .init_verbs = { alc260_init_verbs,
6088 alc260_hp_dc7600_verbs },
6089 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6090 .dac_nids = alc260_dac_nids,
6091 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6092 .adc_nids = alc260_adc_nids_alt,
6093 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6094 .channel_mode = alc260_modes,
6095 .input_mux = &alc260_capture_source,
6096 .unsol_event = alc260_hp_3012_unsol_event,
6097 .init_hook = alc260_hp_3012_automute,
6099 [ALC260_HP_3013] = {
6100 .mixers = { alc260_hp_3013_mixer,
6101 alc260_input_mixer },
6102 .init_verbs = { alc260_hp_3013_init_verbs,
6103 alc260_hp_3013_unsol_verbs },
6104 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6105 .dac_nids = alc260_dac_nids,
6106 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6107 .adc_nids = alc260_adc_nids_alt,
6108 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6109 .channel_mode = alc260_modes,
6110 .input_mux = &alc260_capture_source,
6111 .unsol_event = alc260_hp_3013_unsol_event,
6112 .init_hook = alc260_hp_3013_automute,
6114 [ALC260_FUJITSU_S702X] = {
6115 .mixers = { alc260_fujitsu_mixer },
6116 .init_verbs = { alc260_fujitsu_init_verbs },
6117 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6118 .dac_nids = alc260_dac_nids,
6119 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6120 .adc_nids = alc260_dual_adc_nids,
6121 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6122 .channel_mode = alc260_modes,
6123 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6124 .input_mux = alc260_fujitsu_capture_sources,
6126 [ALC260_ACER] = {
6127 .mixers = { alc260_acer_mixer },
6128 .init_verbs = { alc260_acer_init_verbs },
6129 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6130 .dac_nids = alc260_dac_nids,
6131 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6132 .adc_nids = alc260_dual_adc_nids,
6133 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6134 .channel_mode = alc260_modes,
6135 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6136 .input_mux = alc260_acer_capture_sources,
6138 [ALC260_FAVORIT100] = {
6139 .mixers = { alc260_favorit100_mixer },
6140 .init_verbs = { alc260_favorit100_init_verbs },
6141 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6142 .dac_nids = alc260_dac_nids,
6143 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6144 .adc_nids = alc260_dual_adc_nids,
6145 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6146 .channel_mode = alc260_modes,
6147 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6148 .input_mux = alc260_favorit100_capture_sources,
6150 [ALC260_WILL] = {
6151 .mixers = { alc260_will_mixer },
6152 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6153 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6154 .dac_nids = alc260_dac_nids,
6155 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6156 .adc_nids = alc260_adc_nids,
6157 .dig_out_nid = ALC260_DIGOUT_NID,
6158 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6159 .channel_mode = alc260_modes,
6160 .input_mux = &alc260_capture_source,
6162 [ALC260_REPLACER_672V] = {
6163 .mixers = { alc260_replacer_672v_mixer },
6164 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6165 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6166 .dac_nids = alc260_dac_nids,
6167 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6168 .adc_nids = alc260_adc_nids,
6169 .dig_out_nid = ALC260_DIGOUT_NID,
6170 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6171 .channel_mode = alc260_modes,
6172 .input_mux = &alc260_capture_source,
6173 .unsol_event = alc260_replacer_672v_unsol_event,
6174 .init_hook = alc260_replacer_672v_automute,
6176 #ifdef CONFIG_SND_DEBUG
6177 [ALC260_TEST] = {
6178 .mixers = { alc260_test_mixer },
6179 .init_verbs = { alc260_test_init_verbs },
6180 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6181 .dac_nids = alc260_test_dac_nids,
6182 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6183 .adc_nids = alc260_test_adc_nids,
6184 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6185 .channel_mode = alc260_modes,
6186 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6187 .input_mux = alc260_test_capture_sources,
6189 #endif
6192 static int patch_alc260(struct hda_codec *codec)
6194 struct alc_spec *spec;
6195 int err, board_config;
6197 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6198 if (spec == NULL)
6199 return -ENOMEM;
6201 codec->spec = spec;
6203 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6204 alc260_models,
6205 alc260_cfg_tbl);
6206 if (board_config < 0) {
6207 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, "
6208 "trying auto-probe from BIOS...\n",
6209 codec->chip_name);
6210 board_config = ALC260_AUTO;
6213 if (board_config == ALC260_AUTO) {
6214 /* automatic parse from the BIOS config */
6215 err = alc260_parse_auto_config(codec);
6216 if (err < 0) {
6217 alc_free(codec);
6218 return err;
6219 } else if (!err) {
6220 printk(KERN_INFO
6221 "hda_codec: Cannot set up configuration "
6222 "from BIOS. Using base mode...\n");
6223 board_config = ALC260_BASIC;
6227 err = snd_hda_attach_beep_device(codec, 0x1);
6228 if (err < 0) {
6229 alc_free(codec);
6230 return err;
6233 if (board_config != ALC260_AUTO)
6234 setup_preset(spec, &alc260_presets[board_config]);
6236 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6237 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6239 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6240 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6242 if (!spec->adc_nids && spec->input_mux) {
6243 /* check whether NID 0x04 is valid */
6244 unsigned int wcap = get_wcaps(codec, 0x04);
6245 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6246 /* get type */
6247 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6248 spec->adc_nids = alc260_adc_nids_alt;
6249 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6250 } else {
6251 spec->adc_nids = alc260_adc_nids;
6252 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6255 set_capture_mixer(spec);
6256 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6258 spec->vmaster_nid = 0x08;
6260 codec->patch_ops = alc_patch_ops;
6261 if (board_config == ALC260_AUTO)
6262 spec->init_hook = alc260_auto_init;
6263 #ifdef CONFIG_SND_HDA_POWER_SAVE
6264 if (!spec->loopback.amplist)
6265 spec->loopback.amplist = alc260_loopbacks;
6266 #endif
6267 codec->proc_widget_hook = print_realtek_coef;
6269 return 0;
6274 * ALC882 support
6276 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6277 * configuration. Each pin widget can choose any input DACs and a mixer.
6278 * Each ADC is connected from a mixer of all inputs. This makes possible
6279 * 6-channel independent captures.
6281 * In addition, an independent DAC for the multi-playback (not used in this
6282 * driver yet).
6284 #define ALC882_DIGOUT_NID 0x06
6285 #define ALC882_DIGIN_NID 0x0a
6287 static struct hda_channel_mode alc882_ch_modes[1] = {
6288 { 8, NULL }
6291 static hda_nid_t alc882_dac_nids[4] = {
6292 /* front, rear, clfe, rear_surr */
6293 0x02, 0x03, 0x04, 0x05
6296 /* identical with ALC880 */
6297 #define alc882_adc_nids alc880_adc_nids
6298 #define alc882_adc_nids_alt alc880_adc_nids_alt
6300 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6301 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6303 /* input MUX */
6304 /* FIXME: should be a matrix-type input source selection */
6306 static struct hda_input_mux alc882_capture_source = {
6307 .num_items = 4,
6308 .items = {
6309 { "Mic", 0x0 },
6310 { "Front Mic", 0x1 },
6311 { "Line", 0x2 },
6312 { "CD", 0x4 },
6316 static struct hda_input_mux mb5_capture_source = {
6317 .num_items = 3,
6318 .items = {
6319 { "Mic", 0x1 },
6320 { "Line", 0x2 },
6321 { "CD", 0x4 },
6326 * 2ch mode
6328 static struct hda_verb alc882_3ST_ch2_init[] = {
6329 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6330 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6331 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6332 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6333 { } /* end */
6337 * 6ch mode
6339 static struct hda_verb alc882_3ST_ch6_init[] = {
6340 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6341 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6342 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6343 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6344 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6345 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6346 { } /* end */
6349 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
6350 { 2, alc882_3ST_ch2_init },
6351 { 6, alc882_3ST_ch6_init },
6355 * 6ch mode
6357 static struct hda_verb alc882_sixstack_ch6_init[] = {
6358 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6359 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6360 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6361 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6362 { } /* end */
6366 * 8ch mode
6368 static struct hda_verb alc882_sixstack_ch8_init[] = {
6369 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6370 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6371 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6372 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6373 { } /* end */
6376 static struct hda_channel_mode alc882_sixstack_modes[2] = {
6377 { 6, alc882_sixstack_ch6_init },
6378 { 8, alc882_sixstack_ch8_init },
6382 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6386 * 2ch mode
6388 static struct hda_verb alc885_mbp_ch2_init[] = {
6389 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6390 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6392 { } /* end */
6396 * 6ch mode
6398 static struct hda_verb alc885_mbp_ch6_init[] = {
6399 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6400 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6401 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6402 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6403 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6404 { } /* end */
6407 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
6408 { 2, alc885_mbp_ch2_init },
6409 { 6, alc885_mbp_ch6_init },
6413 * 2ch
6414 * Speakers/Woofer/HP = Front
6415 * LineIn = Input
6417 static struct hda_verb alc885_mb5_ch2_init[] = {
6418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6419 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6420 { } /* end */
6424 * 6ch mode
6425 * Speakers/HP = Front
6426 * Woofer = LFE
6427 * LineIn = Surround
6429 static struct hda_verb alc885_mb5_ch6_init[] = {
6430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6432 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6433 { } /* end */
6436 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6437 { 2, alc885_mb5_ch2_init },
6438 { 6, alc885_mb5_ch6_init },
6441 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6442 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6444 static struct snd_kcontrol_new alc882_base_mixer[] = {
6445 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6446 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6447 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6448 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6449 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6450 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6451 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6452 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6453 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6454 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6456 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6457 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6458 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6459 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6460 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6461 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6462 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6463 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6464 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6466 { } /* end */
6469 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6471 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6472 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
6473 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6475 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
6477 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
6478 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
6479 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
6480 { } /* end */
6483 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
6484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6485 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
6486 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6487 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
6488 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6489 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
6490 HDA_CODEC_VOLUME("HP Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
6491 HDA_BIND_MUTE ("HP Playback Switch", 0x0f, 0x02, HDA_INPUT),
6492 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6493 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
6495 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
6496 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
6497 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
6498 { } /* end */
6501 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
6502 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6503 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6504 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6505 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6509 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6511 { } /* end */
6514 static struct snd_kcontrol_new alc882_targa_mixer[] = {
6515 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6516 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6517 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6518 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6519 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6524 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6527 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6528 { } /* end */
6531 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
6532 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
6534 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
6535 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6536 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6538 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
6539 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6540 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6541 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6542 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6543 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
6544 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
6545 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6546 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6547 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6548 { } /* end */
6551 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
6552 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6553 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6555 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6556 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6557 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6558 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6560 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6562 { } /* end */
6565 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6567 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6568 .name = "Channel Mode",
6569 .info = alc_ch_mode_info,
6570 .get = alc_ch_mode_get,
6571 .put = alc_ch_mode_put,
6573 { } /* end */
6576 static struct hda_verb alc882_init_verbs[] = {
6577 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6580 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6581 /* Rear mixer */
6582 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6585 /* CLFE mixer */
6586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6587 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6588 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6589 /* Side mixer */
6590 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6591 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6592 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6594 /* Front Pin: output 0 (0x0c) */
6595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6597 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6598 /* Rear Pin: output 1 (0x0d) */
6599 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6600 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6602 /* CLFE Pin: output 2 (0x0e) */
6603 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6604 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6605 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6606 /* Side Pin: output 3 (0x0f) */
6607 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6608 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6609 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6610 /* Mic (rear) pin: input vref at 80% */
6611 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6612 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6613 /* Front Mic pin: input vref at 80% */
6614 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6615 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6616 /* Line In pin: input */
6617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6618 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6619 /* Line-2 In: Headphone output (output 0 - 0x0c) */
6620 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6621 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6622 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6623 /* CD pin widget for input */
6624 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6626 /* FIXME: use matrix-type input source selection */
6627 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6628 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6631 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6632 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6633 /* Input mixer2 */
6634 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6635 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6636 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6637 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6638 /* Input mixer3 */
6639 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6640 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6641 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6642 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6643 /* ADC1: mute amp left and right */
6644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6645 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6646 /* ADC2: mute amp left and right */
6647 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6648 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6649 /* ADC3: mute amp left and right */
6650 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6651 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6656 static struct hda_verb alc882_eapd_verbs[] = {
6657 /* change to EAPD mode */
6658 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6659 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
6663 /* Mac Pro test */
6664 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6665 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6666 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6667 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
6668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
6669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
6670 /* FIXME: this looks suspicious...
6671 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
6672 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
6674 { } /* end */
6677 static struct hda_verb alc882_macpro_init_verbs[] = {
6678 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6682 /* Front Pin: output 0 (0x0c) */
6683 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6684 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6685 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6686 /* Front Mic pin: input vref at 80% */
6687 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6689 /* Speaker: output */
6690 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6692 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
6693 /* Headphone output (output 0 - 0x0c) */
6694 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6695 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6696 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6698 /* FIXME: use matrix-type input source selection */
6699 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6700 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6701 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6702 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6703 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6704 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6705 /* Input mixer2 */
6706 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6707 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6708 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6709 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6710 /* Input mixer3 */
6711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6712 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6713 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6714 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6715 /* ADC1: mute amp left and right */
6716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6717 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6718 /* ADC2: mute amp left and right */
6719 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6720 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6721 /* ADC3: mute amp left and right */
6722 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6723 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6728 /* Macbook 5,1 */
6729 static struct hda_verb alc885_mb5_init_verbs[] = {
6730 /* DACs */
6731 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6732 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6733 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6734 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6735 /* Front mixer */
6736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6737 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6739 /* Surround mixer */
6740 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6741 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6743 /* LFE mixer */
6744 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6745 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6747 /* HP mixer */
6748 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6751 /* Front Pin (0x0c) */
6752 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6753 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6754 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6755 /* LFE Pin (0x0e) */
6756 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
6757 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6758 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
6759 /* HP Pin (0x0f) */
6760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6762 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
6763 /* Front Mic pin: input vref at 80% */
6764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6765 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6766 /* Line In pin */
6767 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6768 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6777 /* Macbook Pro rev3 */
6778 static struct hda_verb alc885_mbp3_init_verbs[] = {
6779 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6783 /* Rear mixer */
6784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6785 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6787 /* Front Pin: output 0 (0x0c) */
6788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6789 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6790 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6791 /* HP Pin: output 0 (0x0d) */
6792 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6793 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6794 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6795 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6796 /* Mic (rear) pin: input vref at 80% */
6797 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6799 /* Front Mic pin: input vref at 80% */
6800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6802 /* Line In pin: use output 1 when in LineOut mode */
6803 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6804 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6805 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6807 /* FIXME: use matrix-type input source selection */
6808 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6809 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6811 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6812 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6813 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6814 /* Input mixer2 */
6815 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6816 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6817 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6818 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6819 /* Input mixer3 */
6820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6822 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6823 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6824 /* ADC1: mute amp left and right */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6826 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6827 /* ADC2: mute amp left and right */
6828 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6830 /* ADC3: mute amp left and right */
6831 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6832 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6837 /* iMac 24 mixer. */
6838 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6839 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6840 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6841 { } /* end */
6844 /* iMac 24 init verbs. */
6845 static struct hda_verb alc885_imac24_init_verbs[] = {
6846 /* Internal speakers: output 0 (0x0c) */
6847 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6848 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6849 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6850 /* Internal speakers: output 0 (0x0c) */
6851 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6852 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6853 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6854 /* Headphone: output 0 (0x0c) */
6855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6857 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6858 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6859 /* Front Mic: input vref at 80% */
6860 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6865 /* Toggle speaker-output according to the hp-jack state */
6866 static void alc885_imac24_automute_init_hook(struct hda_codec *codec)
6868 struct alc_spec *spec = codec->spec;
6870 spec->autocfg.hp_pins[0] = 0x14;
6871 spec->autocfg.speaker_pins[0] = 0x18;
6872 spec->autocfg.speaker_pins[1] = 0x1a;
6873 alc_automute_amp(codec);
6876 static void alc885_mbp3_init_hook(struct hda_codec *codec)
6878 struct alc_spec *spec = codec->spec;
6880 spec->autocfg.hp_pins[0] = 0x15;
6881 spec->autocfg.speaker_pins[0] = 0x14;
6882 alc_automute_amp(codec);
6886 static struct hda_verb alc882_targa_verbs[] = {
6887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6890 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6891 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6893 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6894 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6895 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6897 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6898 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6899 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6900 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6901 { } /* end */
6904 /* toggle speaker-output according to the hp-jack state */
6905 static void alc882_targa_automute(struct hda_codec *codec)
6907 struct alc_spec *spec = codec->spec;
6908 alc_automute_amp(codec);
6909 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6910 spec->jack_present ? 1 : 3);
6913 static void alc882_targa_init_hook(struct hda_codec *codec)
6915 struct alc_spec *spec = codec->spec;
6917 spec->autocfg.hp_pins[0] = 0x14;
6918 spec->autocfg.speaker_pins[0] = 0x1b;
6919 alc882_targa_automute(codec);
6922 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6924 if ((res >> 26) == ALC880_HP_EVENT)
6925 alc882_targa_automute(codec);
6928 static struct hda_verb alc882_asus_a7j_verbs[] = {
6929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6936 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6937 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6938 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6940 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6941 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6942 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6943 { } /* end */
6946 static struct hda_verb alc882_asus_a7m_verbs[] = {
6947 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6948 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6952 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6954 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6955 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6956 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6958 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6959 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6960 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6961 { } /* end */
6964 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6966 unsigned int gpiostate, gpiomask, gpiodir;
6968 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6969 AC_VERB_GET_GPIO_DATA, 0);
6971 if (!muted)
6972 gpiostate |= (1 << pin);
6973 else
6974 gpiostate &= ~(1 << pin);
6976 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6977 AC_VERB_GET_GPIO_MASK, 0);
6978 gpiomask |= (1 << pin);
6980 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6981 AC_VERB_GET_GPIO_DIRECTION, 0);
6982 gpiodir |= (1 << pin);
6985 snd_hda_codec_write(codec, codec->afg, 0,
6986 AC_VERB_SET_GPIO_MASK, gpiomask);
6987 snd_hda_codec_write(codec, codec->afg, 0,
6988 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6990 msleep(1);
6992 snd_hda_codec_write(codec, codec->afg, 0,
6993 AC_VERB_SET_GPIO_DATA, gpiostate);
6996 /* set up GPIO at initialization */
6997 static void alc885_macpro_init_hook(struct hda_codec *codec)
6999 alc882_gpio_mute(codec, 0, 0);
7000 alc882_gpio_mute(codec, 1, 0);
7003 /* set up GPIO and update auto-muting at initialization */
7004 static void alc885_imac24_init_hook(struct hda_codec *codec)
7006 alc885_macpro_init_hook(codec);
7007 alc885_imac24_automute_init_hook(codec);
7011 * generic initialization of ADC, input mixers and output mixers
7013 static struct hda_verb alc882_auto_init_verbs[] = {
7015 * Unmute ADC0-2 and set the default input to mic-in
7017 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7019 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7020 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7021 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7024 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7025 * mixer widget
7026 * Note: PASD motherboards uses the Line In 2 as the input for
7027 * front panel mic (mic 2)
7029 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7030 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7031 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7032 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7034 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7037 * Set up output mixers (0x0c - 0x0f)
7039 /* set vol=0 to output mixers */
7040 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7041 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7042 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7043 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7044 /* set up input amps for analog loopback */
7045 /* Amp Indices: DAC = 0, mixer = 1 */
7046 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7047 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7048 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7049 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7050 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7051 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7053 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7054 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7055 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7057 /* FIXME: use matrix-type input source selection */
7058 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7059 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7064 /* Input mixer2 */
7065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7066 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7067 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7069 /* Input mixer3 */
7070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7078 #ifdef CONFIG_SND_HDA_POWER_SAVE
7079 #define alc882_loopbacks alc880_loopbacks
7080 #endif
7082 /* pcm configuration: identical with ALC880 */
7083 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
7084 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
7085 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
7086 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
7089 * configuration and preset
7091 static const char *alc882_models[ALC882_MODEL_LAST] = {
7092 [ALC882_3ST_DIG] = "3stack-dig",
7093 [ALC882_6ST_DIG] = "6stack-dig",
7094 [ALC882_ARIMA] = "arima",
7095 [ALC882_W2JC] = "w2jc",
7096 [ALC882_TARGA] = "targa",
7097 [ALC882_ASUS_A7J] = "asus-a7j",
7098 [ALC882_ASUS_A7M] = "asus-a7m",
7099 [ALC885_MACPRO] = "macpro",
7100 [ALC885_MB5] = "mb5",
7101 [ALC885_MBP3] = "mbp3",
7102 [ALC885_IMAC24] = "imac24",
7103 [ALC882_AUTO] = "auto",
7106 static struct snd_pci_quirk alc882_cfg_tbl[] = {
7107 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
7108 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
7109 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
7110 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
7111 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
7112 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7113 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
7114 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
7115 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
7116 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7117 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7118 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
7122 static struct alc_config_preset alc882_presets[] = {
7123 [ALC882_3ST_DIG] = {
7124 .mixers = { alc882_base_mixer },
7125 .init_verbs = { alc882_init_verbs },
7126 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7127 .dac_nids = alc882_dac_nids,
7128 .dig_out_nid = ALC882_DIGOUT_NID,
7129 .dig_in_nid = ALC882_DIGIN_NID,
7130 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7131 .channel_mode = alc882_ch_modes,
7132 .need_dac_fix = 1,
7133 .input_mux = &alc882_capture_source,
7135 [ALC882_6ST_DIG] = {
7136 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7137 .init_verbs = { alc882_init_verbs },
7138 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7139 .dac_nids = alc882_dac_nids,
7140 .dig_out_nid = ALC882_DIGOUT_NID,
7141 .dig_in_nid = ALC882_DIGIN_NID,
7142 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7143 .channel_mode = alc882_sixstack_modes,
7144 .input_mux = &alc882_capture_source,
7146 [ALC882_ARIMA] = {
7147 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7148 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7149 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7150 .dac_nids = alc882_dac_nids,
7151 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7152 .channel_mode = alc882_sixstack_modes,
7153 .input_mux = &alc882_capture_source,
7155 [ALC882_W2JC] = {
7156 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7157 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7158 alc880_gpio1_init_verbs },
7159 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7160 .dac_nids = alc882_dac_nids,
7161 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7162 .channel_mode = alc880_threestack_modes,
7163 .need_dac_fix = 1,
7164 .input_mux = &alc882_capture_source,
7165 .dig_out_nid = ALC882_DIGOUT_NID,
7167 [ALC885_MBP3] = {
7168 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7169 .init_verbs = { alc885_mbp3_init_verbs,
7170 alc880_gpio1_init_verbs },
7171 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7172 .dac_nids = alc882_dac_nids,
7173 .channel_mode = alc885_mbp_6ch_modes,
7174 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7175 .input_mux = &alc882_capture_source,
7176 .dig_out_nid = ALC882_DIGOUT_NID,
7177 .dig_in_nid = ALC882_DIGIN_NID,
7178 .unsol_event = alc_automute_amp_unsol_event,
7179 .init_hook = alc885_mbp3_init_hook,
7181 [ALC885_MB5] = {
7182 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7183 .init_verbs = { alc885_mb5_init_verbs,
7184 alc880_gpio1_init_verbs },
7185 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7186 .dac_nids = alc882_dac_nids,
7187 .channel_mode = alc885_mb5_6ch_modes,
7188 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7189 .input_mux = &mb5_capture_source,
7190 .dig_out_nid = ALC882_DIGOUT_NID,
7191 .dig_in_nid = ALC882_DIGIN_NID,
7193 [ALC885_MACPRO] = {
7194 .mixers = { alc882_macpro_mixer },
7195 .init_verbs = { alc882_macpro_init_verbs },
7196 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7197 .dac_nids = alc882_dac_nids,
7198 .dig_out_nid = ALC882_DIGOUT_NID,
7199 .dig_in_nid = ALC882_DIGIN_NID,
7200 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7201 .channel_mode = alc882_ch_modes,
7202 .input_mux = &alc882_capture_source,
7203 .init_hook = alc885_macpro_init_hook,
7205 [ALC885_IMAC24] = {
7206 .mixers = { alc885_imac24_mixer },
7207 .init_verbs = { alc885_imac24_init_verbs },
7208 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7209 .dac_nids = alc882_dac_nids,
7210 .dig_out_nid = ALC882_DIGOUT_NID,
7211 .dig_in_nid = ALC882_DIGIN_NID,
7212 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7213 .channel_mode = alc882_ch_modes,
7214 .input_mux = &alc882_capture_source,
7215 .unsol_event = alc_automute_amp_unsol_event,
7216 .init_hook = alc885_imac24_init_hook,
7218 [ALC882_TARGA] = {
7219 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7220 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
7221 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7222 .dac_nids = alc882_dac_nids,
7223 .dig_out_nid = ALC882_DIGOUT_NID,
7224 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7225 .adc_nids = alc882_adc_nids,
7226 .capsrc_nids = alc882_capsrc_nids,
7227 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7228 .channel_mode = alc882_3ST_6ch_modes,
7229 .need_dac_fix = 1,
7230 .input_mux = &alc882_capture_source,
7231 .unsol_event = alc882_targa_unsol_event,
7232 .init_hook = alc882_targa_init_hook,
7234 [ALC882_ASUS_A7J] = {
7235 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7236 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7237 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7238 .dac_nids = alc882_dac_nids,
7239 .dig_out_nid = ALC882_DIGOUT_NID,
7240 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7241 .adc_nids = alc882_adc_nids,
7242 .capsrc_nids = alc882_capsrc_nids,
7243 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7244 .channel_mode = alc882_3ST_6ch_modes,
7245 .need_dac_fix = 1,
7246 .input_mux = &alc882_capture_source,
7248 [ALC882_ASUS_A7M] = {
7249 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7250 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7251 alc880_gpio1_init_verbs,
7252 alc882_asus_a7m_verbs },
7253 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7254 .dac_nids = alc882_dac_nids,
7255 .dig_out_nid = ALC882_DIGOUT_NID,
7256 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7257 .channel_mode = alc880_threestack_modes,
7258 .need_dac_fix = 1,
7259 .input_mux = &alc882_capture_source,
7265 * Pin config fixes
7267 enum {
7268 PINFIX_ABIT_AW9D_MAX
7271 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7272 { 0x15, 0x01080104 }, /* side */
7273 { 0x16, 0x01011012 }, /* rear */
7274 { 0x17, 0x01016011 }, /* clfe */
7278 static const struct alc_pincfg *alc882_pin_fixes[] = {
7279 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7282 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7283 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7288 * BIOS auto configuration
7290 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7291 hda_nid_t nid, int pin_type,
7292 int dac_idx)
7294 /* set as output */
7295 struct alc_spec *spec = codec->spec;
7296 int idx;
7298 alc_set_pin_output(codec, nid, pin_type);
7299 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7300 idx = 4;
7301 else
7302 idx = spec->multiout.dac_nids[dac_idx] - 2;
7303 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7307 static void alc882_auto_init_multi_out(struct hda_codec *codec)
7309 struct alc_spec *spec = codec->spec;
7310 int i;
7312 for (i = 0; i <= HDA_SIDE; i++) {
7313 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7314 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7315 if (nid)
7316 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7321 static void alc882_auto_init_hp_out(struct hda_codec *codec)
7323 struct alc_spec *spec = codec->spec;
7324 hda_nid_t pin;
7326 pin = spec->autocfg.hp_pins[0];
7327 if (pin) /* connect to front */
7328 /* use dac 0 */
7329 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7330 pin = spec->autocfg.speaker_pins[0];
7331 if (pin)
7332 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7335 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7336 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7338 static void alc882_auto_init_analog_input(struct hda_codec *codec)
7340 struct alc_spec *spec = codec->spec;
7341 int i;
7343 for (i = 0; i < AUTO_PIN_LAST; i++) {
7344 hda_nid_t nid = spec->autocfg.input_pins[i];
7345 if (!nid)
7346 continue;
7347 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7348 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7349 snd_hda_codec_write(codec, nid, 0,
7350 AC_VERB_SET_AMP_GAIN_MUTE,
7351 AMP_OUT_MUTE);
7355 static void alc882_auto_init_input_src(struct hda_codec *codec)
7357 struct alc_spec *spec = codec->spec;
7358 int c;
7360 for (c = 0; c < spec->num_adc_nids; c++) {
7361 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7362 hda_nid_t nid = spec->capsrc_nids[c];
7363 unsigned int mux_idx;
7364 const struct hda_input_mux *imux;
7365 int conns, mute, idx, item;
7367 conns = snd_hda_get_connections(codec, nid, conn_list,
7368 ARRAY_SIZE(conn_list));
7369 if (conns < 0)
7370 continue;
7371 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7372 imux = &spec->input_mux[mux_idx];
7373 for (idx = 0; idx < conns; idx++) {
7374 /* if the current connection is the selected one,
7375 * unmute it as default - otherwise mute it
7377 mute = AMP_IN_MUTE(idx);
7378 for (item = 0; item < imux->num_items; item++) {
7379 if (imux->items[item].index == idx) {
7380 if (spec->cur_mux[c] == item)
7381 mute = AMP_IN_UNMUTE(idx);
7382 break;
7385 /* check if we have a selector or mixer
7386 * we could check for the widget type instead, but
7387 * just check for Amp-In presence (in case of mixer
7388 * without amp-in there is something wrong, this
7389 * function shouldn't be used or capsrc nid is wrong)
7391 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7392 snd_hda_codec_write(codec, nid, 0,
7393 AC_VERB_SET_AMP_GAIN_MUTE,
7394 mute);
7395 else if (mute != AMP_IN_MUTE(idx))
7396 snd_hda_codec_write(codec, nid, 0,
7397 AC_VERB_SET_CONNECT_SEL,
7398 idx);
7403 /* add mic boosts if needed */
7404 static int alc_auto_add_mic_boost(struct hda_codec *codec)
7406 struct alc_spec *spec = codec->spec;
7407 int err;
7408 hda_nid_t nid;
7410 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7411 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7412 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7413 "Mic Boost",
7414 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7415 if (err < 0)
7416 return err;
7418 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7419 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7420 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7421 "Front Mic Boost",
7422 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7423 if (err < 0)
7424 return err;
7426 return 0;
7429 /* almost identical with ALC880 parser... */
7430 static int alc882_parse_auto_config(struct hda_codec *codec)
7432 struct alc_spec *spec = codec->spec;
7433 int err = alc880_parse_auto_config(codec);
7435 if (err < 0)
7436 return err;
7437 else if (!err)
7438 return 0; /* no config found */
7440 err = alc_auto_add_mic_boost(codec);
7441 if (err < 0)
7442 return err;
7444 /* hack - override the init verbs */
7445 spec->init_verbs[0] = alc882_auto_init_verbs;
7447 return 1; /* config found */
7450 /* additional initialization for auto-configuration model */
7451 static void alc882_auto_init(struct hda_codec *codec)
7453 struct alc_spec *spec = codec->spec;
7454 alc882_auto_init_multi_out(codec);
7455 alc882_auto_init_hp_out(codec);
7456 alc882_auto_init_analog_input(codec);
7457 alc882_auto_init_input_src(codec);
7458 if (spec->unsol_event)
7459 alc_inithook(codec);
7462 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7464 static int patch_alc882(struct hda_codec *codec)
7466 struct alc_spec *spec;
7467 int err, board_config;
7469 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7470 if (spec == NULL)
7471 return -ENOMEM;
7473 codec->spec = spec;
7475 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7476 alc882_models,
7477 alc882_cfg_tbl);
7479 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7480 /* Pick up systems that don't supply PCI SSID */
7481 switch (codec->subsystem_id) {
7482 case 0x106b0c00: /* Mac Pro */
7483 board_config = ALC885_MACPRO;
7484 break;
7485 case 0x106b1000: /* iMac 24 */
7486 case 0x106b2800: /* AppleTV */
7487 case 0x106b3e00: /* iMac 24 Aluminium */
7488 board_config = ALC885_IMAC24;
7489 break;
7490 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7491 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7492 case 0x106b00a4: /* MacbookPro4,1 */
7493 case 0x106b2c00: /* Macbook Pro rev3 */
7494 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7495 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7496 board_config = ALC885_MBP3;
7497 break;
7498 case 0x106b3f00: /* Macbook 5,1 */
7499 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7500 * seems not working, so apparently
7501 * no perfect solution yet
7503 board_config = ALC885_MB5;
7504 break;
7505 default:
7506 /* ALC889A is handled better as ALC888-compatible */
7507 if (codec->revision_id == 0x100101 ||
7508 codec->revision_id == 0x100103) {
7509 alc_free(codec);
7510 return patch_alc883(codec);
7512 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7513 "trying auto-probe from BIOS...\n",
7514 codec->chip_name);
7515 board_config = ALC882_AUTO;
7519 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7521 if (board_config == ALC882_AUTO) {
7522 /* automatic parse from the BIOS config */
7523 err = alc882_parse_auto_config(codec);
7524 if (err < 0) {
7525 alc_free(codec);
7526 return err;
7527 } else if (!err) {
7528 printk(KERN_INFO
7529 "hda_codec: Cannot set up configuration "
7530 "from BIOS. Using base mode...\n");
7531 board_config = ALC882_3ST_DIG;
7535 err = snd_hda_attach_beep_device(codec, 0x1);
7536 if (err < 0) {
7537 alc_free(codec);
7538 return err;
7541 if (board_config != ALC882_AUTO)
7542 setup_preset(spec, &alc882_presets[board_config]);
7544 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7545 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7546 /* FIXME: setup DAC5 */
7547 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7548 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7550 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7551 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7553 if (!spec->adc_nids && spec->input_mux) {
7554 /* check whether NID 0x07 is valid */
7555 unsigned int wcap = get_wcaps(codec, 0x07);
7556 /* get type */
7557 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7558 if (wcap != AC_WID_AUD_IN) {
7559 spec->adc_nids = alc882_adc_nids_alt;
7560 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7561 spec->capsrc_nids = alc882_capsrc_nids_alt;
7562 } else {
7563 spec->adc_nids = alc882_adc_nids;
7564 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7565 spec->capsrc_nids = alc882_capsrc_nids;
7568 set_capture_mixer(spec);
7569 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7571 spec->vmaster_nid = 0x0c;
7573 codec->patch_ops = alc_patch_ops;
7574 if (board_config == ALC882_AUTO)
7575 spec->init_hook = alc882_auto_init;
7576 #ifdef CONFIG_SND_HDA_POWER_SAVE
7577 if (!spec->loopback.amplist)
7578 spec->loopback.amplist = alc882_loopbacks;
7579 #endif
7580 codec->proc_widget_hook = print_realtek_coef;
7582 return 0;
7586 * ALC883 support
7588 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7589 * configuration. Each pin widget can choose any input DACs and a mixer.
7590 * Each ADC is connected from a mixer of all inputs. This makes possible
7591 * 6-channel independent captures.
7593 * In addition, an independent DAC for the multi-playback (not used in this
7594 * driver yet).
7596 #define ALC883_DIGOUT_NID 0x06
7597 #define ALC883_DIGIN_NID 0x0a
7599 #define ALC1200_DIGOUT_NID 0x10
7601 static hda_nid_t alc883_dac_nids[4] = {
7602 /* front, rear, clfe, rear_surr */
7603 0x02, 0x03, 0x04, 0x05
7606 static hda_nid_t alc883_adc_nids[2] = {
7607 /* ADC1-2 */
7608 0x08, 0x09,
7611 static hda_nid_t alc883_adc_nids_alt[1] = {
7612 /* ADC1 */
7613 0x08,
7616 static hda_nid_t alc883_adc_nids_rev[2] = {
7617 /* ADC2-1 */
7618 0x09, 0x08
7621 #define alc889_adc_nids alc880_adc_nids
7623 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7625 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7627 #define alc889_capsrc_nids alc882_capsrc_nids
7629 /* input MUX */
7630 /* FIXME: should be a matrix-type input source selection */
7632 static struct hda_input_mux alc883_capture_source = {
7633 .num_items = 4,
7634 .items = {
7635 { "Mic", 0x0 },
7636 { "Front Mic", 0x1 },
7637 { "Line", 0x2 },
7638 { "CD", 0x4 },
7642 static struct hda_input_mux alc883_3stack_6ch_intel = {
7643 .num_items = 4,
7644 .items = {
7645 { "Mic", 0x1 },
7646 { "Front Mic", 0x0 },
7647 { "Line", 0x2 },
7648 { "CD", 0x4 },
7652 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7653 .num_items = 2,
7654 .items = {
7655 { "Mic", 0x1 },
7656 { "Line", 0x2 },
7660 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7661 .num_items = 4,
7662 .items = {
7663 { "Mic", 0x0 },
7664 { "iMic", 0x1 },
7665 { "Line", 0x2 },
7666 { "CD", 0x4 },
7670 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7671 .num_items = 2,
7672 .items = {
7673 { "Mic", 0x0 },
7674 { "Int Mic", 0x1 },
7678 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7679 .num_items = 3,
7680 .items = {
7681 { "Mic", 0x0 },
7682 { "Front Mic", 0x1 },
7683 { "Line", 0x4 },
7687 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7688 .num_items = 2,
7689 .items = {
7690 { "Mic", 0x0 },
7691 { "Line", 0x2 },
7695 static struct hda_input_mux alc889A_mb31_capture_source = {
7696 .num_items = 2,
7697 .items = {
7698 { "Mic", 0x0 },
7699 /* Front Mic (0x01) unused */
7700 { "Line", 0x2 },
7701 /* Line 2 (0x03) unused */
7702 /* CD (0x04) unsused? */
7707 * 2ch mode
7709 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7710 { 2, NULL }
7714 * 2ch mode
7716 static struct hda_verb alc883_3ST_ch2_init[] = {
7717 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7718 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7719 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7720 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7721 { } /* end */
7725 * 4ch mode
7727 static struct hda_verb alc883_3ST_ch4_init[] = {
7728 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7729 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7730 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7731 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7732 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7733 { } /* end */
7737 * 6ch mode
7739 static struct hda_verb alc883_3ST_ch6_init[] = {
7740 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7741 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7742 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7743 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7745 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7746 { } /* end */
7749 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7750 { 2, alc883_3ST_ch2_init },
7751 { 4, alc883_3ST_ch4_init },
7752 { 6, alc883_3ST_ch6_init },
7757 * 2ch mode
7759 static struct hda_verb alc883_4ST_ch2_init[] = {
7760 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7761 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7762 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7763 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7764 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7765 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7766 { } /* end */
7770 * 4ch mode
7772 static struct hda_verb alc883_4ST_ch4_init[] = {
7773 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7774 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7775 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7776 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7777 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7779 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7780 { } /* end */
7784 * 6ch mode
7786 static struct hda_verb alc883_4ST_ch6_init[] = {
7787 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7788 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7789 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7790 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7791 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7792 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7793 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7794 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7795 { } /* end */
7799 * 8ch mode
7801 static struct hda_verb alc883_4ST_ch8_init[] = {
7802 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7803 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7804 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7805 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7806 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7807 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7808 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7809 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7810 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7811 { } /* end */
7814 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7815 { 2, alc883_4ST_ch2_init },
7816 { 4, alc883_4ST_ch4_init },
7817 { 6, alc883_4ST_ch6_init },
7818 { 8, alc883_4ST_ch8_init },
7823 * 2ch mode
7825 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7826 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7827 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7828 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7829 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7830 { } /* end */
7834 * 4ch mode
7836 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7837 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7841 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7842 { } /* end */
7846 * 6ch mode
7848 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7849 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7850 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7851 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7854 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7855 { } /* end */
7858 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7859 { 2, alc883_3ST_ch2_intel_init },
7860 { 4, alc883_3ST_ch4_intel_init },
7861 { 6, alc883_3ST_ch6_intel_init },
7865 * 6ch mode
7867 static struct hda_verb alc883_sixstack_ch6_init[] = {
7868 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7869 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7870 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { } /* end */
7876 * 8ch mode
7878 static struct hda_verb alc883_sixstack_ch8_init[] = {
7879 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7880 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7882 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7883 { } /* end */
7886 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7887 { 6, alc883_sixstack_ch6_init },
7888 { 8, alc883_sixstack_ch8_init },
7891 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7892 static struct hda_verb alc889A_mb31_ch2_init[] = {
7893 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7894 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7895 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7896 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7897 { } /* end */
7900 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
7901 static struct hda_verb alc889A_mb31_ch4_init[] = {
7902 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
7903 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7905 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7906 { } /* end */
7909 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
7910 static struct hda_verb alc889A_mb31_ch5_init[] = {
7911 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
7912 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
7913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
7914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
7915 { } /* end */
7918 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
7919 static struct hda_verb alc889A_mb31_ch6_init[] = {
7920 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
7921 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
7922 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
7923 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
7924 { } /* end */
7927 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
7928 { 2, alc889A_mb31_ch2_init },
7929 { 4, alc889A_mb31_ch4_init },
7930 { 5, alc889A_mb31_ch5_init },
7931 { 6, alc889A_mb31_ch6_init },
7934 static struct hda_verb alc883_medion_eapd_verbs[] = {
7935 /* eanable EAPD on medion laptop */
7936 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7937 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7941 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7942 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7945 static struct snd_kcontrol_new alc883_base_mixer[] = {
7946 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7947 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7949 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7950 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7951 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7952 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7953 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7954 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7955 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7956 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7957 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7958 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7959 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7960 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7962 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7963 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7964 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7965 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7966 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7967 { } /* end */
7970 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7972 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7973 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7974 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7975 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7976 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7978 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7979 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7980 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7981 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7982 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7983 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7984 { } /* end */
7987 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7989 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7991 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7993 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7994 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7995 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7996 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7997 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7998 { } /* end */
8001 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8002 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8003 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8004 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8005 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8007 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8008 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8009 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8010 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8011 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8012 { } /* end */
8015 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8016 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8017 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8018 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8019 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8020 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8021 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8022 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8023 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8024 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8025 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8026 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8027 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8028 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8029 { } /* end */
8032 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8033 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8034 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8035 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8036 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8037 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8038 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8039 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8040 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8042 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8044 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8045 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8047 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8048 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8049 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8050 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8051 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8052 { } /* end */
8055 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8058 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8059 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8060 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8061 HDA_OUTPUT),
8062 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8063 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8064 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8065 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8066 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8067 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8072 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8073 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8074 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8075 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8076 { } /* end */
8079 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8080 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8081 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8082 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8083 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8084 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8085 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8086 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8087 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8090 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8094 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8096 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8097 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8098 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8099 { } /* end */
8102 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8104 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8105 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8106 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8107 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8108 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8109 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8110 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8111 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8112 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8113 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8114 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8115 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8116 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8117 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8118 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8119 { } /* end */
8122 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8123 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8125 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8126 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8127 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8131 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8132 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8133 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8134 { } /* end */
8137 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8140 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8141 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8146 { } /* end */
8149 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8150 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8151 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8152 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8156 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8157 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8158 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8159 { } /* end */
8162 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8163 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8164 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8165 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8166 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8167 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8172 { } /* end */
8175 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8176 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8177 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8178 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8179 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8180 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8181 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8182 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8184 { } /* end */
8187 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8188 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8189 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8190 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8191 HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT),
8192 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8193 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8195 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8197 { } /* end */
8200 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8201 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8202 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8203 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8204 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8205 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8206 0x0d, 1, 0x0, HDA_OUTPUT),
8207 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8208 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8209 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8210 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8211 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8212 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8213 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8217 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8222 { } /* end */
8225 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8226 /* Output mixers */
8227 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8228 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8229 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8230 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8231 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8232 HDA_OUTPUT),
8233 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8234 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8235 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8236 /* Output switches */
8237 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8238 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8239 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8240 /* Boost mixers */
8241 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8243 /* Input mixers */
8244 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8245 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8246 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8247 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8248 { } /* end */
8251 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8253 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8255 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8257 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8258 { } /* end */
8261 static struct hda_bind_ctls alc883_bind_cap_vol = {
8262 .ops = &snd_hda_bind_vol,
8263 .values = {
8264 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8265 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8270 static struct hda_bind_ctls alc883_bind_cap_switch = {
8271 .ops = &snd_hda_bind_sw,
8272 .values = {
8273 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8274 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8279 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8280 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8281 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8283 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8284 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8286 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8288 { } /* end */
8291 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8292 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8293 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8295 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8296 /* .name = "Capture Source", */
8297 .name = "Input Source",
8298 .count = 1,
8299 .info = alc_mux_enum_info,
8300 .get = alc_mux_enum_get,
8301 .put = alc_mux_enum_put,
8303 { } /* end */
8306 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8308 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8309 .name = "Channel Mode",
8310 .info = alc_ch_mode_info,
8311 .get = alc_ch_mode_get,
8312 .put = alc_ch_mode_put,
8314 { } /* end */
8317 static struct hda_verb alc883_init_verbs[] = {
8318 /* ADC1: mute amp left and right */
8319 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8320 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8321 /* ADC2: mute amp left and right */
8322 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8324 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8328 /* Rear mixer */
8329 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8330 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8331 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8332 /* CLFE mixer */
8333 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8334 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8336 /* Side mixer */
8337 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8338 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8341 /* mute analog input loopbacks */
8342 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8346 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8348 /* Front Pin: output 0 (0x0c) */
8349 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8350 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8351 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8352 /* Rear Pin: output 1 (0x0d) */
8353 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8354 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8355 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8356 /* CLFE Pin: output 2 (0x0e) */
8357 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8358 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8359 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8360 /* Side Pin: output 3 (0x0f) */
8361 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8362 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8363 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8364 /* Mic (rear) pin: input vref at 80% */
8365 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8366 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8367 /* Front Mic pin: input vref at 80% */
8368 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8369 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8370 /* Line In pin: input */
8371 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8372 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8373 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8374 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8375 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8376 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8377 /* CD pin widget for input */
8378 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8380 /* FIXME: use matrix-type input source selection */
8381 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8382 /* Input mixer2 */
8383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8385 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8386 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8387 /* Input mixer3 */
8388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8390 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8391 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8395 /* toggle speaker-output according to the hp-jack state */
8396 static void alc883_mitac_init_hook(struct hda_codec *codec)
8398 struct alc_spec *spec = codec->spec;
8400 spec->autocfg.hp_pins[0] = 0x15;
8401 spec->autocfg.speaker_pins[0] = 0x14;
8402 spec->autocfg.speaker_pins[1] = 0x17;
8403 alc_automute_amp(codec);
8406 /* auto-toggle front mic */
8408 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8410 unsigned int present;
8411 unsigned char bits;
8413 present = snd_hda_codec_read(codec, 0x18, 0,
8414 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8415 bits = present ? HDA_AMP_MUTE : 0;
8416 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8420 static struct hda_verb alc883_mitac_verbs[] = {
8421 /* HP */
8422 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8424 /* Subwoofer */
8425 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8426 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8428 /* enable unsolicited event */
8429 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8430 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8432 { } /* end */
8435 static struct hda_verb alc883_clevo_m720_verbs[] = {
8436 /* HP */
8437 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8439 /* Int speaker */
8440 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8443 /* enable unsolicited event */
8444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8445 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8447 { } /* end */
8450 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8451 /* HP */
8452 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8454 /* Subwoofer */
8455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8458 /* enable unsolicited event */
8459 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8461 { } /* end */
8464 static struct hda_verb alc883_targa_verbs[] = {
8465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8469 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8471 /* Connect Line-Out side jack (SPDIF) to Side */
8472 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8473 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8474 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8475 /* Connect Mic jack to CLFE */
8476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8477 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8479 /* Connect Line-in jack to Surround */
8480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8483 /* Connect HP out jack to Front */
8484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8488 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8490 { } /* end */
8493 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8495 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8496 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8497 { } /* end */
8500 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8501 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8503 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8505 { } /* end */
8508 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8511 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8512 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8513 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8514 { } /* end */
8517 static struct hda_verb alc883_haier_w66_verbs[] = {
8518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8523 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8524 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8525 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8526 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8527 { } /* end */
8530 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8531 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8533 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8535 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8537 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8538 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8539 { } /* end */
8542 static struct hda_verb alc888_6st_dell_verbs[] = {
8543 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8547 static struct hda_verb alc883_vaiott_verbs[] = {
8548 /* HP */
8549 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8550 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8552 /* enable unsolicited event */
8553 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8555 { } /* end */
8558 static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8560 struct alc_spec *spec = codec->spec;
8562 spec->autocfg.hp_pins[0] = 0x1b;
8563 spec->autocfg.speaker_pins[0] = 0x14;
8564 spec->autocfg.speaker_pins[1] = 0x16;
8565 spec->autocfg.speaker_pins[2] = 0x18;
8566 alc_automute_amp(codec);
8569 static struct hda_verb alc888_3st_hp_verbs[] = {
8570 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8571 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8572 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8573 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8574 { } /* end */
8578 * 2ch mode
8580 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8581 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8582 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8583 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8584 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8585 { } /* end */
8589 * 4ch mode
8591 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8592 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8593 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8594 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8595 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8596 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8597 { } /* end */
8601 * 6ch mode
8603 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8606 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8607 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8608 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8609 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8610 { } /* end */
8613 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8614 { 2, alc888_3st_hp_2ch_init },
8615 { 4, alc888_3st_hp_4ch_init },
8616 { 6, alc888_3st_hp_6ch_init },
8619 /* toggle front-jack and RCA according to the hp-jack state */
8620 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8622 unsigned int present;
8624 present = snd_hda_codec_read(codec, 0x1b, 0,
8625 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8626 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8627 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8628 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8629 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8632 /* toggle RCA according to the front-jack state */
8633 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8635 unsigned int present;
8637 present = snd_hda_codec_read(codec, 0x14, 0,
8638 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8639 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8640 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8643 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8644 unsigned int res)
8646 if ((res >> 26) == ALC880_HP_EVENT)
8647 alc888_lenovo_ms7195_front_automute(codec);
8648 if ((res >> 26) == ALC880_FRONT_EVENT)
8649 alc888_lenovo_ms7195_rca_automute(codec);
8652 static struct hda_verb alc883_medion_md2_verbs[] = {
8653 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8654 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8658 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8659 { } /* end */
8662 /* toggle speaker-output according to the hp-jack state */
8663 static void alc883_medion_md2_init_hook(struct hda_codec *codec)
8665 struct alc_spec *spec = codec->spec;
8667 spec->autocfg.hp_pins[0] = 0x14;
8668 spec->autocfg.speaker_pins[0] = 0x15;
8669 alc_automute_amp(codec);
8672 /* toggle speaker-output according to the hp-jack state */
8673 #define alc883_targa_init_hook alc882_targa_init_hook
8674 #define alc883_targa_unsol_event alc882_targa_unsol_event
8676 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8678 unsigned int present;
8680 present = snd_hda_codec_read(codec, 0x18, 0,
8681 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8682 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8683 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8686 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8688 struct alc_spec *spec = codec->spec;
8690 spec->autocfg.hp_pins[0] = 0x15;
8691 spec->autocfg.speaker_pins[0] = 0x14;
8692 alc_automute_amp(codec);
8693 alc883_clevo_m720_mic_automute(codec);
8696 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8697 unsigned int res)
8699 switch (res >> 26) {
8700 case ALC880_MIC_EVENT:
8701 alc883_clevo_m720_mic_automute(codec);
8702 break;
8703 default:
8704 alc_automute_amp_unsol_event(codec, res);
8705 break;
8709 /* toggle speaker-output according to the hp-jack state */
8710 static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec)
8712 struct alc_spec *spec = codec->spec;
8714 spec->autocfg.hp_pins[0] = 0x14;
8715 spec->autocfg.speaker_pins[0] = 0x15;
8716 alc_automute_amp(codec);
8719 static void alc883_haier_w66_init_hook(struct hda_codec *codec)
8721 struct alc_spec *spec = codec->spec;
8723 spec->autocfg.hp_pins[0] = 0x1b;
8724 spec->autocfg.speaker_pins[0] = 0x14;
8725 alc_automute_amp(codec);
8728 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8730 unsigned int present;
8731 unsigned char bits;
8733 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8734 & AC_PINSENSE_PRESENCE;
8735 bits = present ? HDA_AMP_MUTE : 0;
8736 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8737 HDA_AMP_MUTE, bits);
8740 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8742 unsigned int present;
8743 unsigned char bits;
8745 present = snd_hda_codec_read(codec, 0x1b, 0,
8746 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8747 bits = present ? HDA_AMP_MUTE : 0;
8748 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8749 HDA_AMP_MUTE, bits);
8750 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8751 HDA_AMP_MUTE, bits);
8754 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8755 unsigned int res)
8757 if ((res >> 26) == ALC880_HP_EVENT)
8758 alc883_lenovo_101e_all_automute(codec);
8759 if ((res >> 26) == ALC880_FRONT_EVENT)
8760 alc883_lenovo_101e_ispeaker_automute(codec);
8763 /* toggle speaker-output according to the hp-jack state */
8764 static void alc883_acer_aspire_init_hook(struct hda_codec *codec)
8766 struct alc_spec *spec = codec->spec;
8768 spec->autocfg.hp_pins[0] = 0x14;
8769 spec->autocfg.speaker_pins[0] = 0x15;
8770 spec->autocfg.speaker_pins[1] = 0x16;
8771 alc_automute_amp(codec);
8774 static struct hda_verb alc883_acer_eapd_verbs[] = {
8775 /* HP Pin: output 0 (0x0c) */
8776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8778 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* Front Pin: output 0 (0x0c) */
8780 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8781 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8782 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8783 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8784 /* eanable EAPD on medion laptop */
8785 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8786 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8787 /* enable unsolicited event */
8788 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8792 static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8794 struct alc_spec *spec = codec->spec;
8796 spec->autocfg.hp_pins[0] = 0x1b;
8797 spec->autocfg.speaker_pins[0] = 0x14;
8798 spec->autocfg.speaker_pins[1] = 0x15;
8799 spec->autocfg.speaker_pins[2] = 0x16;
8800 spec->autocfg.speaker_pins[3] = 0x17;
8801 alc_automute_amp(codec);
8804 static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8806 struct alc_spec *spec = codec->spec;
8808 spec->autocfg.hp_pins[0] = 0x1b;
8809 spec->autocfg.speaker_pins[0] = 0x14;
8810 spec->autocfg.speaker_pins[1] = 0x15;
8811 spec->autocfg.speaker_pins[2] = 0x16;
8812 spec->autocfg.speaker_pins[3] = 0x17;
8813 spec->autocfg.speaker_pins[4] = 0x1a;
8814 alc_automute_amp(codec);
8817 static void alc883_vaiott_init_hook(struct hda_codec *codec)
8819 struct alc_spec *spec = codec->spec;
8821 spec->autocfg.hp_pins[0] = 0x15;
8822 spec->autocfg.speaker_pins[0] = 0x14;
8823 spec->autocfg.speaker_pins[1] = 0x17;
8824 alc_automute_amp(codec);
8828 * generic initialization of ADC, input mixers and output mixers
8830 static struct hda_verb alc883_auto_init_verbs[] = {
8832 * Unmute ADC0-2 and set the default input to mic-in
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8835 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8837 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8840 * mixer widget
8841 * Note: PASD motherboards uses the Line In 2 as the input for
8842 * front panel mic (mic 2)
8844 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8845 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8852 * Set up output mixers (0x0c - 0x0f)
8854 /* set vol=0 to output mixers */
8855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8856 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8857 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8858 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8859 /* set up input amps for analog loopback */
8860 /* Amp Indices: DAC = 0, mixer = 1 */
8861 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8862 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8863 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8864 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8865 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8866 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8867 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8868 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8869 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8870 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8872 /* FIXME: use matrix-type input source selection */
8873 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8874 /* Input mixer1 */
8875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8876 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8877 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8878 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8879 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8880 /* Input mixer2 */
8881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8882 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8884 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8890 static struct hda_verb alc888_asus_m90v_verbs[] = {
8891 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8892 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8893 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8894 /* enable unsolicited event */
8895 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8896 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8897 { } /* end */
8900 static void alc883_nb_mic_automute(struct hda_codec *codec)
8902 unsigned int present;
8904 present = snd_hda_codec_read(codec, 0x18, 0,
8905 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8906 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8907 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8908 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8909 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8912 static void alc883_M90V_init_hook(struct hda_codec *codec)
8914 struct alc_spec *spec = codec->spec;
8916 spec->autocfg.hp_pins[0] = 0x1b;
8917 spec->autocfg.speaker_pins[0] = 0x14;
8918 spec->autocfg.speaker_pins[1] = 0x15;
8919 spec->autocfg.speaker_pins[2] = 0x16;
8920 alc_automute_pin(codec);
8923 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8924 unsigned int res)
8926 switch (res >> 26) {
8927 case ALC880_MIC_EVENT:
8928 alc883_nb_mic_automute(codec);
8929 break;
8930 default:
8931 alc_sku_unsol_event(codec, res);
8932 break;
8936 static void alc883_mode2_inithook(struct hda_codec *codec)
8938 alc883_M90V_init_hook(codec);
8939 alc883_nb_mic_automute(codec);
8942 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8943 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8944 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8945 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8947 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8948 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8949 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8950 /* enable unsolicited event */
8951 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8952 { } /* end */
8955 static void alc883_eee1601_inithook(struct hda_codec *codec)
8957 struct alc_spec *spec = codec->spec;
8959 spec->autocfg.hp_pins[0] = 0x14;
8960 spec->autocfg.speaker_pins[0] = 0x1b;
8961 alc_automute_pin(codec);
8964 static struct hda_verb alc889A_mb31_verbs[] = {
8965 /* Init rear pin (used as headphone output) */
8966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
8968 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8969 /* Init line pin (used as output in 4ch and 6ch mode) */
8970 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
8971 /* Init line 2 pin (used as headphone out by default) */
8972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
8973 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
8974 { } /* end */
8977 /* Mute speakers according to the headphone jack state */
8978 static void alc889A_mb31_automute(struct hda_codec *codec)
8980 unsigned int present;
8982 /* Mute only in 2ch or 4ch mode */
8983 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
8984 == 0x00) {
8985 present = snd_hda_codec_read(codec, 0x15, 0,
8986 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
8987 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8988 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8989 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8990 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8994 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
8996 if ((res >> 26) == ALC880_HP_EVENT)
8997 alc889A_mb31_automute(codec);
9000 #ifdef CONFIG_SND_HDA_POWER_SAVE
9001 #define alc883_loopbacks alc880_loopbacks
9002 #endif
9004 /* pcm configuration: identical with ALC880 */
9005 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
9006 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
9007 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
9008 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
9009 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
9012 * configuration and preset
9014 static const char *alc883_models[ALC883_MODEL_LAST] = {
9015 [ALC883_3ST_2ch_DIG] = "3stack-dig",
9016 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9017 [ALC883_3ST_6ch] = "3stack-6ch",
9018 [ALC883_6ST_DIG] = "6stack-dig",
9019 [ALC883_TARGA_DIG] = "targa-dig",
9020 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9021 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9022 [ALC883_ACER] = "acer",
9023 [ALC883_ACER_ASPIRE] = "acer-aspire",
9024 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9025 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9026 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9027 [ALC883_MEDION] = "medion",
9028 [ALC883_MEDION_MD2] = "medion-md2",
9029 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9030 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9031 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9032 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9033 [ALC888_LENOVO_SKY] = "lenovo-sky",
9034 [ALC883_HAIER_W66] = "haier-w66",
9035 [ALC888_3ST_HP] = "3stack-hp",
9036 [ALC888_6ST_DELL] = "6stack-dell",
9037 [ALC883_MITAC] = "mitac",
9038 [ALC883_CLEVO_M720] = "clevo-m720",
9039 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9040 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9041 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9042 [ALC1200_ASUS_P5Q] = "asus-p5q",
9043 [ALC889A_MB31] = "mb31",
9044 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9045 [ALC883_AUTO] = "auto",
9048 static struct snd_pci_quirk alc883_cfg_tbl[] = {
9049 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
9050 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9051 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9052 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9053 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9054 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9055 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9056 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9057 ALC888_ACER_ASPIRE_4930G),
9058 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9059 ALC888_ACER_ASPIRE_4930G),
9060 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9061 ALC888_ACER_ASPIRE_8930G),
9062 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9063 ALC888_ACER_ASPIRE_8930G),
9064 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO),
9065 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO),
9066 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9067 ALC888_ACER_ASPIRE_4930G),
9068 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9069 ALC888_ACER_ASPIRE_6530G),
9070 /* default Acer -- disabled as it causes more problems.
9071 * model=auto should work fine now
9073 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9074 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9075 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9076 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9077 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9078 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9079 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9080 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9081 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9082 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9083 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9084 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9085 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9086 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9087 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
9088 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9089 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9090 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9091 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9092 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9093 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
9094 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9095 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9096 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9097 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
9098 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9099 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9100 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9101 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9102 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9103 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9104 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9105 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9106 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9107 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9108 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9109 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9110 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9111 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9112 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9113 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9114 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9115 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9116 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9117 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9118 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9119 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9120 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9121 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9122 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9123 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9124 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9125 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9126 ALC883_FUJITSU_PI2515),
9127 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9128 ALC888_FUJITSU_XA3530),
9129 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9130 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9131 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9132 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9133 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9134 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9135 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9136 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9137 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9138 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9139 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9140 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9141 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
9142 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9143 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9147 static hda_nid_t alc883_slave_dig_outs[] = {
9148 ALC1200_DIGOUT_NID, 0,
9151 static hda_nid_t alc1200_slave_dig_outs[] = {
9152 ALC883_DIGOUT_NID, 0,
9155 static struct alc_config_preset alc883_presets[] = {
9156 [ALC883_3ST_2ch_DIG] = {
9157 .mixers = { alc883_3ST_2ch_mixer },
9158 .init_verbs = { alc883_init_verbs },
9159 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9160 .dac_nids = alc883_dac_nids,
9161 .dig_out_nid = ALC883_DIGOUT_NID,
9162 .dig_in_nid = ALC883_DIGIN_NID,
9163 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9164 .channel_mode = alc883_3ST_2ch_modes,
9165 .input_mux = &alc883_capture_source,
9167 [ALC883_3ST_6ch_DIG] = {
9168 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9169 .init_verbs = { alc883_init_verbs },
9170 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9171 .dac_nids = alc883_dac_nids,
9172 .dig_out_nid = ALC883_DIGOUT_NID,
9173 .dig_in_nid = ALC883_DIGIN_NID,
9174 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9175 .channel_mode = alc883_3ST_6ch_modes,
9176 .need_dac_fix = 1,
9177 .input_mux = &alc883_capture_source,
9179 [ALC883_3ST_6ch] = {
9180 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9181 .init_verbs = { alc883_init_verbs },
9182 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9183 .dac_nids = alc883_dac_nids,
9184 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9185 .channel_mode = alc883_3ST_6ch_modes,
9186 .need_dac_fix = 1,
9187 .input_mux = &alc883_capture_source,
9189 [ALC883_3ST_6ch_INTEL] = {
9190 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9191 .init_verbs = { alc883_init_verbs },
9192 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9193 .dac_nids = alc883_dac_nids,
9194 .dig_out_nid = ALC883_DIGOUT_NID,
9195 .dig_in_nid = ALC883_DIGIN_NID,
9196 .slave_dig_outs = alc883_slave_dig_outs,
9197 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9198 .channel_mode = alc883_3ST_6ch_intel_modes,
9199 .need_dac_fix = 1,
9200 .input_mux = &alc883_3stack_6ch_intel,
9202 [ALC883_6ST_DIG] = {
9203 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9204 .init_verbs = { alc883_init_verbs },
9205 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9206 .dac_nids = alc883_dac_nids,
9207 .dig_out_nid = ALC883_DIGOUT_NID,
9208 .dig_in_nid = ALC883_DIGIN_NID,
9209 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9210 .channel_mode = alc883_sixstack_modes,
9211 .input_mux = &alc883_capture_source,
9213 [ALC883_TARGA_DIG] = {
9214 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9215 .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
9216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9217 .dac_nids = alc883_dac_nids,
9218 .dig_out_nid = ALC883_DIGOUT_NID,
9219 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9220 .channel_mode = alc883_3ST_6ch_modes,
9221 .need_dac_fix = 1,
9222 .input_mux = &alc883_capture_source,
9223 .unsol_event = alc883_targa_unsol_event,
9224 .init_hook = alc883_targa_init_hook,
9226 [ALC883_TARGA_2ch_DIG] = {
9227 .mixers = { alc883_targa_2ch_mixer},
9228 .init_verbs = { alc883_init_verbs, alc883_targa_verbs},
9229 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9230 .dac_nids = alc883_dac_nids,
9231 .adc_nids = alc883_adc_nids_alt,
9232 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9233 .dig_out_nid = ALC883_DIGOUT_NID,
9234 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9235 .channel_mode = alc883_3ST_2ch_modes,
9236 .input_mux = &alc883_capture_source,
9237 .unsol_event = alc883_targa_unsol_event,
9238 .init_hook = alc883_targa_init_hook,
9240 [ALC883_TARGA_8ch_DIG] = {
9241 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9242 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9243 alc883_targa_verbs },
9244 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9245 .dac_nids = alc883_dac_nids,
9246 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9247 .adc_nids = alc883_adc_nids_rev,
9248 .capsrc_nids = alc883_capsrc_nids_rev,
9249 .dig_out_nid = ALC883_DIGOUT_NID,
9250 .dig_in_nid = ALC883_DIGIN_NID,
9251 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9252 .channel_mode = alc883_4ST_8ch_modes,
9253 .need_dac_fix = 1,
9254 .input_mux = &alc883_capture_source,
9255 .unsol_event = alc883_targa_unsol_event,
9256 .init_hook = alc883_targa_init_hook,
9258 [ALC883_ACER] = {
9259 .mixers = { alc883_base_mixer },
9260 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9261 * and the headphone jack. Turn this on and rely on the
9262 * standard mute methods whenever the user wants to turn
9263 * these outputs off.
9265 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9266 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9267 .dac_nids = alc883_dac_nids,
9268 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9269 .channel_mode = alc883_3ST_2ch_modes,
9270 .input_mux = &alc883_capture_source,
9272 [ALC883_ACER_ASPIRE] = {
9273 .mixers = { alc883_acer_aspire_mixer },
9274 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9275 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9276 .dac_nids = alc883_dac_nids,
9277 .dig_out_nid = ALC883_DIGOUT_NID,
9278 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9279 .channel_mode = alc883_3ST_2ch_modes,
9280 .input_mux = &alc883_capture_source,
9281 .unsol_event = alc_automute_amp_unsol_event,
9282 .init_hook = alc883_acer_aspire_init_hook,
9284 [ALC888_ACER_ASPIRE_4930G] = {
9285 .mixers = { alc888_base_mixer,
9286 alc883_chmode_mixer },
9287 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9288 alc888_acer_aspire_4930g_verbs },
9289 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9290 .dac_nids = alc883_dac_nids,
9291 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9292 .adc_nids = alc883_adc_nids_rev,
9293 .capsrc_nids = alc883_capsrc_nids_rev,
9294 .dig_out_nid = ALC883_DIGOUT_NID,
9295 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9296 .channel_mode = alc883_3ST_6ch_modes,
9297 .need_dac_fix = 1,
9298 .num_mux_defs =
9299 ARRAY_SIZE(alc888_2_capture_sources),
9300 .input_mux = alc888_2_capture_sources,
9301 .unsol_event = alc_automute_amp_unsol_event,
9302 .init_hook = alc888_acer_aspire_4930g_init_hook,
9304 [ALC888_ACER_ASPIRE_6530G] = {
9305 .mixers = { alc888_acer_aspire_6530_mixer },
9306 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9307 alc888_acer_aspire_6530g_verbs },
9308 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9309 .dac_nids = alc883_dac_nids,
9310 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9311 .adc_nids = alc883_adc_nids_rev,
9312 .capsrc_nids = alc883_capsrc_nids_rev,
9313 .dig_out_nid = ALC883_DIGOUT_NID,
9314 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9315 .channel_mode = alc883_3ST_2ch_modes,
9316 .num_mux_defs =
9317 ARRAY_SIZE(alc888_2_capture_sources),
9318 .input_mux = alc888_acer_aspire_6530_sources,
9319 .unsol_event = alc_automute_amp_unsol_event,
9320 .init_hook = alc888_acer_aspire_4930g_init_hook,
9322 [ALC888_ACER_ASPIRE_8930G] = {
9323 .mixers = { alc888_base_mixer,
9324 alc883_chmode_mixer },
9325 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9326 alc889_acer_aspire_8930g_verbs },
9327 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9328 .dac_nids = alc883_dac_nids,
9329 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9330 .adc_nids = alc889_adc_nids,
9331 .capsrc_nids = alc889_capsrc_nids,
9332 .dig_out_nid = ALC883_DIGOUT_NID,
9333 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9334 .channel_mode = alc883_3ST_6ch_modes,
9335 .need_dac_fix = 1,
9336 .const_channel_count = 6,
9337 .num_mux_defs =
9338 ARRAY_SIZE(alc889_capture_sources),
9339 .input_mux = alc889_capture_sources,
9340 .unsol_event = alc_automute_amp_unsol_event,
9341 .init_hook = alc889_acer_aspire_8930g_init_hook,
9343 [ALC883_MEDION] = {
9344 .mixers = { alc883_fivestack_mixer,
9345 alc883_chmode_mixer },
9346 .init_verbs = { alc883_init_verbs,
9347 alc883_medion_eapd_verbs },
9348 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9349 .dac_nids = alc883_dac_nids,
9350 .adc_nids = alc883_adc_nids_alt,
9351 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9352 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9353 .channel_mode = alc883_sixstack_modes,
9354 .input_mux = &alc883_capture_source,
9356 [ALC883_MEDION_MD2] = {
9357 .mixers = { alc883_medion_md2_mixer},
9358 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9359 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9360 .dac_nids = alc883_dac_nids,
9361 .dig_out_nid = ALC883_DIGOUT_NID,
9362 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9363 .channel_mode = alc883_3ST_2ch_modes,
9364 .input_mux = &alc883_capture_source,
9365 .unsol_event = alc_automute_amp_unsol_event,
9366 .init_hook = alc883_medion_md2_init_hook,
9368 [ALC883_LAPTOP_EAPD] = {
9369 .mixers = { alc883_base_mixer },
9370 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9371 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9372 .dac_nids = alc883_dac_nids,
9373 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9374 .channel_mode = alc883_3ST_2ch_modes,
9375 .input_mux = &alc883_capture_source,
9377 [ALC883_CLEVO_M720] = {
9378 .mixers = { alc883_clevo_m720_mixer },
9379 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9380 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9381 .dac_nids = alc883_dac_nids,
9382 .dig_out_nid = ALC883_DIGOUT_NID,
9383 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9384 .channel_mode = alc883_3ST_2ch_modes,
9385 .input_mux = &alc883_capture_source,
9386 .unsol_event = alc883_clevo_m720_unsol_event,
9387 .init_hook = alc883_clevo_m720_init_hook,
9389 [ALC883_LENOVO_101E_2ch] = {
9390 .mixers = { alc883_lenovo_101e_2ch_mixer},
9391 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9392 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9393 .dac_nids = alc883_dac_nids,
9394 .adc_nids = alc883_adc_nids_alt,
9395 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9396 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9397 .channel_mode = alc883_3ST_2ch_modes,
9398 .input_mux = &alc883_lenovo_101e_capture_source,
9399 .unsol_event = alc883_lenovo_101e_unsol_event,
9400 .init_hook = alc883_lenovo_101e_all_automute,
9402 [ALC883_LENOVO_NB0763] = {
9403 .mixers = { alc883_lenovo_nb0763_mixer },
9404 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9405 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9406 .dac_nids = alc883_dac_nids,
9407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9408 .channel_mode = alc883_3ST_2ch_modes,
9409 .need_dac_fix = 1,
9410 .input_mux = &alc883_lenovo_nb0763_capture_source,
9411 .unsol_event = alc_automute_amp_unsol_event,
9412 .init_hook = alc883_medion_md2_init_hook,
9414 [ALC888_LENOVO_MS7195_DIG] = {
9415 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9416 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9417 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9418 .dac_nids = alc883_dac_nids,
9419 .dig_out_nid = ALC883_DIGOUT_NID,
9420 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9421 .channel_mode = alc883_3ST_6ch_modes,
9422 .need_dac_fix = 1,
9423 .input_mux = &alc883_capture_source,
9424 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9425 .init_hook = alc888_lenovo_ms7195_front_automute,
9427 [ALC883_HAIER_W66] = {
9428 .mixers = { alc883_targa_2ch_mixer},
9429 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9430 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9431 .dac_nids = alc883_dac_nids,
9432 .dig_out_nid = ALC883_DIGOUT_NID,
9433 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9434 .channel_mode = alc883_3ST_2ch_modes,
9435 .input_mux = &alc883_capture_source,
9436 .unsol_event = alc_automute_amp_unsol_event,
9437 .init_hook = alc883_haier_w66_init_hook,
9439 [ALC888_3ST_HP] = {
9440 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9441 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
9442 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9443 .dac_nids = alc883_dac_nids,
9444 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
9445 .channel_mode = alc888_3st_hp_modes,
9446 .need_dac_fix = 1,
9447 .input_mux = &alc883_capture_source,
9448 .unsol_event = alc_automute_amp_unsol_event,
9449 .init_hook = alc888_3st_hp_init_hook,
9451 [ALC888_6ST_DELL] = {
9452 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9453 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
9454 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9455 .dac_nids = alc883_dac_nids,
9456 .dig_out_nid = ALC883_DIGOUT_NID,
9457 .dig_in_nid = ALC883_DIGIN_NID,
9458 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9459 .channel_mode = alc883_sixstack_modes,
9460 .input_mux = &alc883_capture_source,
9461 .unsol_event = alc_automute_amp_unsol_event,
9462 .init_hook = alc888_6st_dell_init_hook,
9464 [ALC883_MITAC] = {
9465 .mixers = { alc883_mitac_mixer },
9466 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
9467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9468 .dac_nids = alc883_dac_nids,
9469 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9470 .channel_mode = alc883_3ST_2ch_modes,
9471 .input_mux = &alc883_capture_source,
9472 .unsol_event = alc_automute_amp_unsol_event,
9473 .init_hook = alc883_mitac_init_hook,
9475 [ALC883_FUJITSU_PI2515] = {
9476 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
9477 .init_verbs = { alc883_init_verbs,
9478 alc883_2ch_fujitsu_pi2515_verbs},
9479 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9480 .dac_nids = alc883_dac_nids,
9481 .dig_out_nid = ALC883_DIGOUT_NID,
9482 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9483 .channel_mode = alc883_3ST_2ch_modes,
9484 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9485 .unsol_event = alc_automute_amp_unsol_event,
9486 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook,
9488 [ALC888_FUJITSU_XA3530] = {
9489 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
9490 .init_verbs = { alc883_init_verbs,
9491 alc888_fujitsu_xa3530_verbs },
9492 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9493 .dac_nids = alc883_dac_nids,
9494 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9495 .adc_nids = alc883_adc_nids_rev,
9496 .capsrc_nids = alc883_capsrc_nids_rev,
9497 .dig_out_nid = ALC883_DIGOUT_NID,
9498 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
9499 .channel_mode = alc888_4ST_8ch_intel_modes,
9500 .num_mux_defs =
9501 ARRAY_SIZE(alc888_2_capture_sources),
9502 .input_mux = alc888_2_capture_sources,
9503 .unsol_event = alc_automute_amp_unsol_event,
9504 .init_hook = alc888_fujitsu_xa3530_init_hook,
9506 [ALC888_LENOVO_SKY] = {
9507 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
9508 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
9509 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9510 .dac_nids = alc883_dac_nids,
9511 .dig_out_nid = ALC883_DIGOUT_NID,
9512 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9513 .channel_mode = alc883_sixstack_modes,
9514 .need_dac_fix = 1,
9515 .input_mux = &alc883_lenovo_sky_capture_source,
9516 .unsol_event = alc_automute_amp_unsol_event,
9517 .init_hook = alc888_lenovo_sky_init_hook,
9519 [ALC888_ASUS_M90V] = {
9520 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9521 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
9522 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9523 .dac_nids = alc883_dac_nids,
9524 .dig_out_nid = ALC883_DIGOUT_NID,
9525 .dig_in_nid = ALC883_DIGIN_NID,
9526 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9527 .channel_mode = alc883_3ST_6ch_modes,
9528 .need_dac_fix = 1,
9529 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9530 .unsol_event = alc883_mode2_unsol_event,
9531 .init_hook = alc883_mode2_inithook,
9533 [ALC888_ASUS_EEE1601] = {
9534 .mixers = { alc883_asus_eee1601_mixer },
9535 .cap_mixer = alc883_asus_eee1601_cap_mixer,
9536 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
9537 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9538 .dac_nids = alc883_dac_nids,
9539 .dig_out_nid = ALC883_DIGOUT_NID,
9540 .dig_in_nid = ALC883_DIGIN_NID,
9541 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9542 .channel_mode = alc883_3ST_2ch_modes,
9543 .need_dac_fix = 1,
9544 .input_mux = &alc883_asus_eee1601_capture_source,
9545 .unsol_event = alc_sku_unsol_event,
9546 .init_hook = alc883_eee1601_inithook,
9548 [ALC1200_ASUS_P5Q] = {
9549 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9550 .init_verbs = { alc883_init_verbs },
9551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9552 .dac_nids = alc883_dac_nids,
9553 .dig_out_nid = ALC1200_DIGOUT_NID,
9554 .dig_in_nid = ALC883_DIGIN_NID,
9555 .slave_dig_outs = alc1200_slave_dig_outs,
9556 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9557 .channel_mode = alc883_sixstack_modes,
9558 .input_mux = &alc883_capture_source,
9560 [ALC889A_MB31] = {
9561 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
9562 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
9563 alc880_gpio1_init_verbs },
9564 .adc_nids = alc883_adc_nids,
9565 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
9566 .dac_nids = alc883_dac_nids,
9567 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9568 .channel_mode = alc889A_mb31_6ch_modes,
9569 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
9570 .input_mux = &alc889A_mb31_capture_source,
9571 .dig_out_nid = ALC883_DIGOUT_NID,
9572 .unsol_event = alc889A_mb31_unsol_event,
9573 .init_hook = alc889A_mb31_automute,
9575 [ALC883_SONY_VAIO_TT] = {
9576 .mixers = { alc883_vaiott_mixer },
9577 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
9578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9579 .dac_nids = alc883_dac_nids,
9580 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9581 .channel_mode = alc883_3ST_2ch_modes,
9582 .input_mux = &alc883_capture_source,
9583 .unsol_event = alc_automute_amp_unsol_event,
9584 .init_hook = alc883_vaiott_init_hook,
9590 * BIOS auto configuration
9592 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9593 hda_nid_t nid, int pin_type,
9594 int dac_idx)
9596 /* set as output */
9597 struct alc_spec *spec = codec->spec;
9598 int idx;
9600 alc_set_pin_output(codec, nid, pin_type);
9601 if (spec->multiout.dac_nids[dac_idx] == 0x25)
9602 idx = 4;
9603 else
9604 idx = spec->multiout.dac_nids[dac_idx] - 2;
9605 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9609 static void alc883_auto_init_multi_out(struct hda_codec *codec)
9611 struct alc_spec *spec = codec->spec;
9612 int i;
9614 for (i = 0; i <= HDA_SIDE; i++) {
9615 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9616 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9617 if (nid)
9618 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
9623 static void alc883_auto_init_hp_out(struct hda_codec *codec)
9625 struct alc_spec *spec = codec->spec;
9626 hda_nid_t pin;
9628 pin = spec->autocfg.hp_pins[0];
9629 if (pin) /* connect to front */
9630 /* use dac 0 */
9631 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9632 pin = spec->autocfg.speaker_pins[0];
9633 if (pin)
9634 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9637 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
9638 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9640 static void alc883_auto_init_analog_input(struct hda_codec *codec)
9642 struct alc_spec *spec = codec->spec;
9643 int i;
9645 for (i = 0; i < AUTO_PIN_LAST; i++) {
9646 hda_nid_t nid = spec->autocfg.input_pins[i];
9647 if (alc883_is_input_pin(nid)) {
9648 alc_set_input_pin(codec, nid, i);
9649 if (nid != ALC883_PIN_CD_NID &&
9650 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
9651 snd_hda_codec_write(codec, nid, 0,
9652 AC_VERB_SET_AMP_GAIN_MUTE,
9653 AMP_OUT_MUTE);
9658 #define alc883_auto_init_input_src alc882_auto_init_input_src
9660 /* almost identical with ALC880 parser... */
9661 static int alc883_parse_auto_config(struct hda_codec *codec)
9663 struct alc_spec *spec = codec->spec;
9664 int err = alc880_parse_auto_config(codec);
9665 struct auto_pin_cfg *cfg = &spec->autocfg;
9666 int i;
9668 if (err < 0)
9669 return err;
9670 else if (!err)
9671 return 0; /* no config found */
9673 err = alc_auto_add_mic_boost(codec);
9674 if (err < 0)
9675 return err;
9677 /* hack - override the init verbs */
9678 spec->init_verbs[0] = alc883_auto_init_verbs;
9680 /* setup input_mux for ALC889 */
9681 if (codec->vendor_id == 0x10ec0889) {
9682 /* digital-mic input pin is excluded in alc880_auto_create..()
9683 * because it's under 0x18
9685 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
9686 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
9687 struct hda_input_mux *imux = &spec->private_imux[0];
9688 for (i = 1; i < 3; i++)
9689 memcpy(&spec->private_imux[i],
9690 &spec->private_imux[0],
9691 sizeof(spec->private_imux[0]));
9692 imux->items[imux->num_items].label = "Int DMic";
9693 imux->items[imux->num_items].index = 0x0b;
9694 imux->num_items++;
9695 spec->num_mux_defs = 3;
9696 spec->input_mux = spec->private_imux;
9700 return 1; /* config found */
9703 /* additional initialization for auto-configuration model */
9704 static void alc883_auto_init(struct hda_codec *codec)
9706 struct alc_spec *spec = codec->spec;
9707 alc883_auto_init_multi_out(codec);
9708 alc883_auto_init_hp_out(codec);
9709 alc883_auto_init_analog_input(codec);
9710 alc883_auto_init_input_src(codec);
9711 if (spec->unsol_event)
9712 alc_inithook(codec);
9715 static int patch_alc883(struct hda_codec *codec)
9717 struct alc_spec *spec;
9718 int err, board_config;
9720 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
9721 if (spec == NULL)
9722 return -ENOMEM;
9724 codec->spec = spec;
9726 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9728 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
9729 alc883_models,
9730 alc883_cfg_tbl);
9731 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) {
9732 /* Pick up systems that don't supply PCI SSID */
9733 switch (codec->subsystem_id) {
9734 case 0x106b3600: /* Macbook 3.1 */
9735 board_config = ALC889A_MB31;
9736 break;
9737 default:
9738 printk(KERN_INFO
9739 "hda_codec: Unknown model for %s, trying "
9740 "auto-probe from BIOS...\n", codec->chip_name);
9741 board_config = ALC883_AUTO;
9745 if (board_config == ALC883_AUTO) {
9746 /* automatic parse from the BIOS config */
9747 err = alc883_parse_auto_config(codec);
9748 if (err < 0) {
9749 alc_free(codec);
9750 return err;
9751 } else if (!err) {
9752 printk(KERN_INFO
9753 "hda_codec: Cannot set up configuration "
9754 "from BIOS. Using base mode...\n");
9755 board_config = ALC883_3ST_2ch_DIG;
9759 err = snd_hda_attach_beep_device(codec, 0x1);
9760 if (err < 0) {
9761 alc_free(codec);
9762 return err;
9765 if (board_config != ALC883_AUTO)
9766 setup_preset(spec, &alc883_presets[board_config]);
9768 switch (codec->vendor_id) {
9769 case 0x10ec0888:
9770 if (!spec->num_adc_nids) {
9771 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9772 spec->adc_nids = alc883_adc_nids;
9774 if (!spec->capsrc_nids)
9775 spec->capsrc_nids = alc883_capsrc_nids;
9776 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9777 break;
9778 case 0x10ec0889:
9779 if (!spec->num_adc_nids) {
9780 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids);
9781 spec->adc_nids = alc889_adc_nids;
9783 if (!spec->capsrc_nids)
9784 spec->capsrc_nids = alc889_capsrc_nids;
9785 break;
9786 default:
9787 if (!spec->num_adc_nids) {
9788 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
9789 spec->adc_nids = alc883_adc_nids;
9791 if (!spec->capsrc_nids)
9792 spec->capsrc_nids = alc883_capsrc_nids;
9793 break;
9796 spec->stream_analog_playback = &alc883_pcm_analog_playback;
9797 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9798 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9800 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9801 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9803 if (!spec->cap_mixer)
9804 set_capture_mixer(spec);
9805 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9807 spec->vmaster_nid = 0x0c;
9809 codec->patch_ops = alc_patch_ops;
9810 if (board_config == ALC883_AUTO)
9811 spec->init_hook = alc883_auto_init;
9813 #ifdef CONFIG_SND_HDA_POWER_SAVE
9814 if (!spec->loopback.amplist)
9815 spec->loopback.amplist = alc883_loopbacks;
9816 #endif
9817 codec->proc_widget_hook = print_realtek_coef;
9819 return 0;
9823 * ALC262 support
9826 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
9827 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
9829 #define alc262_dac_nids alc260_dac_nids
9830 #define alc262_adc_nids alc882_adc_nids
9831 #define alc262_adc_nids_alt alc882_adc_nids_alt
9832 #define alc262_capsrc_nids alc882_capsrc_nids
9833 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9835 #define alc262_modes alc260_modes
9836 #define alc262_capture_source alc882_capture_source
9838 static hda_nid_t alc262_dmic_adc_nids[1] = {
9839 /* ADC0 */
9840 0x09
9843 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
9845 static struct snd_kcontrol_new alc262_base_mixer[] = {
9846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9847 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9848 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9849 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9855 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9856 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9857 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9860 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9861 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9862 { } /* end */
9865 /* update HP, line and mono-out pins according to the master switch */
9866 static void alc262_hp_master_update(struct hda_codec *codec)
9868 struct alc_spec *spec = codec->spec;
9869 int val = spec->master_sw;
9871 /* HP & line-out */
9872 snd_hda_codec_write_cache(codec, 0x1b, 0,
9873 AC_VERB_SET_PIN_WIDGET_CONTROL,
9874 val ? PIN_HP : 0);
9875 snd_hda_codec_write_cache(codec, 0x15, 0,
9876 AC_VERB_SET_PIN_WIDGET_CONTROL,
9877 val ? PIN_HP : 0);
9878 /* mono (speaker) depending on the HP jack sense */
9879 val = val && !spec->jack_present;
9880 snd_hda_codec_write_cache(codec, 0x16, 0,
9881 AC_VERB_SET_PIN_WIDGET_CONTROL,
9882 val ? PIN_OUT : 0);
9885 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9887 struct alc_spec *spec = codec->spec;
9888 unsigned int presence;
9889 presence = snd_hda_codec_read(codec, 0x1b, 0,
9890 AC_VERB_GET_PIN_SENSE, 0);
9891 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9892 alc262_hp_master_update(codec);
9895 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9897 if ((res >> 26) != ALC880_HP_EVENT)
9898 return;
9899 alc262_hp_bpc_automute(codec);
9902 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9904 struct alc_spec *spec = codec->spec;
9905 unsigned int presence;
9906 presence = snd_hda_codec_read(codec, 0x15, 0,
9907 AC_VERB_GET_PIN_SENSE, 0);
9908 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9909 alc262_hp_master_update(codec);
9912 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9913 unsigned int res)
9915 if ((res >> 26) != ALC880_HP_EVENT)
9916 return;
9917 alc262_hp_wildwest_automute(codec);
9920 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
9922 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9923 struct snd_ctl_elem_value *ucontrol)
9925 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9926 struct alc_spec *spec = codec->spec;
9927 int val = !!*ucontrol->value.integer.value;
9929 if (val == spec->master_sw)
9930 return 0;
9931 spec->master_sw = val;
9932 alc262_hp_master_update(codec);
9933 return 1;
9936 #define ALC262_HP_MASTER_SWITCH \
9938 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
9939 .name = "Master Playback Switch", \
9940 .info = snd_ctl_boolean_mono_info, \
9941 .get = alc262_hp_master_sw_get, \
9942 .put = alc262_hp_master_sw_put, \
9945 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9946 ALC262_HP_MASTER_SWITCH,
9947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9948 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9949 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9950 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9951 HDA_OUTPUT),
9952 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9953 HDA_OUTPUT),
9954 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9955 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9956 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9957 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9958 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9959 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9960 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9961 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9962 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9963 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9964 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9965 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9966 { } /* end */
9969 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9970 ALC262_HP_MASTER_SWITCH,
9971 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9972 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9973 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9974 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9975 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9976 HDA_OUTPUT),
9977 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9978 HDA_OUTPUT),
9979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9980 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9981 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9982 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9983 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9984 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9985 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9986 { } /* end */
9989 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9990 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9991 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9992 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9993 { } /* end */
9996 /* mute/unmute internal speaker according to the hp jack and mute state */
9997 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9999 struct alc_spec *spec = codec->spec;
10001 spec->autocfg.hp_pins[0] = 0x15;
10002 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
10003 alc_automute_amp(codec);
10006 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10007 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10008 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10009 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10010 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10013 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10014 { } /* end */
10017 static struct hda_verb alc262_hp_t5735_verbs[] = {
10018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10021 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10025 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10026 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10027 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10028 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10029 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10030 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10031 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10032 { } /* end */
10035 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10036 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10037 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10038 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10039 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10040 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10041 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10042 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10044 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10045 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10049 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10050 .num_items = 1,
10051 .items = {
10052 { "Line", 0x1 },
10056 /* bind hp and internal speaker mute (with plug check) as master switch */
10057 static void alc262_hippo_master_update(struct hda_codec *codec)
10059 struct alc_spec *spec = codec->spec;
10060 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10061 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10062 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10063 unsigned int mute;
10065 /* HP */
10066 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10067 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10068 HDA_AMP_MUTE, mute);
10069 /* mute internal speaker per jack sense */
10070 if (spec->jack_present)
10071 mute = HDA_AMP_MUTE;
10072 if (line_nid)
10073 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10074 HDA_AMP_MUTE, mute);
10075 if (speaker_nid && speaker_nid != line_nid)
10076 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10077 HDA_AMP_MUTE, mute);
10080 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10082 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10083 struct snd_ctl_elem_value *ucontrol)
10085 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10086 struct alc_spec *spec = codec->spec;
10087 int val = !!*ucontrol->value.integer.value;
10089 if (val == spec->master_sw)
10090 return 0;
10091 spec->master_sw = val;
10092 alc262_hippo_master_update(codec);
10093 return 1;
10096 #define ALC262_HIPPO_MASTER_SWITCH \
10098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10099 .name = "Master Playback Switch", \
10100 .info = snd_ctl_boolean_mono_info, \
10101 .get = alc262_hippo_master_sw_get, \
10102 .put = alc262_hippo_master_sw_put, \
10105 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10106 ALC262_HIPPO_MASTER_SWITCH,
10107 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10114 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10115 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10117 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10119 { } /* end */
10122 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10123 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10124 ALC262_HIPPO_MASTER_SWITCH,
10125 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10126 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10127 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10128 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10131 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10132 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10134 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10135 { } /* end */
10138 /* mute/unmute internal speaker according to the hp jack and mute state */
10139 static void alc262_hippo_automute(struct hda_codec *codec)
10141 struct alc_spec *spec = codec->spec;
10142 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10143 unsigned int present;
10145 /* need to execute and sync at first */
10146 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
10147 present = snd_hda_codec_read(codec, hp_nid, 0,
10148 AC_VERB_GET_PIN_SENSE, 0);
10149 spec->jack_present = (present & 0x80000000) != 0;
10150 alc262_hippo_master_update(codec);
10153 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10155 if ((res >> 26) != ALC880_HP_EVENT)
10156 return;
10157 alc262_hippo_automute(codec);
10160 static void alc262_hippo_init_hook(struct hda_codec *codec)
10162 struct alc_spec *spec = codec->spec;
10164 spec->autocfg.hp_pins[0] = 0x15;
10165 spec->autocfg.speaker_pins[0] = 0x14;
10166 alc262_hippo_automute(codec);
10169 static void alc262_hippo1_init_hook(struct hda_codec *codec)
10171 struct alc_spec *spec = codec->spec;
10173 spec->autocfg.hp_pins[0] = 0x1b;
10174 spec->autocfg.speaker_pins[0] = 0x14;
10175 alc262_hippo_automute(codec);
10179 static struct snd_kcontrol_new alc262_sony_mixer[] = {
10180 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10181 ALC262_HIPPO_MASTER_SWITCH,
10182 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10183 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10184 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10185 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10186 { } /* end */
10189 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10190 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10191 ALC262_HIPPO_MASTER_SWITCH,
10192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10193 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10195 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10196 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10197 { } /* end */
10200 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10201 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10202 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10203 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10204 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10208 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10209 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10210 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10211 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10212 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10213 { } /* end */
10216 static struct hda_verb alc262_tyan_verbs[] = {
10217 /* Headphone automute */
10218 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10219 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10220 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10222 /* P11 AUX_IN, white 4-pin connector */
10223 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10224 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10225 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10226 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10231 /* unsolicited event for HP jack sensing */
10232 static void alc262_tyan_init_hook(struct hda_codec *codec)
10234 struct alc_spec *spec = codec->spec;
10236 spec->autocfg.hp_pins[0] = 0x1b;
10237 spec->autocfg.speaker_pins[0] = 0x15;
10238 alc_automute_amp(codec);
10242 #define alc262_capture_mixer alc882_capture_mixer
10243 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
10246 * generic initialization of ADC, input mixers and output mixers
10248 static struct hda_verb alc262_init_verbs[] = {
10250 * Unmute ADC0-2 and set the default input to mic-in
10252 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10253 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10254 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10255 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10256 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10257 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10259 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10260 * mixer widget
10261 * Note: PASD motherboards uses the Line In 2 as the input for
10262 * front panel mic (mic 2)
10264 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10265 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10266 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10267 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10268 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10269 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10272 * Set up output mixers (0x0c - 0x0e)
10274 /* set vol=0 to output mixers */
10275 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10278 /* set up input amps for analog loopback */
10279 /* Amp Indices: DAC = 0, mixer = 1 */
10280 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10281 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10282 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10283 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10284 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10285 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10289 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
10290 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10291 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10292 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10295 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10296 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10297 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10298 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10300 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10301 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10303 /* FIXME: use matrix-type input source selection */
10304 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10305 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10306 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10308 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10309 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10310 /* Input mixer2 */
10311 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10312 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10313 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10314 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10315 /* Input mixer3 */
10316 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10318 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10324 static struct hda_verb alc262_eapd_verbs[] = {
10325 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10326 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10330 static struct hda_verb alc262_hippo_unsol_verbs[] = {
10331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10332 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10336 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10338 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10339 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
10341 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10342 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10346 static struct hda_verb alc262_sony_unsol_verbs[] = {
10347 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10348 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10349 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
10351 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10352 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10356 static struct hda_input_mux alc262_dmic_capture_source = {
10357 .num_items = 2,
10358 .items = {
10359 { "Int DMic", 0x9 },
10360 { "Mic", 0x0 },
10364 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10365 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10366 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10367 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10369 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10370 { } /* end */
10373 static struct hda_verb alc262_toshiba_s06_verbs[] = {
10374 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10375 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10378 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
10379 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10380 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10381 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10385 static void alc262_dmic_automute(struct hda_codec *codec)
10387 unsigned int present;
10389 present = snd_hda_codec_read(codec, 0x18, 0,
10390 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10391 snd_hda_codec_write(codec, 0x22, 0,
10392 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10396 /* unsolicited event for HP jack sensing */
10397 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10398 unsigned int res)
10400 if ((res >> 26) == ALC880_MIC_EVENT)
10401 alc262_dmic_automute(codec);
10402 else
10403 alc_sku_unsol_event(codec, res);
10406 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10408 struct alc_spec *spec = codec->spec;
10410 spec->autocfg.hp_pins[0] = 0x15;
10411 spec->autocfg.speaker_pins[0] = 0x14;
10412 alc_automute_pin(codec);
10413 alc262_dmic_automute(codec);
10417 * nec model
10418 * 0x15 = headphone
10419 * 0x16 = internal speaker
10420 * 0x18 = external mic
10423 static struct snd_kcontrol_new alc262_nec_mixer[] = {
10424 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
10425 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
10427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10428 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10429 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10431 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10432 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10433 { } /* end */
10436 static struct hda_verb alc262_nec_verbs[] = {
10437 /* Unmute Speaker */
10438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10440 /* Headphone */
10441 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10444 /* External mic to headphone */
10445 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10446 /* External mic to speaker */
10447 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10452 * fujitsu model
10453 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
10454 * 0x1b = port replicator headphone out
10457 #define ALC_HP_EVENT 0x37
10459 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
10460 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10461 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10462 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10463 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10467 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
10468 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
10469 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10473 static struct hda_input_mux alc262_fujitsu_capture_source = {
10474 .num_items = 3,
10475 .items = {
10476 { "Mic", 0x0 },
10477 { "Int Mic", 0x1 },
10478 { "CD", 0x4 },
10482 static struct hda_input_mux alc262_HP_capture_source = {
10483 .num_items = 5,
10484 .items = {
10485 { "Mic", 0x0 },
10486 { "Front Mic", 0x1 },
10487 { "Line", 0x2 },
10488 { "CD", 0x4 },
10489 { "AUX IN", 0x6 },
10493 static struct hda_input_mux alc262_HP_D7000_capture_source = {
10494 .num_items = 4,
10495 .items = {
10496 { "Mic", 0x0 },
10497 { "Front Mic", 0x2 },
10498 { "Line", 0x1 },
10499 { "CD", 0x4 },
10503 /* mute/unmute internal speaker according to the hp jacks and mute state */
10504 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
10506 struct alc_spec *spec = codec->spec;
10507 unsigned int mute;
10509 if (force || !spec->sense_updated) {
10510 unsigned int present;
10511 /* need to execute and sync at first */
10512 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
10513 /* check laptop HP jack */
10514 present = snd_hda_codec_read(codec, 0x14, 0,
10515 AC_VERB_GET_PIN_SENSE, 0);
10516 /* need to execute and sync at first */
10517 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10518 /* check docking HP jack */
10519 present |= snd_hda_codec_read(codec, 0x1b, 0,
10520 AC_VERB_GET_PIN_SENSE, 0);
10521 if (present & AC_PINSENSE_PRESENCE)
10522 spec->jack_present = 1;
10523 else
10524 spec->jack_present = 0;
10525 spec->sense_updated = 1;
10527 /* unmute internal speaker only if both HPs are unplugged and
10528 * master switch is on
10530 if (spec->jack_present)
10531 mute = HDA_AMP_MUTE;
10532 else
10533 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10534 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10535 HDA_AMP_MUTE, mute);
10538 /* unsolicited event for HP jack sensing */
10539 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
10540 unsigned int res)
10542 if ((res >> 26) != ALC_HP_EVENT)
10543 return;
10544 alc262_fujitsu_automute(codec, 1);
10547 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
10549 alc262_fujitsu_automute(codec, 1);
10552 /* bind volumes of both NID 0x0c and 0x0d */
10553 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
10554 .ops = &snd_hda_bind_vol,
10555 .values = {
10556 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
10557 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
10562 /* mute/unmute internal speaker according to the hp jack and mute state */
10563 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
10565 struct alc_spec *spec = codec->spec;
10566 unsigned int mute;
10568 if (force || !spec->sense_updated) {
10569 unsigned int present_int_hp;
10570 /* need to execute and sync at first */
10571 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
10572 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
10573 AC_VERB_GET_PIN_SENSE, 0);
10574 spec->jack_present = (present_int_hp & 0x80000000) != 0;
10575 spec->sense_updated = 1;
10577 if (spec->jack_present) {
10578 /* mute internal speaker */
10579 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10580 HDA_AMP_MUTE, HDA_AMP_MUTE);
10581 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10582 HDA_AMP_MUTE, HDA_AMP_MUTE);
10583 } else {
10584 /* unmute internal speaker if necessary */
10585 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
10586 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10587 HDA_AMP_MUTE, mute);
10588 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10589 HDA_AMP_MUTE, mute);
10593 /* unsolicited event for HP jack sensing */
10594 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
10595 unsigned int res)
10597 if ((res >> 26) != ALC_HP_EVENT)
10598 return;
10599 alc262_lenovo_3000_automute(codec, 1);
10602 /* bind hp and internal speaker mute (with plug check) */
10603 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
10604 struct snd_ctl_elem_value *ucontrol)
10606 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10607 long *valp = ucontrol->value.integer.value;
10608 int change;
10610 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10611 HDA_AMP_MUTE,
10612 valp ? 0 : HDA_AMP_MUTE);
10613 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10614 HDA_AMP_MUTE,
10615 valp ? 0 : HDA_AMP_MUTE);
10617 if (change)
10618 alc262_fujitsu_automute(codec, 0);
10619 return change;
10622 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
10623 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10625 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10626 .name = "Master Playback Switch",
10627 .info = snd_hda_mixer_amp_switch_info,
10628 .get = snd_hda_mixer_amp_switch_get,
10629 .put = alc262_fujitsu_master_sw_put,
10630 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10632 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10633 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10634 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10635 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10636 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10637 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10638 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10639 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10640 { } /* end */
10643 /* bind hp and internal speaker mute (with plug check) */
10644 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
10645 struct snd_ctl_elem_value *ucontrol)
10647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10648 long *valp = ucontrol->value.integer.value;
10649 int change;
10651 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
10652 HDA_AMP_MUTE,
10653 valp ? 0 : HDA_AMP_MUTE);
10655 if (change)
10656 alc262_lenovo_3000_automute(codec, 0);
10657 return change;
10660 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
10661 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10663 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10664 .name = "Master Playback Switch",
10665 .info = snd_hda_mixer_amp_switch_info,
10666 .get = snd_hda_mixer_amp_switch_get,
10667 .put = alc262_lenovo_3000_master_sw_put,
10668 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
10670 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10671 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10673 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10674 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10675 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
10676 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10677 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10678 { } /* end */
10681 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
10682 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
10683 ALC262_HIPPO_MASTER_SWITCH,
10684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10686 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10687 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10688 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10689 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10690 { } /* end */
10693 /* additional init verbs for Benq laptops */
10694 static struct hda_verb alc262_EAPD_verbs[] = {
10695 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10696 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
10700 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
10701 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10702 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10704 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
10705 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
10709 /* Samsung Q1 Ultra Vista model setup */
10710 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
10711 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10712 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10713 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10714 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10715 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
10716 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
10717 { } /* end */
10720 static struct hda_verb alc262_ultra_verbs[] = {
10721 /* output mixer */
10722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10723 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10725 /* speaker */
10726 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10727 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10729 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10730 /* HP */
10731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10733 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10734 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10735 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10736 /* internal mic */
10737 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10739 /* ADC, choose mic */
10740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10743 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10744 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10745 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10746 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10747 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10748 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10749 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
10753 /* mute/unmute internal speaker according to the hp jack and mute state */
10754 static void alc262_ultra_automute(struct hda_codec *codec)
10756 struct alc_spec *spec = codec->spec;
10757 unsigned int mute;
10759 mute = 0;
10760 /* auto-mute only when HP is used as HP */
10761 if (!spec->cur_mux[0]) {
10762 unsigned int present;
10763 /* need to execute and sync at first */
10764 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
10765 present = snd_hda_codec_read(codec, 0x15, 0,
10766 AC_VERB_GET_PIN_SENSE, 0);
10767 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
10768 if (spec->jack_present)
10769 mute = HDA_AMP_MUTE;
10771 /* mute/unmute internal speaker */
10772 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10773 HDA_AMP_MUTE, mute);
10774 /* mute/unmute HP */
10775 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10776 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
10779 /* unsolicited event for HP jack sensing */
10780 static void alc262_ultra_unsol_event(struct hda_codec *codec,
10781 unsigned int res)
10783 if ((res >> 26) != ALC880_HP_EVENT)
10784 return;
10785 alc262_ultra_automute(codec);
10788 static struct hda_input_mux alc262_ultra_capture_source = {
10789 .num_items = 2,
10790 .items = {
10791 { "Mic", 0x1 },
10792 { "Headphone", 0x7 },
10796 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
10797 struct snd_ctl_elem_value *ucontrol)
10799 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10800 struct alc_spec *spec = codec->spec;
10801 int ret;
10803 ret = alc_mux_enum_put(kcontrol, ucontrol);
10804 if (!ret)
10805 return 0;
10806 /* reprogram the HP pin as mic or HP according to the input source */
10807 snd_hda_codec_write_cache(codec, 0x15, 0,
10808 AC_VERB_SET_PIN_WIDGET_CONTROL,
10809 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
10810 alc262_ultra_automute(codec); /* mute/unmute HP */
10811 return ret;
10814 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10815 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
10816 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
10818 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10819 .name = "Capture Source",
10820 .info = alc_mux_enum_info,
10821 .get = alc_mux_enum_get,
10822 .put = alc262_ultra_mux_enum_put,
10824 { } /* end */
10827 /* add playback controls from the parsed DAC table */
10828 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10829 const struct auto_pin_cfg *cfg)
10831 hda_nid_t nid;
10832 int err;
10834 spec->multiout.num_dacs = 1; /* only use one dac */
10835 spec->multiout.dac_nids = spec->private_dac_nids;
10836 spec->multiout.dac_nids[0] = 2;
10838 nid = cfg->line_out_pins[0];
10839 if (nid) {
10840 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10841 "Front Playback Volume",
10842 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10843 if (err < 0)
10844 return err;
10845 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10846 "Front Playback Switch",
10847 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10848 if (err < 0)
10849 return err;
10852 nid = cfg->speaker_pins[0];
10853 if (nid) {
10854 if (nid == 0x16) {
10855 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10856 "Speaker Playback Volume",
10857 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10858 HDA_OUTPUT));
10859 if (err < 0)
10860 return err;
10861 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10862 "Speaker Playback Switch",
10863 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10864 HDA_OUTPUT));
10865 if (err < 0)
10866 return err;
10867 } else {
10868 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10869 "Speaker Playback Switch",
10870 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10871 HDA_OUTPUT));
10872 if (err < 0)
10873 return err;
10876 nid = cfg->hp_pins[0];
10877 if (nid) {
10878 /* spec->multiout.hp_nid = 2; */
10879 if (nid == 0x16) {
10880 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10881 "Headphone Playback Volume",
10882 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10883 HDA_OUTPUT));
10884 if (err < 0)
10885 return err;
10886 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10887 "Headphone Playback Switch",
10888 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10889 HDA_OUTPUT));
10890 if (err < 0)
10891 return err;
10892 } else {
10893 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10894 "Headphone Playback Switch",
10895 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10896 HDA_OUTPUT));
10897 if (err < 0)
10898 return err;
10901 return 0;
10904 static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
10905 const struct auto_pin_cfg *cfg)
10907 int err;
10909 err = alc880_auto_create_analog_input_ctls(spec, cfg);
10910 if (err < 0)
10911 return err;
10912 /* digital-mic input pin is excluded in alc880_auto_create..()
10913 * because it's under 0x18
10915 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
10916 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
10917 struct hda_input_mux *imux = &spec->private_imux[0];
10918 imux->items[imux->num_items].label = "Int Mic";
10919 imux->items[imux->num_items].index = 0x09;
10920 imux->num_items++;
10922 return 0;
10927 * generic initialization of ADC, input mixers and output mixers
10929 static struct hda_verb alc262_volume_init_verbs[] = {
10931 * Unmute ADC0-2 and set the default input to mic-in
10933 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10934 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10935 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10936 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10937 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10938 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10940 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10941 * mixer widget
10942 * Note: PASD motherboards uses the Line In 2 as the input for
10943 * front panel mic (mic 2)
10945 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10950 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10953 * Set up output mixers (0x0c - 0x0f)
10955 /* set vol=0 to output mixers */
10956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10957 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10958 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10960 /* set up input amps for analog loopback */
10961 /* Amp Indices: DAC = 0, mixer = 1 */
10962 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10963 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10964 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10965 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10966 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10967 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10969 /* FIXME: use matrix-type input source selection */
10970 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10971 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10972 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10973 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10974 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10975 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10976 /* Input mixer2 */
10977 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10978 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10979 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10980 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10981 /* Input mixer3 */
10982 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10983 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10984 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10985 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10990 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10992 * Unmute ADC0-2 and set the default input to mic-in
10994 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10996 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10997 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10998 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10999 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11001 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11002 * mixer widget
11003 * Note: PASD motherboards uses the Line In 2 as the input for
11004 * front panel mic (mic 2)
11006 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11008 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11009 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11010 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11011 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11012 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11016 * Set up output mixers (0x0c - 0x0e)
11018 /* set vol=0 to output mixers */
11019 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11020 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11023 /* set up input amps for analog loopback */
11024 /* Amp Indices: DAC = 0, mixer = 1 */
11025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11027 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11028 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11029 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11030 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11032 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11033 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11034 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11036 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11039 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11042 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11043 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11045 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11046 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11048 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11049 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11050 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11051 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11052 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11053 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11056 /* FIXME: use matrix-type input source selection */
11057 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11058 /* Input mixer1: only unmute Mic */
11059 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11060 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11061 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11062 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11063 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11064 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11065 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11066 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11067 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11068 /* Input mixer2 */
11069 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11072 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11074 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11077 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11078 /* Input mixer3 */
11079 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11080 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11081 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11085 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11089 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11094 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11096 * Unmute ADC0-2 and set the default input to mic-in
11098 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11099 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11100 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11101 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11102 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11103 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11105 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11106 * mixer widget
11107 * Note: PASD motherboards uses the Line In 2 as the input for front
11108 * panel mic (mic 2)
11110 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11111 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11120 * Set up output mixers (0x0c - 0x0e)
11122 /* set vol=0 to output mixers */
11123 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11124 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11125 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11127 /* set up input amps for analog loopback */
11128 /* Amp Indices: DAC = 0, mixer = 1 */
11129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11130 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11131 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11133 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11134 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11137 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11138 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11139 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11140 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11141 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11142 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11143 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11145 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11146 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11148 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11149 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11151 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11155 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11156 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11158 /* FIXME: use matrix-type input source selection */
11159 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11160 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11161 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11162 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11163 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11164 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11165 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11166 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11167 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11168 /* Input mixer2 */
11169 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11170 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11171 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11172 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11173 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11174 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11175 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11176 /* Input mixer3 */
11177 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11182 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11183 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11185 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11190 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11192 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11193 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11194 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11196 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11197 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11208 #ifdef CONFIG_SND_HDA_POWER_SAVE
11209 #define alc262_loopbacks alc880_loopbacks
11210 #endif
11212 /* pcm configuration: identical with ALC880 */
11213 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
11214 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
11215 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
11216 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
11219 * BIOS auto configuration
11221 static int alc262_parse_auto_config(struct hda_codec *codec)
11223 struct alc_spec *spec = codec->spec;
11224 int err;
11225 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11227 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11228 alc262_ignore);
11229 if (err < 0)
11230 return err;
11231 if (!spec->autocfg.line_outs) {
11232 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11233 spec->multiout.max_channels = 2;
11234 spec->no_analog = 1;
11235 goto dig_only;
11237 return 0; /* can't find valid BIOS pin config */
11239 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11240 if (err < 0)
11241 return err;
11242 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
11243 if (err < 0)
11244 return err;
11246 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11248 dig_only:
11249 if (spec->autocfg.dig_outs) {
11250 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11251 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11253 if (spec->autocfg.dig_in_pin)
11254 spec->dig_in_nid = ALC262_DIGIN_NID;
11256 if (spec->kctls.list)
11257 add_mixer(spec, spec->kctls.list);
11259 add_verb(spec, alc262_volume_init_verbs);
11260 spec->num_mux_defs = 1;
11261 spec->input_mux = &spec->private_imux[0];
11263 err = alc_auto_add_mic_boost(codec);
11264 if (err < 0)
11265 return err;
11267 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
11269 return 1;
11272 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11273 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11274 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11275 #define alc262_auto_init_input_src alc882_auto_init_input_src
11278 /* init callback for auto-configuration model -- overriding the default init */
11279 static void alc262_auto_init(struct hda_codec *codec)
11281 struct alc_spec *spec = codec->spec;
11282 alc262_auto_init_multi_out(codec);
11283 alc262_auto_init_hp_out(codec);
11284 alc262_auto_init_analog_input(codec);
11285 alc262_auto_init_input_src(codec);
11286 if (spec->unsol_event)
11287 alc_inithook(codec);
11291 * configuration and preset
11293 static const char *alc262_models[ALC262_MODEL_LAST] = {
11294 [ALC262_BASIC] = "basic",
11295 [ALC262_HIPPO] = "hippo",
11296 [ALC262_HIPPO_1] = "hippo_1",
11297 [ALC262_FUJITSU] = "fujitsu",
11298 [ALC262_HP_BPC] = "hp-bpc",
11299 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
11300 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
11301 [ALC262_HP_RP5700] = "hp-rp5700",
11302 [ALC262_BENQ_ED8] = "benq",
11303 [ALC262_BENQ_T31] = "benq-t31",
11304 [ALC262_SONY_ASSAMD] = "sony-assamd",
11305 [ALC262_TOSHIBA_S06] = "toshiba-s06",
11306 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
11307 [ALC262_ULTRA] = "ultra",
11308 [ALC262_LENOVO_3000] = "lenovo-3000",
11309 [ALC262_NEC] = "nec",
11310 [ALC262_TYAN] = "tyan",
11311 [ALC262_AUTO] = "auto",
11314 static struct snd_pci_quirk alc262_cfg_tbl[] = {
11315 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
11316 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
11317 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
11318 ALC262_HP_BPC),
11319 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
11320 ALC262_HP_BPC),
11321 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
11322 ALC262_HP_BPC),
11323 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
11324 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
11325 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
11326 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
11327 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
11328 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
11329 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
11330 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
11331 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
11332 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
11333 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
11334 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
11335 ALC262_HP_TC_T5735),
11336 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
11337 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11338 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
11339 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
11340 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
11341 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
11342 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
11343 ALC262_SONY_ASSAMD),
11344 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
11345 ALC262_TOSHIBA_RX1),
11346 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
11347 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
11348 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
11349 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
11350 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
11351 ALC262_ULTRA),
11352 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
11353 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
11354 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
11355 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
11356 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
11360 static struct alc_config_preset alc262_presets[] = {
11361 [ALC262_BASIC] = {
11362 .mixers = { alc262_base_mixer },
11363 .init_verbs = { alc262_init_verbs },
11364 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11365 .dac_nids = alc262_dac_nids,
11366 .hp_nid = 0x03,
11367 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11368 .channel_mode = alc262_modes,
11369 .input_mux = &alc262_capture_source,
11371 [ALC262_HIPPO] = {
11372 .mixers = { alc262_hippo_mixer },
11373 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
11374 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11375 .dac_nids = alc262_dac_nids,
11376 .hp_nid = 0x03,
11377 .dig_out_nid = ALC262_DIGOUT_NID,
11378 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11379 .channel_mode = alc262_modes,
11380 .input_mux = &alc262_capture_source,
11381 .unsol_event = alc262_hippo_unsol_event,
11382 .init_hook = alc262_hippo_init_hook,
11384 [ALC262_HIPPO_1] = {
11385 .mixers = { alc262_hippo1_mixer },
11386 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
11387 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11388 .dac_nids = alc262_dac_nids,
11389 .hp_nid = 0x02,
11390 .dig_out_nid = ALC262_DIGOUT_NID,
11391 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11392 .channel_mode = alc262_modes,
11393 .input_mux = &alc262_capture_source,
11394 .unsol_event = alc262_hippo_unsol_event,
11395 .init_hook = alc262_hippo1_init_hook,
11397 [ALC262_FUJITSU] = {
11398 .mixers = { alc262_fujitsu_mixer },
11399 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11400 alc262_fujitsu_unsol_verbs },
11401 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11402 .dac_nids = alc262_dac_nids,
11403 .hp_nid = 0x03,
11404 .dig_out_nid = ALC262_DIGOUT_NID,
11405 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11406 .channel_mode = alc262_modes,
11407 .input_mux = &alc262_fujitsu_capture_source,
11408 .unsol_event = alc262_fujitsu_unsol_event,
11409 .init_hook = alc262_fujitsu_init_hook,
11411 [ALC262_HP_BPC] = {
11412 .mixers = { alc262_HP_BPC_mixer },
11413 .init_verbs = { alc262_HP_BPC_init_verbs },
11414 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11415 .dac_nids = alc262_dac_nids,
11416 .hp_nid = 0x03,
11417 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11418 .channel_mode = alc262_modes,
11419 .input_mux = &alc262_HP_capture_source,
11420 .unsol_event = alc262_hp_bpc_unsol_event,
11421 .init_hook = alc262_hp_bpc_automute,
11423 [ALC262_HP_BPC_D7000_WF] = {
11424 .mixers = { alc262_HP_BPC_WildWest_mixer },
11425 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11426 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11427 .dac_nids = alc262_dac_nids,
11428 .hp_nid = 0x03,
11429 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11430 .channel_mode = alc262_modes,
11431 .input_mux = &alc262_HP_D7000_capture_source,
11432 .unsol_event = alc262_hp_wildwest_unsol_event,
11433 .init_hook = alc262_hp_wildwest_automute,
11435 [ALC262_HP_BPC_D7000_WL] = {
11436 .mixers = { alc262_HP_BPC_WildWest_mixer,
11437 alc262_HP_BPC_WildWest_option_mixer },
11438 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
11439 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11440 .dac_nids = alc262_dac_nids,
11441 .hp_nid = 0x03,
11442 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11443 .channel_mode = alc262_modes,
11444 .input_mux = &alc262_HP_D7000_capture_source,
11445 .unsol_event = alc262_hp_wildwest_unsol_event,
11446 .init_hook = alc262_hp_wildwest_automute,
11448 [ALC262_HP_TC_T5735] = {
11449 .mixers = { alc262_hp_t5735_mixer },
11450 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
11451 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11452 .dac_nids = alc262_dac_nids,
11453 .hp_nid = 0x03,
11454 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11455 .channel_mode = alc262_modes,
11456 .input_mux = &alc262_capture_source,
11457 .unsol_event = alc_automute_amp_unsol_event,
11458 .init_hook = alc262_hp_t5735_init_hook,
11460 [ALC262_HP_RP5700] = {
11461 .mixers = { alc262_hp_rp5700_mixer },
11462 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
11463 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11464 .dac_nids = alc262_dac_nids,
11465 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11466 .channel_mode = alc262_modes,
11467 .input_mux = &alc262_hp_rp5700_capture_source,
11469 [ALC262_BENQ_ED8] = {
11470 .mixers = { alc262_base_mixer },
11471 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
11472 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11473 .dac_nids = alc262_dac_nids,
11474 .hp_nid = 0x03,
11475 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11476 .channel_mode = alc262_modes,
11477 .input_mux = &alc262_capture_source,
11479 [ALC262_SONY_ASSAMD] = {
11480 .mixers = { alc262_sony_mixer },
11481 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
11482 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11483 .dac_nids = alc262_dac_nids,
11484 .hp_nid = 0x02,
11485 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11486 .channel_mode = alc262_modes,
11487 .input_mux = &alc262_capture_source,
11488 .unsol_event = alc262_hippo_unsol_event,
11489 .init_hook = alc262_hippo_init_hook,
11491 [ALC262_BENQ_T31] = {
11492 .mixers = { alc262_benq_t31_mixer },
11493 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
11494 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11495 .dac_nids = alc262_dac_nids,
11496 .hp_nid = 0x03,
11497 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11498 .channel_mode = alc262_modes,
11499 .input_mux = &alc262_capture_source,
11500 .unsol_event = alc262_hippo_unsol_event,
11501 .init_hook = alc262_hippo_init_hook,
11503 [ALC262_ULTRA] = {
11504 .mixers = { alc262_ultra_mixer },
11505 .cap_mixer = alc262_ultra_capture_mixer,
11506 .init_verbs = { alc262_ultra_verbs },
11507 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11508 .dac_nids = alc262_dac_nids,
11509 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11510 .channel_mode = alc262_modes,
11511 .input_mux = &alc262_ultra_capture_source,
11512 .adc_nids = alc262_adc_nids, /* ADC0 */
11513 .capsrc_nids = alc262_capsrc_nids,
11514 .num_adc_nids = 1, /* single ADC */
11515 .unsol_event = alc262_ultra_unsol_event,
11516 .init_hook = alc262_ultra_automute,
11518 [ALC262_LENOVO_3000] = {
11519 .mixers = { alc262_lenovo_3000_mixer },
11520 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
11521 alc262_lenovo_3000_unsol_verbs },
11522 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11523 .dac_nids = alc262_dac_nids,
11524 .hp_nid = 0x03,
11525 .dig_out_nid = ALC262_DIGOUT_NID,
11526 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11527 .channel_mode = alc262_modes,
11528 .input_mux = &alc262_fujitsu_capture_source,
11529 .unsol_event = alc262_lenovo_3000_unsol_event,
11531 [ALC262_NEC] = {
11532 .mixers = { alc262_nec_mixer },
11533 .init_verbs = { alc262_nec_verbs },
11534 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11535 .dac_nids = alc262_dac_nids,
11536 .hp_nid = 0x03,
11537 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11538 .channel_mode = alc262_modes,
11539 .input_mux = &alc262_capture_source,
11541 [ALC262_TOSHIBA_S06] = {
11542 .mixers = { alc262_toshiba_s06_mixer },
11543 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
11544 alc262_eapd_verbs },
11545 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11546 .capsrc_nids = alc262_dmic_capsrc_nids,
11547 .dac_nids = alc262_dac_nids,
11548 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
11549 .num_adc_nids = 1, /* single ADC */
11550 .dig_out_nid = ALC262_DIGOUT_NID,
11551 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11552 .channel_mode = alc262_modes,
11553 .input_mux = &alc262_dmic_capture_source,
11554 .unsol_event = alc262_toshiba_s06_unsol_event,
11555 .init_hook = alc262_toshiba_s06_init_hook,
11557 [ALC262_TOSHIBA_RX1] = {
11558 .mixers = { alc262_toshiba_rx1_mixer },
11559 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
11560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11561 .dac_nids = alc262_dac_nids,
11562 .hp_nid = 0x03,
11563 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11564 .channel_mode = alc262_modes,
11565 .input_mux = &alc262_capture_source,
11566 .unsol_event = alc262_hippo_unsol_event,
11567 .init_hook = alc262_hippo_init_hook,
11569 [ALC262_TYAN] = {
11570 .mixers = { alc262_tyan_mixer },
11571 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
11572 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11573 .dac_nids = alc262_dac_nids,
11574 .hp_nid = 0x02,
11575 .dig_out_nid = ALC262_DIGOUT_NID,
11576 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11577 .channel_mode = alc262_modes,
11578 .input_mux = &alc262_capture_source,
11579 .unsol_event = alc_automute_amp_unsol_event,
11580 .init_hook = alc262_tyan_init_hook,
11584 static int patch_alc262(struct hda_codec *codec)
11586 struct alc_spec *spec;
11587 int board_config;
11588 int err;
11590 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11591 if (spec == NULL)
11592 return -ENOMEM;
11594 codec->spec = spec;
11595 #if 0
11596 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
11597 * under-run
11600 int tmp;
11601 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11602 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
11603 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
11604 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
11606 #endif
11608 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11610 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
11611 alc262_models,
11612 alc262_cfg_tbl);
11614 if (board_config < 0) {
11615 printk(KERN_INFO "hda_codec: Unknown model for %s, "
11616 "trying auto-probe from BIOS...\n", codec->chip_name);
11617 board_config = ALC262_AUTO;
11620 if (board_config == ALC262_AUTO) {
11621 /* automatic parse from the BIOS config */
11622 err = alc262_parse_auto_config(codec);
11623 if (err < 0) {
11624 alc_free(codec);
11625 return err;
11626 } else if (!err) {
11627 printk(KERN_INFO
11628 "hda_codec: Cannot set up configuration "
11629 "from BIOS. Using base mode...\n");
11630 board_config = ALC262_BASIC;
11634 if (!spec->no_analog) {
11635 err = snd_hda_attach_beep_device(codec, 0x1);
11636 if (err < 0) {
11637 alc_free(codec);
11638 return err;
11642 if (board_config != ALC262_AUTO)
11643 setup_preset(spec, &alc262_presets[board_config]);
11645 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11646 spec->stream_analog_capture = &alc262_pcm_analog_capture;
11648 spec->stream_digital_playback = &alc262_pcm_digital_playback;
11649 spec->stream_digital_capture = &alc262_pcm_digital_capture;
11651 if (!spec->adc_nids && spec->input_mux) {
11652 int i;
11653 /* check whether the digital-mic has to be supported */
11654 for (i = 0; i < spec->input_mux->num_items; i++) {
11655 if (spec->input_mux->items[i].index >= 9)
11656 break;
11658 if (i < spec->input_mux->num_items) {
11659 /* use only ADC0 */
11660 spec->adc_nids = alc262_dmic_adc_nids;
11661 spec->num_adc_nids = 1;
11662 spec->capsrc_nids = alc262_dmic_capsrc_nids;
11663 } else {
11664 /* all analog inputs */
11665 /* check whether NID 0x07 is valid */
11666 unsigned int wcap = get_wcaps(codec, 0x07);
11668 /* get type */
11669 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11670 if (wcap != AC_WID_AUD_IN) {
11671 spec->adc_nids = alc262_adc_nids_alt;
11672 spec->num_adc_nids =
11673 ARRAY_SIZE(alc262_adc_nids_alt);
11674 spec->capsrc_nids = alc262_capsrc_nids_alt;
11675 } else {
11676 spec->adc_nids = alc262_adc_nids;
11677 spec->num_adc_nids =
11678 ARRAY_SIZE(alc262_adc_nids);
11679 spec->capsrc_nids = alc262_capsrc_nids;
11683 if (!spec->cap_mixer && !spec->no_analog)
11684 set_capture_mixer(spec);
11685 if (!spec->no_analog)
11686 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11688 spec->vmaster_nid = 0x0c;
11690 codec->patch_ops = alc_patch_ops;
11691 if (board_config == ALC262_AUTO)
11692 spec->init_hook = alc262_auto_init;
11693 #ifdef CONFIG_SND_HDA_POWER_SAVE
11694 if (!spec->loopback.amplist)
11695 spec->loopback.amplist = alc262_loopbacks;
11696 #endif
11697 codec->proc_widget_hook = print_realtek_coef;
11699 return 0;
11703 * ALC268 channel source setting (2 channel)
11705 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
11706 #define alc268_modes alc260_modes
11708 static hda_nid_t alc268_dac_nids[2] = {
11709 /* front, hp */
11710 0x02, 0x03
11713 static hda_nid_t alc268_adc_nids[2] = {
11714 /* ADC0-1 */
11715 0x08, 0x07
11718 static hda_nid_t alc268_adc_nids_alt[1] = {
11719 /* ADC0 */
11720 0x08
11723 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
11725 static struct snd_kcontrol_new alc268_base_mixer[] = {
11726 /* output mixer control */
11727 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11728 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11729 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11730 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11731 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11732 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11733 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11737 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
11738 /* output mixer control */
11739 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11740 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11741 ALC262_HIPPO_MASTER_SWITCH,
11742 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11743 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11744 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11748 /* bind Beep switches of both NID 0x0f and 0x10 */
11749 static struct hda_bind_ctls alc268_bind_beep_sw = {
11750 .ops = &snd_hda_bind_sw,
11751 .values = {
11752 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
11753 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
11758 static struct snd_kcontrol_new alc268_beep_mixer[] = {
11759 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
11760 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
11764 static struct hda_verb alc268_eapd_verbs[] = {
11765 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11766 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11770 /* Toshiba specific */
11771 static struct hda_verb alc268_toshiba_verbs[] = {
11772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11773 { } /* end */
11776 static struct hda_input_mux alc268_acer_lc_capture_source = {
11777 .num_items = 2,
11778 .items = {
11779 { "i-Mic", 0x6 },
11780 { "E-Mic", 0x0 },
11784 /* Acer specific */
11785 /* bind volumes of both NID 0x02 and 0x03 */
11786 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
11787 .ops = &snd_hda_bind_vol,
11788 .values = {
11789 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11790 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11795 /* mute/unmute internal speaker according to the hp jack and mute state */
11796 static void alc268_acer_automute(struct hda_codec *codec, int force)
11798 struct alc_spec *spec = codec->spec;
11799 unsigned int mute;
11801 if (force || !spec->sense_updated) {
11802 unsigned int present;
11803 present = snd_hda_codec_read(codec, 0x14, 0,
11804 AC_VERB_GET_PIN_SENSE, 0);
11805 spec->jack_present = (present & 0x80000000) != 0;
11806 spec->sense_updated = 1;
11808 if (spec->jack_present)
11809 mute = HDA_AMP_MUTE; /* mute internal speaker */
11810 else /* unmute internal speaker if necessary */
11811 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11812 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11813 HDA_AMP_MUTE, mute);
11817 /* bind hp and internal speaker mute (with plug check) */
11818 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
11819 struct snd_ctl_elem_value *ucontrol)
11821 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11822 long *valp = ucontrol->value.integer.value;
11823 int change;
11825 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
11826 HDA_AMP_MUTE,
11827 valp[0] ? 0 : HDA_AMP_MUTE);
11828 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
11829 HDA_AMP_MUTE,
11830 valp[1] ? 0 : HDA_AMP_MUTE);
11831 if (change)
11832 alc268_acer_automute(codec, 0);
11833 return change;
11836 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
11837 /* output mixer control */
11838 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11840 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11841 .name = "Master Playback Switch",
11842 .info = snd_hda_mixer_amp_switch_info,
11843 .get = snd_hda_mixer_amp_switch_get,
11844 .put = alc268_acer_master_sw_put,
11845 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11847 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
11851 static struct snd_kcontrol_new alc268_acer_mixer[] = {
11852 /* output mixer control */
11853 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11856 .name = "Master Playback Switch",
11857 .info = snd_hda_mixer_amp_switch_info,
11858 .get = snd_hda_mixer_amp_switch_get,
11859 .put = alc268_acer_master_sw_put,
11860 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11862 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11863 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11864 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11868 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11869 /* output mixer control */
11870 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11872 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11873 .name = "Master Playback Switch",
11874 .info = snd_hda_mixer_amp_switch_info,
11875 .get = snd_hda_mixer_amp_switch_get,
11876 .put = alc268_acer_master_sw_put,
11877 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11879 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11880 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11884 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
11885 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11886 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11887 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11888 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11889 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
11890 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
11894 static struct hda_verb alc268_acer_verbs[] = {
11895 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
11896 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11897 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11900 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11901 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11905 /* unsolicited event for HP jack sensing */
11906 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11907 #define alc268_toshiba_init_hook alc262_hippo_init_hook
11909 static void alc268_acer_unsol_event(struct hda_codec *codec,
11910 unsigned int res)
11912 if ((res >> 26) != ALC880_HP_EVENT)
11913 return;
11914 alc268_acer_automute(codec, 1);
11917 static void alc268_acer_init_hook(struct hda_codec *codec)
11919 alc268_acer_automute(codec, 1);
11922 /* toggle speaker-output according to the hp-jack state */
11923 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11925 unsigned int present;
11926 unsigned char bits;
11928 present = snd_hda_codec_read(codec, 0x15, 0,
11929 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11930 bits = present ? AMP_IN_MUTE(0) : 0;
11931 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
11932 AMP_IN_MUTE(0), bits);
11933 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
11934 AMP_IN_MUTE(0), bits);
11938 static void alc268_acer_mic_automute(struct hda_codec *codec)
11940 unsigned int present;
11942 present = snd_hda_codec_read(codec, 0x18, 0,
11943 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11944 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11945 present ? 0x0 : 0x6);
11948 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11949 unsigned int res)
11951 if ((res >> 26) == ALC880_HP_EVENT)
11952 alc268_aspire_one_speaker_automute(codec);
11953 if ((res >> 26) == ALC880_MIC_EVENT)
11954 alc268_acer_mic_automute(codec);
11957 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11959 alc268_aspire_one_speaker_automute(codec);
11960 alc268_acer_mic_automute(codec);
11963 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11964 /* output mixer control */
11965 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11966 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11968 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11969 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11970 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11974 static struct hda_verb alc268_dell_verbs[] = {
11975 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11977 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11981 /* mute/unmute internal speaker according to the hp jack and mute state */
11982 static void alc268_dell_init_hook(struct hda_codec *codec)
11984 struct alc_spec *spec = codec->spec;
11986 spec->autocfg.hp_pins[0] = 0x15;
11987 spec->autocfg.speaker_pins[0] = 0x14;
11988 alc_automute_pin(codec);
11991 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11992 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11993 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11994 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11996 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11997 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11998 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11999 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12003 static struct hda_verb alc267_quanta_il1_verbs[] = {
12004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12005 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12009 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
12011 unsigned int present;
12013 present = snd_hda_codec_read(codec, 0x18, 0,
12014 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12015 snd_hda_codec_write(codec, 0x23, 0,
12016 AC_VERB_SET_CONNECT_SEL,
12017 present ? 0x00 : 0x01);
12020 static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
12022 struct alc_spec *spec = codec->spec;
12024 spec->autocfg.hp_pins[0] = 0x15;
12025 spec->autocfg.speaker_pins[0] = 0x14;
12026 alc_automute_pin(codec);
12027 alc267_quanta_il1_mic_automute(codec);
12030 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
12031 unsigned int res)
12033 switch (res >> 26) {
12034 case ALC880_MIC_EVENT:
12035 alc267_quanta_il1_mic_automute(codec);
12036 break;
12037 default:
12038 alc_sku_unsol_event(codec, res);
12039 break;
12044 * generic initialization of ADC, input mixers and output mixers
12046 static struct hda_verb alc268_base_init_verbs[] = {
12047 /* Unmute DAC0-1 and set vol = 0 */
12048 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12049 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12052 * Set up output mixers (0x0c - 0x0e)
12054 /* set vol=0 to output mixers */
12055 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12056 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12059 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12061 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12064 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12065 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12066 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12067 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12068 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12070 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12072 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12074 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12076 /* set PCBEEP vol = 0, mute connections */
12077 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12079 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12081 /* Unmute Selector 23h,24h and set the default input to mic-in */
12083 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12085 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12086 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12092 * generic initialization of ADC, input mixers and output mixers
12094 static struct hda_verb alc268_volume_init_verbs[] = {
12095 /* set output DAC */
12096 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12097 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12099 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12100 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12101 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12102 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12103 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12105 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12107 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12110 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12112 /* set PCBEEP vol = 0, mute connections */
12113 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12114 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12115 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12120 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12121 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12122 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12125 /* The multiple "Capture Source" controls confuse alsamixer
12126 * So call somewhat different..
12128 /* .name = "Capture Source", */
12129 .name = "Input Source",
12130 .count = 1,
12131 .info = alc_mux_enum_info,
12132 .get = alc_mux_enum_get,
12133 .put = alc_mux_enum_put,
12135 { } /* end */
12138 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12139 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12140 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12141 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12142 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12145 /* The multiple "Capture Source" controls confuse alsamixer
12146 * So call somewhat different..
12148 /* .name = "Capture Source", */
12149 .name = "Input Source",
12150 .count = 2,
12151 .info = alc_mux_enum_info,
12152 .get = alc_mux_enum_get,
12153 .put = alc_mux_enum_put,
12155 { } /* end */
12158 static struct hda_input_mux alc268_capture_source = {
12159 .num_items = 4,
12160 .items = {
12161 { "Mic", 0x0 },
12162 { "Front Mic", 0x1 },
12163 { "Line", 0x2 },
12164 { "CD", 0x3 },
12168 static struct hda_input_mux alc268_acer_capture_source = {
12169 .num_items = 3,
12170 .items = {
12171 { "Mic", 0x0 },
12172 { "Internal Mic", 0x1 },
12173 { "Line", 0x2 },
12177 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12178 .num_items = 3,
12179 .items = {
12180 { "Mic", 0x0 },
12181 { "Internal Mic", 0x6 },
12182 { "Line", 0x2 },
12186 #ifdef CONFIG_SND_DEBUG
12187 static struct snd_kcontrol_new alc268_test_mixer[] = {
12188 /* Volume widgets */
12189 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12190 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12191 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12192 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12193 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12194 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12195 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12196 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12197 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12198 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12199 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12200 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12201 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12202 /* The below appears problematic on some hardwares */
12203 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12204 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12205 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12206 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12207 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12209 /* Modes for retasking pin widgets */
12210 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12211 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12212 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12213 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12215 /* Controls for GPIO pins, assuming they are configured as outputs */
12216 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12217 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12218 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12219 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12221 /* Switches to allow the digital SPDIF output pin to be enabled.
12222 * The ALC268 does not have an SPDIF input.
12224 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12226 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12227 * this output to turn on an external amplifier.
12229 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12230 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12232 { } /* end */
12234 #endif
12236 /* create input playback/capture controls for the given pin */
12237 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12238 const char *ctlname, int idx)
12240 char name[32];
12241 int err;
12243 sprintf(name, "%s Playback Volume", ctlname);
12244 if (nid == 0x14) {
12245 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12246 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
12247 HDA_OUTPUT));
12248 if (err < 0)
12249 return err;
12250 } else if (nid == 0x15) {
12251 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12252 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
12253 HDA_OUTPUT));
12254 if (err < 0)
12255 return err;
12256 } else
12257 return -1;
12258 sprintf(name, "%s Playback Switch", ctlname);
12259 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12260 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12261 if (err < 0)
12262 return err;
12263 return 0;
12266 /* add playback controls from the parsed DAC table */
12267 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12268 const struct auto_pin_cfg *cfg)
12270 hda_nid_t nid;
12271 int err;
12273 spec->multiout.num_dacs = 2; /* only use one dac */
12274 spec->multiout.dac_nids = spec->private_dac_nids;
12275 spec->multiout.dac_nids[0] = 2;
12276 spec->multiout.dac_nids[1] = 3;
12278 nid = cfg->line_out_pins[0];
12279 if (nid)
12280 alc268_new_analog_output(spec, nid, "Front", 0);
12282 nid = cfg->speaker_pins[0];
12283 if (nid == 0x1d) {
12284 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12285 "Speaker Playback Volume",
12286 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12287 if (err < 0)
12288 return err;
12290 nid = cfg->hp_pins[0];
12291 if (nid)
12292 alc268_new_analog_output(spec, nid, "Headphone", 0);
12294 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12295 if (nid == 0x16) {
12296 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12297 "Mono Playback Switch",
12298 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
12299 if (err < 0)
12300 return err;
12302 return 0;
12305 /* create playback/capture controls for input pins */
12306 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
12307 const struct auto_pin_cfg *cfg)
12309 struct hda_input_mux *imux = &spec->private_imux[0];
12310 int i, idx1;
12312 for (i = 0; i < AUTO_PIN_LAST; i++) {
12313 switch(cfg->input_pins[i]) {
12314 case 0x18:
12315 idx1 = 0; /* Mic 1 */
12316 break;
12317 case 0x19:
12318 idx1 = 1; /* Mic 2 */
12319 break;
12320 case 0x1a:
12321 idx1 = 2; /* Line In */
12322 break;
12323 case 0x1c:
12324 idx1 = 3; /* CD */
12325 break;
12326 case 0x12:
12327 case 0x13:
12328 idx1 = 6; /* digital mics */
12329 break;
12330 default:
12331 continue;
12333 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12334 imux->items[imux->num_items].index = idx1;
12335 imux->num_items++;
12337 return 0;
12340 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12342 struct alc_spec *spec = codec->spec;
12343 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
12344 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
12345 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12346 unsigned int dac_vol1, dac_vol2;
12348 if (speaker_nid) {
12349 snd_hda_codec_write(codec, speaker_nid, 0,
12350 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12351 snd_hda_codec_write(codec, 0x0f, 0,
12352 AC_VERB_SET_AMP_GAIN_MUTE,
12353 AMP_IN_UNMUTE(1));
12354 snd_hda_codec_write(codec, 0x10, 0,
12355 AC_VERB_SET_AMP_GAIN_MUTE,
12356 AMP_IN_UNMUTE(1));
12357 } else {
12358 snd_hda_codec_write(codec, 0x0f, 0,
12359 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12360 snd_hda_codec_write(codec, 0x10, 0,
12361 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12364 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
12365 if (line_nid == 0x14)
12366 dac_vol2 = AMP_OUT_ZERO;
12367 else if (line_nid == 0x15)
12368 dac_vol1 = AMP_OUT_ZERO;
12369 if (hp_nid == 0x14)
12370 dac_vol2 = AMP_OUT_ZERO;
12371 else if (hp_nid == 0x15)
12372 dac_vol1 = AMP_OUT_ZERO;
12373 if (line_nid != 0x16 || hp_nid != 0x16 ||
12374 spec->autocfg.line_out_pins[1] != 0x16 ||
12375 spec->autocfg.line_out_pins[2] != 0x16)
12376 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
12378 snd_hda_codec_write(codec, 0x02, 0,
12379 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
12380 snd_hda_codec_write(codec, 0x03, 0,
12381 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
12384 /* pcm configuration: identical with ALC880 */
12385 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
12386 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
12387 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
12388 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
12391 * BIOS auto configuration
12393 static int alc268_parse_auto_config(struct hda_codec *codec)
12395 struct alc_spec *spec = codec->spec;
12396 int err;
12397 static hda_nid_t alc268_ignore[] = { 0 };
12399 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12400 alc268_ignore);
12401 if (err < 0)
12402 return err;
12403 if (!spec->autocfg.line_outs) {
12404 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12405 spec->multiout.max_channels = 2;
12406 spec->no_analog = 1;
12407 goto dig_only;
12409 return 0; /* can't find valid BIOS pin config */
12411 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12412 if (err < 0)
12413 return err;
12414 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
12415 if (err < 0)
12416 return err;
12418 spec->multiout.max_channels = 2;
12420 dig_only:
12421 /* digital only support output */
12422 if (spec->autocfg.dig_outs) {
12423 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
12424 spec->dig_out_type = spec->autocfg.dig_out_type[0];
12426 if (spec->kctls.list)
12427 add_mixer(spec, spec->kctls.list);
12429 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
12430 add_mixer(spec, alc268_beep_mixer);
12432 add_verb(spec, alc268_volume_init_verbs);
12433 spec->num_mux_defs = 1;
12434 spec->input_mux = &spec->private_imux[0];
12436 err = alc_auto_add_mic_boost(codec);
12437 if (err < 0)
12438 return err;
12440 return 1;
12443 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
12444 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
12445 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
12447 /* init callback for auto-configuration model -- overriding the default init */
12448 static void alc268_auto_init(struct hda_codec *codec)
12450 struct alc_spec *spec = codec->spec;
12451 alc268_auto_init_multi_out(codec);
12452 alc268_auto_init_hp_out(codec);
12453 alc268_auto_init_mono_speaker_out(codec);
12454 alc268_auto_init_analog_input(codec);
12455 if (spec->unsol_event)
12456 alc_inithook(codec);
12460 * configuration and preset
12462 static const char *alc268_models[ALC268_MODEL_LAST] = {
12463 [ALC267_QUANTA_IL1] = "quanta-il1",
12464 [ALC268_3ST] = "3stack",
12465 [ALC268_TOSHIBA] = "toshiba",
12466 [ALC268_ACER] = "acer",
12467 [ALC268_ACER_DMIC] = "acer-dmic",
12468 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
12469 [ALC268_DELL] = "dell",
12470 [ALC268_ZEPTO] = "zepto",
12471 #ifdef CONFIG_SND_DEBUG
12472 [ALC268_TEST] = "test",
12473 #endif
12474 [ALC268_AUTO] = "auto",
12477 static struct snd_pci_quirk alc268_cfg_tbl[] = {
12478 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
12479 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
12480 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
12481 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
12482 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
12483 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
12484 ALC268_ACER_ASPIRE_ONE),
12485 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12486 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12487 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12488 ALC268_TOSHIBA),
12489 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12490 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12491 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
12492 ALC268_TOSHIBA),
12493 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
12494 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
12495 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
12496 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
12500 static struct alc_config_preset alc268_presets[] = {
12501 [ALC267_QUANTA_IL1] = {
12502 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer },
12503 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12504 alc267_quanta_il1_verbs },
12505 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12506 .dac_nids = alc268_dac_nids,
12507 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12508 .adc_nids = alc268_adc_nids_alt,
12509 .hp_nid = 0x03,
12510 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12511 .channel_mode = alc268_modes,
12512 .input_mux = &alc268_capture_source,
12513 .unsol_event = alc267_quanta_il1_unsol_event,
12514 .init_hook = alc267_quanta_il1_init_hook,
12516 [ALC268_3ST] = {
12517 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12518 alc268_beep_mixer },
12519 .init_verbs = { alc268_base_init_verbs },
12520 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12521 .dac_nids = alc268_dac_nids,
12522 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12523 .adc_nids = alc268_adc_nids_alt,
12524 .capsrc_nids = alc268_capsrc_nids,
12525 .hp_nid = 0x03,
12526 .dig_out_nid = ALC268_DIGOUT_NID,
12527 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12528 .channel_mode = alc268_modes,
12529 .input_mux = &alc268_capture_source,
12531 [ALC268_TOSHIBA] = {
12532 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
12533 alc268_beep_mixer },
12534 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12535 alc268_toshiba_verbs },
12536 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12537 .dac_nids = alc268_dac_nids,
12538 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12539 .adc_nids = alc268_adc_nids_alt,
12540 .capsrc_nids = alc268_capsrc_nids,
12541 .hp_nid = 0x03,
12542 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12543 .channel_mode = alc268_modes,
12544 .input_mux = &alc268_capture_source,
12545 .unsol_event = alc268_toshiba_unsol_event,
12546 .init_hook = alc268_toshiba_init_hook,
12548 [ALC268_ACER] = {
12549 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
12550 alc268_beep_mixer },
12551 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12552 alc268_acer_verbs },
12553 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12554 .dac_nids = alc268_dac_nids,
12555 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12556 .adc_nids = alc268_adc_nids_alt,
12557 .capsrc_nids = alc268_capsrc_nids,
12558 .hp_nid = 0x02,
12559 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12560 .channel_mode = alc268_modes,
12561 .input_mux = &alc268_acer_capture_source,
12562 .unsol_event = alc268_acer_unsol_event,
12563 .init_hook = alc268_acer_init_hook,
12565 [ALC268_ACER_DMIC] = {
12566 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
12567 alc268_beep_mixer },
12568 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12569 alc268_acer_verbs },
12570 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12571 .dac_nids = alc268_dac_nids,
12572 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12573 .adc_nids = alc268_adc_nids_alt,
12574 .capsrc_nids = alc268_capsrc_nids,
12575 .hp_nid = 0x02,
12576 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12577 .channel_mode = alc268_modes,
12578 .input_mux = &alc268_acer_dmic_capture_source,
12579 .unsol_event = alc268_acer_unsol_event,
12580 .init_hook = alc268_acer_init_hook,
12582 [ALC268_ACER_ASPIRE_ONE] = {
12583 .mixers = { alc268_acer_aspire_one_mixer,
12584 alc268_beep_mixer,
12585 alc268_capture_alt_mixer },
12586 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12587 alc268_acer_aspire_one_verbs },
12588 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12589 .dac_nids = alc268_dac_nids,
12590 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12591 .adc_nids = alc268_adc_nids_alt,
12592 .capsrc_nids = alc268_capsrc_nids,
12593 .hp_nid = 0x03,
12594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12595 .channel_mode = alc268_modes,
12596 .input_mux = &alc268_acer_lc_capture_source,
12597 .unsol_event = alc268_acer_lc_unsol_event,
12598 .init_hook = alc268_acer_lc_init_hook,
12600 [ALC268_DELL] = {
12601 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
12602 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12603 alc268_dell_verbs },
12604 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12605 .dac_nids = alc268_dac_nids,
12606 .hp_nid = 0x02,
12607 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12608 .channel_mode = alc268_modes,
12609 .unsol_event = alc_sku_unsol_event,
12610 .init_hook = alc268_dell_init_hook,
12611 .input_mux = &alc268_capture_source,
12613 [ALC268_ZEPTO] = {
12614 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
12615 alc268_beep_mixer },
12616 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12617 alc268_toshiba_verbs },
12618 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12619 .dac_nids = alc268_dac_nids,
12620 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12621 .adc_nids = alc268_adc_nids_alt,
12622 .capsrc_nids = alc268_capsrc_nids,
12623 .hp_nid = 0x03,
12624 .dig_out_nid = ALC268_DIGOUT_NID,
12625 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12626 .channel_mode = alc268_modes,
12627 .input_mux = &alc268_capture_source,
12628 .unsol_event = alc268_toshiba_unsol_event,
12629 .init_hook = alc268_toshiba_init_hook
12631 #ifdef CONFIG_SND_DEBUG
12632 [ALC268_TEST] = {
12633 .mixers = { alc268_test_mixer, alc268_capture_mixer },
12634 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12635 alc268_volume_init_verbs },
12636 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12637 .dac_nids = alc268_dac_nids,
12638 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12639 .adc_nids = alc268_adc_nids_alt,
12640 .capsrc_nids = alc268_capsrc_nids,
12641 .hp_nid = 0x03,
12642 .dig_out_nid = ALC268_DIGOUT_NID,
12643 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12644 .channel_mode = alc268_modes,
12645 .input_mux = &alc268_capture_source,
12647 #endif
12650 static int patch_alc268(struct hda_codec *codec)
12652 struct alc_spec *spec;
12653 int board_config;
12654 int i, has_beep, err;
12656 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
12657 if (spec == NULL)
12658 return -ENOMEM;
12660 codec->spec = spec;
12662 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
12663 alc268_models,
12664 alc268_cfg_tbl);
12666 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12667 printk(KERN_INFO "hda_codec: Unknown model for %s, "
12668 "trying auto-probe from BIOS...\n", codec->chip_name);
12669 board_config = ALC268_AUTO;
12672 if (board_config == ALC268_AUTO) {
12673 /* automatic parse from the BIOS config */
12674 err = alc268_parse_auto_config(codec);
12675 if (err < 0) {
12676 alc_free(codec);
12677 return err;
12678 } else if (!err) {
12679 printk(KERN_INFO
12680 "hda_codec: Cannot set up configuration "
12681 "from BIOS. Using base mode...\n");
12682 board_config = ALC268_3ST;
12686 if (board_config != ALC268_AUTO)
12687 setup_preset(spec, &alc268_presets[board_config]);
12689 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12690 spec->stream_analog_capture = &alc268_pcm_analog_capture;
12691 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
12693 spec->stream_digital_playback = &alc268_pcm_digital_playback;
12695 has_beep = 0;
12696 for (i = 0; i < spec->num_mixers; i++) {
12697 if (spec->mixers[i] == alc268_beep_mixer) {
12698 has_beep = 1;
12699 break;
12703 if (has_beep) {
12704 err = snd_hda_attach_beep_device(codec, 0x1);
12705 if (err < 0) {
12706 alc_free(codec);
12707 return err;
12709 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
12710 /* override the amp caps for beep generator */
12711 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
12712 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
12713 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
12714 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
12715 (0 << AC_AMPCAP_MUTE_SHIFT));
12718 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
12719 /* check whether NID 0x07 is valid */
12720 unsigned int wcap = get_wcaps(codec, 0x07);
12721 int i;
12723 /* get type */
12724 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
12725 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12726 spec->adc_nids = alc268_adc_nids_alt;
12727 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12728 add_mixer(spec, alc268_capture_alt_mixer);
12729 } else {
12730 spec->adc_nids = alc268_adc_nids;
12731 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
12732 add_mixer(spec, alc268_capture_mixer);
12734 spec->capsrc_nids = alc268_capsrc_nids;
12735 /* set default input source */
12736 for (i = 0; i < spec->num_adc_nids; i++)
12737 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12738 0, AC_VERB_SET_CONNECT_SEL,
12739 spec->input_mux->items[0].index);
12742 spec->vmaster_nid = 0x02;
12744 codec->patch_ops = alc_patch_ops;
12745 if (board_config == ALC268_AUTO)
12746 spec->init_hook = alc268_auto_init;
12748 codec->proc_widget_hook = print_realtek_coef;
12750 return 0;
12754 * ALC269 channel source setting (2 channel)
12756 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
12758 #define alc269_dac_nids alc260_dac_nids
12760 static hda_nid_t alc269_adc_nids[1] = {
12761 /* ADC1 */
12762 0x08,
12765 static hda_nid_t alc269_capsrc_nids[1] = {
12766 0x23,
12769 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
12770 * not a mux!
12773 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12774 .num_items = 2,
12775 .items = {
12776 { "i-Mic", 0x5 },
12777 { "e-Mic", 0x0 },
12781 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12782 .num_items = 2,
12783 .items = {
12784 { "i-Mic", 0x1 },
12785 { "e-Mic", 0x0 },
12789 #define alc269_modes alc260_modes
12790 #define alc269_capture_source alc880_lg_lw_capture_source
12792 static struct snd_kcontrol_new alc269_base_mixer[] = {
12793 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12794 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12795 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12796 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12797 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12798 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12799 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12800 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12801 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12802 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12803 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12804 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
12805 { } /* end */
12808 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
12809 /* output mixer control */
12810 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12812 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12813 .name = "Master Playback Switch",
12814 .info = snd_hda_mixer_amp_switch_info,
12815 .get = snd_hda_mixer_amp_switch_get,
12816 .put = alc268_acer_master_sw_put,
12817 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12822 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12823 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12824 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12828 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12829 /* output mixer control */
12830 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12833 .name = "Master Playback Switch",
12834 .info = snd_hda_mixer_amp_switch_info,
12835 .get = snd_hda_mixer_amp_switch_get,
12836 .put = alc268_acer_master_sw_put,
12837 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12842 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12843 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12844 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12845 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12846 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12847 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12851 /* bind volumes of both NID 0x0c and 0x0d */
12852 static struct hda_bind_ctls alc269_epc_bind_vol = {
12853 .ops = &snd_hda_bind_vol,
12854 .values = {
12855 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12856 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12861 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
12862 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12863 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
12864 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12865 { } /* end */
12868 /* capture mixer elements */
12869 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
12870 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12871 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12872 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12873 { } /* end */
12876 /* FSC amilo */
12877 static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
12878 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12879 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12880 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
12881 { } /* end */
12884 static struct hda_verb alc269_quanta_fl1_verbs[] = {
12885 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12886 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12887 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12888 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12889 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12890 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12894 static struct hda_verb alc269_lifebook_verbs[] = {
12895 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12896 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12897 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12901 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12902 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12903 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12904 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12908 /* toggle speaker-output according to the hp-jack state */
12909 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
12911 unsigned int present;
12912 unsigned char bits;
12914 present = snd_hda_codec_read(codec, 0x15, 0,
12915 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12916 bits = present ? AMP_IN_MUTE(0) : 0;
12917 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12918 AMP_IN_MUTE(0), bits);
12919 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12920 AMP_IN_MUTE(0), bits);
12922 snd_hda_codec_write(codec, 0x20, 0,
12923 AC_VERB_SET_COEF_INDEX, 0x0c);
12924 snd_hda_codec_write(codec, 0x20, 0,
12925 AC_VERB_SET_PROC_COEF, 0x680);
12927 snd_hda_codec_write(codec, 0x20, 0,
12928 AC_VERB_SET_COEF_INDEX, 0x0c);
12929 snd_hda_codec_write(codec, 0x20, 0,
12930 AC_VERB_SET_PROC_COEF, 0x480);
12933 /* toggle speaker-output according to the hp-jacks state */
12934 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12936 unsigned int present;
12937 unsigned char bits;
12939 /* Check laptop headphone socket */
12940 present = snd_hda_codec_read(codec, 0x15, 0,
12941 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12943 /* Check port replicator headphone socket */
12944 present |= snd_hda_codec_read(codec, 0x1a, 0,
12945 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12947 bits = present ? AMP_IN_MUTE(0) : 0;
12948 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12949 AMP_IN_MUTE(0), bits);
12950 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12951 AMP_IN_MUTE(0), bits);
12953 snd_hda_codec_write(codec, 0x20, 0,
12954 AC_VERB_SET_COEF_INDEX, 0x0c);
12955 snd_hda_codec_write(codec, 0x20, 0,
12956 AC_VERB_SET_PROC_COEF, 0x680);
12958 snd_hda_codec_write(codec, 0x20, 0,
12959 AC_VERB_SET_COEF_INDEX, 0x0c);
12960 snd_hda_codec_write(codec, 0x20, 0,
12961 AC_VERB_SET_PROC_COEF, 0x480);
12964 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12966 unsigned int present;
12968 present = snd_hda_codec_read(codec, 0x18, 0,
12969 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12970 snd_hda_codec_write(codec, 0x23, 0,
12971 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
12974 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12976 unsigned int present_laptop;
12977 unsigned int present_dock;
12979 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12980 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12982 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12983 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12985 /* Laptop mic port overrides dock mic port, design decision */
12986 if (present_dock)
12987 snd_hda_codec_write(codec, 0x23, 0,
12988 AC_VERB_SET_CONNECT_SEL, 0x3);
12989 if (present_laptop)
12990 snd_hda_codec_write(codec, 0x23, 0,
12991 AC_VERB_SET_CONNECT_SEL, 0x0);
12992 if (!present_dock && !present_laptop)
12993 snd_hda_codec_write(codec, 0x23, 0,
12994 AC_VERB_SET_CONNECT_SEL, 0x1);
12997 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
12998 unsigned int res)
13000 if ((res >> 26) == ALC880_HP_EVENT)
13001 alc269_quanta_fl1_speaker_automute(codec);
13002 if ((res >> 26) == ALC880_MIC_EVENT)
13003 alc269_quanta_fl1_mic_automute(codec);
13006 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13007 unsigned int res)
13009 if ((res >> 26) == ALC880_HP_EVENT)
13010 alc269_lifebook_speaker_automute(codec);
13011 if ((res >> 26) == ALC880_MIC_EVENT)
13012 alc269_lifebook_mic_autoswitch(codec);
13015 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13017 alc269_quanta_fl1_speaker_automute(codec);
13018 alc269_quanta_fl1_mic_automute(codec);
13021 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13023 alc269_lifebook_speaker_automute(codec);
13024 alc269_lifebook_mic_autoswitch(codec);
13027 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13029 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13032 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13034 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13038 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13040 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13041 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13048 /* toggle speaker-output according to the hp-jack state */
13049 static void alc269_speaker_automute(struct hda_codec *codec)
13051 unsigned int present;
13052 unsigned char bits;
13054 present = snd_hda_codec_read(codec, 0x15, 0,
13055 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13056 bits = present ? AMP_IN_MUTE(0) : 0;
13057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13058 AMP_IN_MUTE(0), bits);
13059 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13060 AMP_IN_MUTE(0), bits);
13063 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
13065 unsigned int present;
13067 present = snd_hda_codec_read(codec, 0x18, 0,
13068 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13069 snd_hda_codec_write(codec, 0x23, 0,
13070 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
13073 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
13075 unsigned int present;
13077 present = snd_hda_codec_read(codec, 0x18, 0,
13078 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13079 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13080 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13081 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13082 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13085 /* unsolicited event for HP jack sensing */
13086 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
13087 unsigned int res)
13089 if ((res >> 26) == ALC880_HP_EVENT)
13090 alc269_speaker_automute(codec);
13092 if ((res >> 26) == ALC880_MIC_EVENT)
13093 alc269_eeepc_dmic_automute(codec);
13096 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
13098 alc269_speaker_automute(codec);
13099 alc269_eeepc_dmic_automute(codec);
13102 /* unsolicited event for HP jack sensing */
13103 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
13104 unsigned int res)
13106 if ((res >> 26) == ALC880_HP_EVENT)
13107 alc269_speaker_automute(codec);
13109 if ((res >> 26) == ALC880_MIC_EVENT)
13110 alc269_eeepc_amic_automute(codec);
13113 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
13115 alc269_speaker_automute(codec);
13116 alc269_eeepc_amic_automute(codec);
13120 * generic initialization of ADC, input mixers and output mixers
13122 static struct hda_verb alc269_init_verbs[] = {
13124 * Unmute ADC0 and set the default input to mic-in
13126 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13128 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13129 * analog-loopback mixer widget
13130 * Note: PASD motherboards uses the Line In 2 as the input for
13131 * front panel mic (mic 2)
13133 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13141 * Set up output mixers (0x0c - 0x0e)
13143 /* set vol=0 to output mixers */
13144 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13145 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13147 /* set up input amps for analog loopback */
13148 /* Amp Indices: DAC = 0, mixer = 1 */
13149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13151 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13152 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13153 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13154 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13156 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13159 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13160 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13161 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13162 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13164 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13166 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13167 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13168 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13169 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13170 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13172 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13173 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
13175 /* FIXME: use matrix-type input source selection */
13176 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13177 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13178 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13179 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13180 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13181 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13183 /* set EAPD */
13184 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13185 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13189 /* add playback controls from the parsed DAC table */
13190 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
13191 const struct auto_pin_cfg *cfg)
13193 hda_nid_t nid;
13194 int err;
13196 spec->multiout.num_dacs = 1; /* only use one dac */
13197 spec->multiout.dac_nids = spec->private_dac_nids;
13198 spec->multiout.dac_nids[0] = 2;
13200 nid = cfg->line_out_pins[0];
13201 if (nid) {
13202 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13203 "Front Playback Volume",
13204 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
13205 if (err < 0)
13206 return err;
13207 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13208 "Front Playback Switch",
13209 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13210 if (err < 0)
13211 return err;
13214 nid = cfg->speaker_pins[0];
13215 if (nid) {
13216 if (!cfg->line_out_pins[0]) {
13217 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13218 "Speaker Playback Volume",
13219 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
13220 HDA_OUTPUT));
13221 if (err < 0)
13222 return err;
13224 if (nid == 0x16) {
13225 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13226 "Speaker Playback Switch",
13227 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13228 HDA_OUTPUT));
13229 if (err < 0)
13230 return err;
13231 } else {
13232 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13233 "Speaker Playback Switch",
13234 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13235 HDA_OUTPUT));
13236 if (err < 0)
13237 return err;
13240 nid = cfg->hp_pins[0];
13241 if (nid) {
13242 /* spec->multiout.hp_nid = 2; */
13243 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
13244 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13245 "Headphone Playback Volume",
13246 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
13247 HDA_OUTPUT));
13248 if (err < 0)
13249 return err;
13251 if (nid == 0x16) {
13252 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13253 "Headphone Playback Switch",
13254 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13255 HDA_OUTPUT));
13256 if (err < 0)
13257 return err;
13258 } else {
13259 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13260 "Headphone Playback Switch",
13261 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13262 HDA_OUTPUT));
13263 if (err < 0)
13264 return err;
13267 return 0;
13270 #define alc269_auto_create_analog_input_ctls \
13271 alc262_auto_create_analog_input_ctls
13273 #ifdef CONFIG_SND_HDA_POWER_SAVE
13274 #define alc269_loopbacks alc880_loopbacks
13275 #endif
13277 /* pcm configuration: identical with ALC880 */
13278 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13279 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13280 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13281 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13283 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13284 .substreams = 1,
13285 .channels_min = 2,
13286 .channels_max = 8,
13287 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13288 /* NID is set in alc_build_pcms */
13289 .ops = {
13290 .open = alc880_playback_pcm_open,
13291 .prepare = alc880_playback_pcm_prepare,
13292 .cleanup = alc880_playback_pcm_cleanup
13296 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13297 .substreams = 1,
13298 .channels_min = 2,
13299 .channels_max = 2,
13300 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13301 /* NID is set in alc_build_pcms */
13305 * BIOS auto configuration
13307 static int alc269_parse_auto_config(struct hda_codec *codec)
13309 struct alc_spec *spec = codec->spec;
13310 int err;
13311 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13313 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13314 alc269_ignore);
13315 if (err < 0)
13316 return err;
13318 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13319 if (err < 0)
13320 return err;
13321 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
13322 if (err < 0)
13323 return err;
13325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13327 if (spec->autocfg.dig_outs)
13328 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
13330 if (spec->kctls.list)
13331 add_mixer(spec, spec->kctls.list);
13333 add_verb(spec, alc269_init_verbs);
13334 spec->num_mux_defs = 1;
13335 spec->input_mux = &spec->private_imux[0];
13336 /* set default input source */
13337 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
13338 0, AC_VERB_SET_CONNECT_SEL,
13339 spec->input_mux->items[0].index);
13341 err = alc_auto_add_mic_boost(codec);
13342 if (err < 0)
13343 return err;
13345 if (!spec->cap_mixer && !spec->no_analog)
13346 set_capture_mixer(spec);
13348 return 1;
13351 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
13352 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
13353 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
13356 /* init callback for auto-configuration model -- overriding the default init */
13357 static void alc269_auto_init(struct hda_codec *codec)
13359 struct alc_spec *spec = codec->spec;
13360 alc269_auto_init_multi_out(codec);
13361 alc269_auto_init_hp_out(codec);
13362 alc269_auto_init_analog_input(codec);
13363 if (spec->unsol_event)
13364 alc_inithook(codec);
13368 * configuration and preset
13370 static const char *alc269_models[ALC269_MODEL_LAST] = {
13371 [ALC269_BASIC] = "basic",
13372 [ALC269_QUANTA_FL1] = "quanta",
13373 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
13374 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
13375 [ALC269_FUJITSU] = "fujitsu",
13376 [ALC269_LIFEBOOK] = "lifebook"
13379 static struct snd_pci_quirk alc269_cfg_tbl[] = {
13380 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13381 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13382 ALC269_ASUS_EEEPC_P703),
13383 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_EEEPC_P703),
13384 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_EEEPC_P703),
13385 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_EEEPC_P703),
13386 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_EEEPC_P703),
13387 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_EEEPC_P703),
13388 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_EEEPC_P703),
13389 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13390 ALC269_ASUS_EEEPC_P901),
13391 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13392 ALC269_ASUS_EEEPC_P901),
13393 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_EEEPC_P901),
13394 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13395 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13399 static struct alc_config_preset alc269_presets[] = {
13400 [ALC269_BASIC] = {
13401 .mixers = { alc269_base_mixer },
13402 .init_verbs = { alc269_init_verbs },
13403 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13404 .dac_nids = alc269_dac_nids,
13405 .hp_nid = 0x03,
13406 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13407 .channel_mode = alc269_modes,
13408 .input_mux = &alc269_capture_source,
13410 [ALC269_QUANTA_FL1] = {
13411 .mixers = { alc269_quanta_fl1_mixer },
13412 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
13413 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13414 .dac_nids = alc269_dac_nids,
13415 .hp_nid = 0x03,
13416 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13417 .channel_mode = alc269_modes,
13418 .input_mux = &alc269_capture_source,
13419 .unsol_event = alc269_quanta_fl1_unsol_event,
13420 .init_hook = alc269_quanta_fl1_init_hook,
13422 [ALC269_ASUS_EEEPC_P703] = {
13423 .mixers = { alc269_eeepc_mixer },
13424 .cap_mixer = alc269_epc_capture_mixer,
13425 .init_verbs = { alc269_init_verbs,
13426 alc269_eeepc_amic_init_verbs },
13427 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13428 .dac_nids = alc269_dac_nids,
13429 .hp_nid = 0x03,
13430 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13431 .channel_mode = alc269_modes,
13432 .input_mux = &alc269_eeepc_amic_capture_source,
13433 .unsol_event = alc269_eeepc_amic_unsol_event,
13434 .init_hook = alc269_eeepc_amic_inithook,
13436 [ALC269_ASUS_EEEPC_P901] = {
13437 .mixers = { alc269_eeepc_mixer },
13438 .cap_mixer = alc269_epc_capture_mixer,
13439 .init_verbs = { alc269_init_verbs,
13440 alc269_eeepc_dmic_init_verbs },
13441 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13442 .dac_nids = alc269_dac_nids,
13443 .hp_nid = 0x03,
13444 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13445 .channel_mode = alc269_modes,
13446 .input_mux = &alc269_eeepc_dmic_capture_source,
13447 .unsol_event = alc269_eeepc_dmic_unsol_event,
13448 .init_hook = alc269_eeepc_dmic_inithook,
13450 [ALC269_FUJITSU] = {
13451 .mixers = { alc269_fujitsu_mixer },
13452 .cap_mixer = alc269_epc_capture_mixer,
13453 .init_verbs = { alc269_init_verbs,
13454 alc269_eeepc_dmic_init_verbs },
13455 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13456 .dac_nids = alc269_dac_nids,
13457 .hp_nid = 0x03,
13458 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13459 .channel_mode = alc269_modes,
13460 .input_mux = &alc269_eeepc_dmic_capture_source,
13461 .unsol_event = alc269_eeepc_dmic_unsol_event,
13462 .init_hook = alc269_eeepc_dmic_inithook,
13464 [ALC269_LIFEBOOK] = {
13465 .mixers = { alc269_lifebook_mixer },
13466 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
13467 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13468 .dac_nids = alc269_dac_nids,
13469 .hp_nid = 0x03,
13470 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13471 .channel_mode = alc269_modes,
13472 .input_mux = &alc269_capture_source,
13473 .unsol_event = alc269_lifebook_unsol_event,
13474 .init_hook = alc269_lifebook_init_hook,
13478 static int patch_alc269(struct hda_codec *codec)
13480 struct alc_spec *spec;
13481 int board_config;
13482 int err;
13484 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13485 if (spec == NULL)
13486 return -ENOMEM;
13488 codec->spec = spec;
13490 alc_fix_pll_init(codec, 0x20, 0x04, 15);
13492 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
13493 alc269_models,
13494 alc269_cfg_tbl);
13496 if (board_config < 0) {
13497 printk(KERN_INFO "hda_codec: Unknown model for %s, "
13498 "trying auto-probe from BIOS...\n", codec->chip_name);
13499 board_config = ALC269_AUTO;
13502 if (board_config == ALC269_AUTO) {
13503 /* automatic parse from the BIOS config */
13504 err = alc269_parse_auto_config(codec);
13505 if (err < 0) {
13506 alc_free(codec);
13507 return err;
13508 } else if (!err) {
13509 printk(KERN_INFO
13510 "hda_codec: Cannot set up configuration "
13511 "from BIOS. Using base mode...\n");
13512 board_config = ALC269_BASIC;
13516 err = snd_hda_attach_beep_device(codec, 0x1);
13517 if (err < 0) {
13518 alc_free(codec);
13519 return err;
13522 if (board_config != ALC269_AUTO)
13523 setup_preset(spec, &alc269_presets[board_config]);
13525 if (codec->subsystem_id == 0x17aa3bf8) {
13526 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13527 * fix the sample rate of analog I/O to 44.1kHz
13529 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
13530 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
13531 } else {
13532 spec->stream_analog_playback = &alc269_pcm_analog_playback;
13533 spec->stream_analog_capture = &alc269_pcm_analog_capture;
13535 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13536 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13538 spec->adc_nids = alc269_adc_nids;
13539 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13540 spec->capsrc_nids = alc269_capsrc_nids;
13541 if (!spec->cap_mixer)
13542 set_capture_mixer(spec);
13543 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13545 codec->patch_ops = alc_patch_ops;
13546 if (board_config == ALC269_AUTO)
13547 spec->init_hook = alc269_auto_init;
13548 #ifdef CONFIG_SND_HDA_POWER_SAVE
13549 if (!spec->loopback.amplist)
13550 spec->loopback.amplist = alc269_loopbacks;
13551 #endif
13552 codec->proc_widget_hook = print_realtek_coef;
13554 return 0;
13558 * ALC861 channel source setting (2/6 channel selection for 3-stack)
13562 * set the path ways for 2 channel output
13563 * need to set the codec line out and mic 1 pin widgets to inputs
13565 static struct hda_verb alc861_threestack_ch2_init[] = {
13566 /* set pin widget 1Ah (line in) for input */
13567 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13568 /* set pin widget 18h (mic1/2) for input, for mic also enable
13569 * the vref
13571 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13573 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13574 #if 0
13575 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13576 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13577 #endif
13578 { } /* end */
13581 * 6ch mode
13582 * need to set the codec line out and mic 1 pin widgets to outputs
13584 static struct hda_verb alc861_threestack_ch6_init[] = {
13585 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13586 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13587 /* set pin widget 18h (mic1) for output (CLFE)*/
13588 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13590 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13591 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13593 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13594 #if 0
13595 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13596 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13597 #endif
13598 { } /* end */
13601 static struct hda_channel_mode alc861_threestack_modes[2] = {
13602 { 2, alc861_threestack_ch2_init },
13603 { 6, alc861_threestack_ch6_init },
13605 /* Set mic1 as input and unmute the mixer */
13606 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
13607 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13608 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13609 { } /* end */
13611 /* Set mic1 as output and mute mixer */
13612 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
13613 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13614 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13615 { } /* end */
13618 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
13619 { 2, alc861_uniwill_m31_ch2_init },
13620 { 4, alc861_uniwill_m31_ch4_init },
13623 /* Set mic1 and line-in as input and unmute the mixer */
13624 static struct hda_verb alc861_asus_ch2_init[] = {
13625 /* set pin widget 1Ah (line in) for input */
13626 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13627 /* set pin widget 18h (mic1/2) for input, for mic also enable
13628 * the vref
13630 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13632 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
13633 #if 0
13634 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
13635 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
13636 #endif
13637 { } /* end */
13639 /* Set mic1 nad line-in as output and mute mixer */
13640 static struct hda_verb alc861_asus_ch6_init[] = {
13641 /* set pin widget 1Ah (line in) for output (Back Surround)*/
13642 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13643 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13644 /* set pin widget 18h (mic1) for output (CLFE)*/
13645 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13646 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
13647 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
13648 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
13650 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
13651 #if 0
13652 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
13653 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
13654 #endif
13655 { } /* end */
13658 static struct hda_channel_mode alc861_asus_modes[2] = {
13659 { 2, alc861_asus_ch2_init },
13660 { 6, alc861_asus_ch6_init },
13663 /* patch-ALC861 */
13665 static struct snd_kcontrol_new alc861_base_mixer[] = {
13666 /* output mixer control */
13667 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13668 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13669 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13670 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13671 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13673 /*Input mixer control */
13674 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13675 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13676 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13677 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13678 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13679 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13680 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13681 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13682 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13685 { } /* end */
13688 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
13689 /* output mixer control */
13690 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13691 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13692 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13693 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13694 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13696 /* Input mixer control */
13697 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13698 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13699 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13700 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13701 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13702 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13704 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13705 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13710 .name = "Channel Mode",
13711 .info = alc_ch_mode_info,
13712 .get = alc_ch_mode_get,
13713 .put = alc_ch_mode_put,
13714 .private_value = ARRAY_SIZE(alc861_threestack_modes),
13716 { } /* end */
13719 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
13720 /* output mixer control */
13721 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13722 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13723 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13725 { } /* end */
13728 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
13729 /* output mixer control */
13730 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13731 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13732 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13733 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13734 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
13736 /* Input mixer control */
13737 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13738 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
13739 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13740 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13741 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13742 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13744 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13745 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13746 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
13749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13750 .name = "Channel Mode",
13751 .info = alc_ch_mode_info,
13752 .get = alc_ch_mode_get,
13753 .put = alc_ch_mode_put,
13754 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
13756 { } /* end */
13759 static struct snd_kcontrol_new alc861_asus_mixer[] = {
13760 /* output mixer control */
13761 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
13762 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
13763 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
13764 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
13765 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
13767 /* Input mixer control */
13768 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
13769 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13770 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13771 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
13773 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
13774 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
13775 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
13776 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
13777 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
13780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13781 .name = "Channel Mode",
13782 .info = alc_ch_mode_info,
13783 .get = alc_ch_mode_get,
13784 .put = alc_ch_mode_put,
13785 .private_value = ARRAY_SIZE(alc861_asus_modes),
13790 /* additional mixer */
13791 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
13792 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
13793 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
13798 * generic initialization of ADC, input mixers and output mixers
13800 static struct hda_verb alc861_base_init_verbs[] = {
13802 * Unmute ADC0 and set the default input to mic-in
13804 /* port-A for surround (rear panel) */
13805 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13806 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
13807 /* port-B for mic-in (rear panel) with vref */
13808 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13809 /* port-C for line-in (rear panel) */
13810 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13811 /* port-D for Front */
13812 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13813 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13814 /* port-E for HP out (front panel) */
13815 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13816 /* route front PCM to HP */
13817 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13818 /* port-F for mic-in (front panel) with vref */
13819 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13820 /* port-G for CLFE (rear panel) */
13821 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13822 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13823 /* port-H for side (rear panel) */
13824 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13825 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
13826 /* CD-in */
13827 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13828 /* route front mic to ADC1*/
13829 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13832 /* Unmute DAC0~3 & spdif out*/
13833 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13834 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13835 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13836 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13837 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13839 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13840 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13841 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13842 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13843 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13845 /* Unmute Stereo Mixer 15 */
13846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13847 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13848 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13849 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13851 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13852 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13853 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13854 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13855 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13856 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13857 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13858 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13859 /* hp used DAC 3 (Front) */
13860 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13861 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13866 static struct hda_verb alc861_threestack_init_verbs[] = {
13868 * Unmute ADC0 and set the default input to mic-in
13870 /* port-A for surround (rear panel) */
13871 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13872 /* port-B for mic-in (rear panel) with vref */
13873 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13874 /* port-C for line-in (rear panel) */
13875 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13876 /* port-D for Front */
13877 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13878 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13879 /* port-E for HP out (front panel) */
13880 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
13881 /* route front PCM to HP */
13882 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13883 /* port-F for mic-in (front panel) with vref */
13884 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13885 /* port-G for CLFE (rear panel) */
13886 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13887 /* port-H for side (rear panel) */
13888 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13889 /* CD-in */
13890 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13891 /* route front mic to ADC1*/
13892 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13893 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13894 /* Unmute DAC0~3 & spdif out*/
13895 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13896 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13897 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13898 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13899 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13901 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13902 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13903 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13904 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13905 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13907 /* Unmute Stereo Mixer 15 */
13908 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13909 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13911 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13913 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13914 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13915 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13916 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13917 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13918 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13919 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13920 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13921 /* hp used DAC 3 (Front) */
13922 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13923 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13927 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
13929 * Unmute ADC0 and set the default input to mic-in
13931 /* port-A for surround (rear panel) */
13932 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13933 /* port-B for mic-in (rear panel) with vref */
13934 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13935 /* port-C for line-in (rear panel) */
13936 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13937 /* port-D for Front */
13938 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
13939 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
13940 /* port-E for HP out (front panel) */
13941 /* this has to be set to VREF80 */
13942 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13943 /* route front PCM to HP */
13944 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
13945 /* port-F for mic-in (front panel) with vref */
13946 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
13947 /* port-G for CLFE (rear panel) */
13948 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13949 /* port-H for side (rear panel) */
13950 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13951 /* CD-in */
13952 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
13953 /* route front mic to ADC1*/
13954 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
13955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13956 /* Unmute DAC0~3 & spdif out*/
13957 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13958 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13959 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13960 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13961 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13963 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13964 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13965 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13966 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13967 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13969 /* Unmute Stereo Mixer 15 */
13970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13971 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13972 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13973 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13975 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13976 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13977 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13978 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13979 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13980 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13981 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13982 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13983 /* hp used DAC 3 (Front) */
13984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13985 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13989 static struct hda_verb alc861_asus_init_verbs[] = {
13991 * Unmute ADC0 and set the default input to mic-in
13993 /* port-A for surround (rear panel)
13994 * according to codec#0 this is the HP jack
13996 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
13997 /* route front PCM to HP */
13998 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
13999 /* port-B for mic-in (rear panel) with vref */
14000 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14001 /* port-C for line-in (rear panel) */
14002 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14003 /* port-D for Front */
14004 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14005 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14006 /* port-E for HP out (front panel) */
14007 /* this has to be set to VREF80 */
14008 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14009 /* route front PCM to HP */
14010 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14011 /* port-F for mic-in (front panel) with vref */
14012 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14013 /* port-G for CLFE (rear panel) */
14014 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14015 /* port-H for side (rear panel) */
14016 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14017 /* CD-in */
14018 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14019 /* route front mic to ADC1*/
14020 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14022 /* Unmute DAC0~3 & spdif out*/
14023 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14024 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14025 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14026 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14027 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14028 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14029 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14030 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14031 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14032 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14034 /* Unmute Stereo Mixer 15 */
14035 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14036 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14037 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14040 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14041 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14042 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14043 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14044 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14045 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14047 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14048 /* hp used DAC 3 (Front) */
14049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14054 /* additional init verbs for ASUS laptops */
14055 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14056 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14057 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14062 * generic initialization of ADC, input mixers and output mixers
14064 static struct hda_verb alc861_auto_init_verbs[] = {
14066 * Unmute ADC0 and set the default input to mic-in
14068 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14069 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14071 /* Unmute DAC0~3 & spdif out*/
14072 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14073 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14074 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14075 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14076 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14078 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14079 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14080 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14081 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14082 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14084 /* Unmute Stereo Mixer 15 */
14085 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14086 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14087 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14091 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14092 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14093 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14094 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14097 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14101 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14102 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14103 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14105 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14106 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14113 static struct hda_verb alc861_toshiba_init_verbs[] = {
14114 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14119 /* toggle speaker-output according to the hp-jack state */
14120 static void alc861_toshiba_automute(struct hda_codec *codec)
14122 unsigned int present;
14124 present = snd_hda_codec_read(codec, 0x0f, 0,
14125 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14126 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14127 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14128 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14129 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14132 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14133 unsigned int res)
14135 if ((res >> 26) == ALC880_HP_EVENT)
14136 alc861_toshiba_automute(codec);
14139 /* pcm configuration: identical with ALC880 */
14140 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
14141 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
14142 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
14143 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
14146 #define ALC861_DIGOUT_NID 0x07
14148 static struct hda_channel_mode alc861_8ch_modes[1] = {
14149 { 8, NULL }
14152 static hda_nid_t alc861_dac_nids[4] = {
14153 /* front, surround, clfe, side */
14154 0x03, 0x06, 0x05, 0x04
14157 static hda_nid_t alc660_dac_nids[3] = {
14158 /* front, clfe, surround */
14159 0x03, 0x05, 0x06
14162 static hda_nid_t alc861_adc_nids[1] = {
14163 /* ADC0-2 */
14164 0x08,
14167 static struct hda_input_mux alc861_capture_source = {
14168 .num_items = 5,
14169 .items = {
14170 { "Mic", 0x0 },
14171 { "Front Mic", 0x3 },
14172 { "Line", 0x1 },
14173 { "CD", 0x4 },
14174 { "Mixer", 0x5 },
14178 /* fill in the dac_nids table from the parsed pin configuration */
14179 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
14180 const struct auto_pin_cfg *cfg)
14182 int i;
14183 hda_nid_t nid;
14185 spec->multiout.dac_nids = spec->private_dac_nids;
14186 for (i = 0; i < cfg->line_outs; i++) {
14187 nid = cfg->line_out_pins[i];
14188 if (nid) {
14189 if (i >= ARRAY_SIZE(alc861_dac_nids))
14190 continue;
14191 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
14194 spec->multiout.num_dacs = cfg->line_outs;
14195 return 0;
14198 /* add playback controls from the parsed DAC table */
14199 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
14200 const struct auto_pin_cfg *cfg)
14202 char name[32];
14203 static const char *chname[4] = {
14204 "Front", "Surround", NULL /*CLFE*/, "Side"
14206 hda_nid_t nid;
14207 int i, idx, err;
14209 for (i = 0; i < cfg->line_outs; i++) {
14210 nid = spec->multiout.dac_nids[i];
14211 if (!nid)
14212 continue;
14213 if (nid == 0x05) {
14214 /* Center/LFE */
14215 err = add_control(spec, ALC_CTL_BIND_MUTE,
14216 "Center Playback Switch",
14217 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14218 HDA_OUTPUT));
14219 if (err < 0)
14220 return err;
14221 err = add_control(spec, ALC_CTL_BIND_MUTE,
14222 "LFE Playback Switch",
14223 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14224 HDA_OUTPUT));
14225 if (err < 0)
14226 return err;
14227 } else {
14228 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
14229 idx++)
14230 if (nid == alc861_dac_nids[idx])
14231 break;
14232 sprintf(name, "%s Playback Switch", chname[idx]);
14233 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14234 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14235 HDA_OUTPUT));
14236 if (err < 0)
14237 return err;
14240 return 0;
14243 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
14245 int err;
14246 hda_nid_t nid;
14248 if (!pin)
14249 return 0;
14251 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14252 nid = 0x03;
14253 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
14254 "Headphone Playback Switch",
14255 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
14256 if (err < 0)
14257 return err;
14258 spec->multiout.hp_nid = nid;
14260 return 0;
14263 /* create playback/capture controls for input pins */
14264 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
14265 const struct auto_pin_cfg *cfg)
14267 struct hda_input_mux *imux = &spec->private_imux[0];
14268 int i, err, idx, idx1;
14270 for (i = 0; i < AUTO_PIN_LAST; i++) {
14271 switch (cfg->input_pins[i]) {
14272 case 0x0c:
14273 idx1 = 1;
14274 idx = 2; /* Line In */
14275 break;
14276 case 0x0f:
14277 idx1 = 2;
14278 idx = 2; /* Line In */
14279 break;
14280 case 0x0d:
14281 idx1 = 0;
14282 idx = 1; /* Mic In */
14283 break;
14284 case 0x10:
14285 idx1 = 3;
14286 idx = 1; /* Mic In */
14287 break;
14288 case 0x11:
14289 idx1 = 4;
14290 idx = 0; /* CD */
14291 break;
14292 default:
14293 continue;
14296 err = new_analog_input(spec, cfg->input_pins[i],
14297 auto_pin_cfg_labels[i], idx, 0x15);
14298 if (err < 0)
14299 return err;
14301 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
14302 imux->items[imux->num_items].index = idx1;
14303 imux->num_items++;
14305 return 0;
14308 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14309 hda_nid_t nid,
14310 int pin_type, int dac_idx)
14312 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14313 pin_type);
14314 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14315 AMP_OUT_UNMUTE);
14318 static void alc861_auto_init_multi_out(struct hda_codec *codec)
14320 struct alc_spec *spec = codec->spec;
14321 int i;
14323 for (i = 0; i < spec->autocfg.line_outs; i++) {
14324 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14325 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14326 if (nid)
14327 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
14328 spec->multiout.dac_nids[i]);
14332 static void alc861_auto_init_hp_out(struct hda_codec *codec)
14334 struct alc_spec *spec = codec->spec;
14335 hda_nid_t pin;
14337 pin = spec->autocfg.hp_pins[0];
14338 if (pin) /* connect to front */
14339 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
14340 spec->multiout.dac_nids[0]);
14341 pin = spec->autocfg.speaker_pins[0];
14342 if (pin)
14343 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14346 static void alc861_auto_init_analog_input(struct hda_codec *codec)
14348 struct alc_spec *spec = codec->spec;
14349 int i;
14351 for (i = 0; i < AUTO_PIN_LAST; i++) {
14352 hda_nid_t nid = spec->autocfg.input_pins[i];
14353 if (nid >= 0x0c && nid <= 0x11)
14354 alc_set_input_pin(codec, nid, i);
14358 /* parse the BIOS configuration and set up the alc_spec */
14359 /* return 1 if successful, 0 if the proper config is not found,
14360 * or a negative error code
14362 static int alc861_parse_auto_config(struct hda_codec *codec)
14364 struct alc_spec *spec = codec->spec;
14365 int err;
14366 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
14368 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14369 alc861_ignore);
14370 if (err < 0)
14371 return err;
14372 if (!spec->autocfg.line_outs)
14373 return 0; /* can't find valid BIOS pin config */
14375 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
14376 if (err < 0)
14377 return err;
14378 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
14379 if (err < 0)
14380 return err;
14381 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
14382 if (err < 0)
14383 return err;
14384 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
14385 if (err < 0)
14386 return err;
14388 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14390 if (spec->autocfg.dig_outs)
14391 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
14393 if (spec->kctls.list)
14394 add_mixer(spec, spec->kctls.list);
14396 add_verb(spec, alc861_auto_init_verbs);
14398 spec->num_mux_defs = 1;
14399 spec->input_mux = &spec->private_imux[0];
14401 spec->adc_nids = alc861_adc_nids;
14402 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14403 set_capture_mixer(spec);
14405 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14407 return 1;
14410 /* additional initialization for auto-configuration model */
14411 static void alc861_auto_init(struct hda_codec *codec)
14413 struct alc_spec *spec = codec->spec;
14414 alc861_auto_init_multi_out(codec);
14415 alc861_auto_init_hp_out(codec);
14416 alc861_auto_init_analog_input(codec);
14417 if (spec->unsol_event)
14418 alc_inithook(codec);
14421 #ifdef CONFIG_SND_HDA_POWER_SAVE
14422 static struct hda_amp_list alc861_loopbacks[] = {
14423 { 0x15, HDA_INPUT, 0 },
14424 { 0x15, HDA_INPUT, 1 },
14425 { 0x15, HDA_INPUT, 2 },
14426 { 0x15, HDA_INPUT, 3 },
14427 { } /* end */
14429 #endif
14433 * configuration and preset
14435 static const char *alc861_models[ALC861_MODEL_LAST] = {
14436 [ALC861_3ST] = "3stack",
14437 [ALC660_3ST] = "3stack-660",
14438 [ALC861_3ST_DIG] = "3stack-dig",
14439 [ALC861_6ST_DIG] = "6stack-dig",
14440 [ALC861_UNIWILL_M31] = "uniwill-m31",
14441 [ALC861_TOSHIBA] = "toshiba",
14442 [ALC861_ASUS] = "asus",
14443 [ALC861_ASUS_LAPTOP] = "asus-laptop",
14444 [ALC861_AUTO] = "auto",
14447 static struct snd_pci_quirk alc861_cfg_tbl[] = {
14448 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
14449 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14450 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
14451 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
14452 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
14453 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
14454 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
14455 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
14456 * Any other models that need this preset?
14458 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
14459 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
14460 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
14461 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
14462 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
14463 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
14464 /* FIXME: the below seems conflict */
14465 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
14466 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
14467 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
14471 static struct alc_config_preset alc861_presets[] = {
14472 [ALC861_3ST] = {
14473 .mixers = { alc861_3ST_mixer },
14474 .init_verbs = { alc861_threestack_init_verbs },
14475 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14476 .dac_nids = alc861_dac_nids,
14477 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14478 .channel_mode = alc861_threestack_modes,
14479 .need_dac_fix = 1,
14480 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14481 .adc_nids = alc861_adc_nids,
14482 .input_mux = &alc861_capture_source,
14484 [ALC861_3ST_DIG] = {
14485 .mixers = { alc861_base_mixer },
14486 .init_verbs = { alc861_threestack_init_verbs },
14487 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14488 .dac_nids = alc861_dac_nids,
14489 .dig_out_nid = ALC861_DIGOUT_NID,
14490 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14491 .channel_mode = alc861_threestack_modes,
14492 .need_dac_fix = 1,
14493 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14494 .adc_nids = alc861_adc_nids,
14495 .input_mux = &alc861_capture_source,
14497 [ALC861_6ST_DIG] = {
14498 .mixers = { alc861_base_mixer },
14499 .init_verbs = { alc861_base_init_verbs },
14500 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14501 .dac_nids = alc861_dac_nids,
14502 .dig_out_nid = ALC861_DIGOUT_NID,
14503 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
14504 .channel_mode = alc861_8ch_modes,
14505 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14506 .adc_nids = alc861_adc_nids,
14507 .input_mux = &alc861_capture_source,
14509 [ALC660_3ST] = {
14510 .mixers = { alc861_3ST_mixer },
14511 .init_verbs = { alc861_threestack_init_verbs },
14512 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
14513 .dac_nids = alc660_dac_nids,
14514 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
14515 .channel_mode = alc861_threestack_modes,
14516 .need_dac_fix = 1,
14517 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14518 .adc_nids = alc861_adc_nids,
14519 .input_mux = &alc861_capture_source,
14521 [ALC861_UNIWILL_M31] = {
14522 .mixers = { alc861_uniwill_m31_mixer },
14523 .init_verbs = { alc861_uniwill_m31_init_verbs },
14524 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14525 .dac_nids = alc861_dac_nids,
14526 .dig_out_nid = ALC861_DIGOUT_NID,
14527 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
14528 .channel_mode = alc861_uniwill_m31_modes,
14529 .need_dac_fix = 1,
14530 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14531 .adc_nids = alc861_adc_nids,
14532 .input_mux = &alc861_capture_source,
14534 [ALC861_TOSHIBA] = {
14535 .mixers = { alc861_toshiba_mixer },
14536 .init_verbs = { alc861_base_init_verbs,
14537 alc861_toshiba_init_verbs },
14538 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14539 .dac_nids = alc861_dac_nids,
14540 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14541 .channel_mode = alc883_3ST_2ch_modes,
14542 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14543 .adc_nids = alc861_adc_nids,
14544 .input_mux = &alc861_capture_source,
14545 .unsol_event = alc861_toshiba_unsol_event,
14546 .init_hook = alc861_toshiba_automute,
14548 [ALC861_ASUS] = {
14549 .mixers = { alc861_asus_mixer },
14550 .init_verbs = { alc861_asus_init_verbs },
14551 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14552 .dac_nids = alc861_dac_nids,
14553 .dig_out_nid = ALC861_DIGOUT_NID,
14554 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
14555 .channel_mode = alc861_asus_modes,
14556 .need_dac_fix = 1,
14557 .hp_nid = 0x06,
14558 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14559 .adc_nids = alc861_adc_nids,
14560 .input_mux = &alc861_capture_source,
14562 [ALC861_ASUS_LAPTOP] = {
14563 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
14564 .init_verbs = { alc861_asus_init_verbs,
14565 alc861_asus_laptop_init_verbs },
14566 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
14567 .dac_nids = alc861_dac_nids,
14568 .dig_out_nid = ALC861_DIGOUT_NID,
14569 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
14570 .channel_mode = alc883_3ST_2ch_modes,
14571 .need_dac_fix = 1,
14572 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
14573 .adc_nids = alc861_adc_nids,
14574 .input_mux = &alc861_capture_source,
14579 static int patch_alc861(struct hda_codec *codec)
14581 struct alc_spec *spec;
14582 int board_config;
14583 int err;
14585 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14586 if (spec == NULL)
14587 return -ENOMEM;
14589 codec->spec = spec;
14591 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
14592 alc861_models,
14593 alc861_cfg_tbl);
14595 if (board_config < 0) {
14596 printk(KERN_INFO "hda_codec: Unknown model for %s, "
14597 "trying auto-probe from BIOS...\n", codec->chip_name);
14598 board_config = ALC861_AUTO;
14601 if (board_config == ALC861_AUTO) {
14602 /* automatic parse from the BIOS config */
14603 err = alc861_parse_auto_config(codec);
14604 if (err < 0) {
14605 alc_free(codec);
14606 return err;
14607 } else if (!err) {
14608 printk(KERN_INFO
14609 "hda_codec: Cannot set up configuration "
14610 "from BIOS. Using base mode...\n");
14611 board_config = ALC861_3ST_DIG;
14615 err = snd_hda_attach_beep_device(codec, 0x23);
14616 if (err < 0) {
14617 alc_free(codec);
14618 return err;
14621 if (board_config != ALC861_AUTO)
14622 setup_preset(spec, &alc861_presets[board_config]);
14624 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14625 spec->stream_analog_capture = &alc861_pcm_analog_capture;
14627 spec->stream_digital_playback = &alc861_pcm_digital_playback;
14628 spec->stream_digital_capture = &alc861_pcm_digital_capture;
14630 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
14632 spec->vmaster_nid = 0x03;
14634 codec->patch_ops = alc_patch_ops;
14635 if (board_config == ALC861_AUTO)
14636 spec->init_hook = alc861_auto_init;
14637 #ifdef CONFIG_SND_HDA_POWER_SAVE
14638 if (!spec->loopback.amplist)
14639 spec->loopback.amplist = alc861_loopbacks;
14640 #endif
14641 codec->proc_widget_hook = print_realtek_coef;
14643 return 0;
14647 * ALC861-VD support
14649 * Based on ALC882
14651 * In addition, an independent DAC
14653 #define ALC861VD_DIGOUT_NID 0x06
14655 static hda_nid_t alc861vd_dac_nids[4] = {
14656 /* front, surr, clfe, side surr */
14657 0x02, 0x03, 0x04, 0x05
14660 /* dac_nids for ALC660vd are in a different order - according to
14661 * Realtek's driver.
14662 * This should probably result in a different mixer for 6stack models
14663 * of ALC660vd codecs, but for now there is only 3stack mixer
14664 * - and it is the same as in 861vd.
14665 * adc_nids in ALC660vd are (is) the same as in 861vd
14667 static hda_nid_t alc660vd_dac_nids[3] = {
14668 /* front, rear, clfe, rear_surr */
14669 0x02, 0x04, 0x03
14672 static hda_nid_t alc861vd_adc_nids[1] = {
14673 /* ADC0 */
14674 0x09,
14677 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
14679 /* input MUX */
14680 /* FIXME: should be a matrix-type input source selection */
14681 static struct hda_input_mux alc861vd_capture_source = {
14682 .num_items = 4,
14683 .items = {
14684 { "Mic", 0x0 },
14685 { "Front Mic", 0x1 },
14686 { "Line", 0x2 },
14687 { "CD", 0x4 },
14691 static struct hda_input_mux alc861vd_dallas_capture_source = {
14692 .num_items = 2,
14693 .items = {
14694 { "Ext Mic", 0x0 },
14695 { "Int Mic", 0x1 },
14699 static struct hda_input_mux alc861vd_hp_capture_source = {
14700 .num_items = 2,
14701 .items = {
14702 { "Front Mic", 0x0 },
14703 { "ATAPI Mic", 0x1 },
14708 * 2ch mode
14710 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
14711 { 2, NULL }
14715 * 6ch mode
14717 static struct hda_verb alc861vd_6stack_ch6_init[] = {
14718 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14719 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14720 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14721 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14722 { } /* end */
14726 * 8ch mode
14728 static struct hda_verb alc861vd_6stack_ch8_init[] = {
14729 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14730 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14731 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14732 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14733 { } /* end */
14736 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
14737 { 6, alc861vd_6stack_ch6_init },
14738 { 8, alc861vd_6stack_ch8_init },
14741 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
14743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14744 .name = "Channel Mode",
14745 .info = alc_ch_mode_info,
14746 .get = alc_ch_mode_get,
14747 .put = alc_ch_mode_put,
14749 { } /* end */
14752 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14753 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14755 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
14756 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14757 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14759 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14760 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
14762 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
14763 HDA_OUTPUT),
14764 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
14765 HDA_OUTPUT),
14766 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
14767 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
14769 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
14770 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
14772 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14774 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14775 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14776 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14778 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14779 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14780 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14782 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14783 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14785 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14786 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14788 { } /* end */
14791 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
14792 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14793 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14797 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14798 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14799 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14801 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14802 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14803 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14805 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14806 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14808 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14809 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14811 { } /* end */
14814 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
14815 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14816 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
14817 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14819 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14821 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
14822 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14823 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14825 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
14826 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14827 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14832 { } /* end */
14835 /* Pin assignment: Speaker=0x14, HP = 0x15,
14836 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
14838 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
14839 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14840 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
14841 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14842 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14843 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
14844 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14845 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14846 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
14847 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14848 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14849 { } /* end */
14852 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
14853 * Front Mic=0x18, ATAPI Mic = 0x19,
14855 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
14856 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14857 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
14858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14859 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
14860 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14861 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14862 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14863 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14865 { } /* end */
14869 * generic initialization of ADC, input mixers and output mixers
14871 static struct hda_verb alc861vd_volume_init_verbs[] = {
14873 * Unmute ADC0 and set the default input to mic-in
14875 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14878 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
14879 * the analog-loopback mixer widget
14881 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
14882 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14886 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14888 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
14889 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14890 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14891 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14892 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
14895 * Set up output mixers (0x02 - 0x05)
14897 /* set vol=0 to output mixers */
14898 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14899 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14900 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14901 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14903 /* set up input amps for analog loopback */
14904 /* Amp Indices: DAC = 0, mixer = 1 */
14905 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14906 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14909 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14911 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14912 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14918 * 3-stack pin configuration:
14919 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
14921 static struct hda_verb alc861vd_3stack_init_verbs[] = {
14923 * Set pin mode and muting
14925 /* set front pin widgets 0x14 for output */
14926 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14927 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14928 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14930 /* Mic (rear) pin: input vref at 80% */
14931 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14932 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14933 /* Front Mic pin: input vref at 80% */
14934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14936 /* Line In pin: input */
14937 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14938 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14939 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14941 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14942 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14943 /* CD pin widget for input */
14944 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14950 * 6-stack pin configuration:
14952 static struct hda_verb alc861vd_6stack_init_verbs[] = {
14954 * Set pin mode and muting
14956 /* set front pin widgets 0x14 for output */
14957 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14958 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14959 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
14961 /* Rear Pin: output 1 (0x0d) */
14962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14963 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14964 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14965 /* CLFE Pin: output 2 (0x0e) */
14966 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14967 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
14969 /* Side Pin: output 3 (0x0f) */
14970 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14971 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14972 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
14974 /* Mic (rear) pin: input vref at 80% */
14975 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14976 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14977 /* Front Mic pin: input vref at 80% */
14978 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14979 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14980 /* Line In pin: input */
14981 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14982 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14983 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14984 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14985 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14986 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14987 /* CD pin widget for input */
14988 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14993 static struct hda_verb alc861vd_eapd_verbs[] = {
14994 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14998 static struct hda_verb alc660vd_eapd_verbs[] = {
14999 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15000 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15004 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15005 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15006 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15007 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15008 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15013 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15015 unsigned int present;
15016 unsigned char bits;
15018 present = snd_hda_codec_read(codec, 0x18, 0,
15019 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15020 bits = present ? HDA_AMP_MUTE : 0;
15021 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15022 HDA_AMP_MUTE, bits);
15025 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15027 struct alc_spec *spec = codec->spec;
15029 spec->autocfg.hp_pins[0] = 0x1b;
15030 spec->autocfg.speaker_pins[0] = 0x14;
15031 alc_automute_amp(codec);
15032 alc861vd_lenovo_mic_automute(codec);
15035 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15036 unsigned int res)
15038 switch (res >> 26) {
15039 case ALC880_MIC_EVENT:
15040 alc861vd_lenovo_mic_automute(codec);
15041 break;
15042 default:
15043 alc_automute_amp_unsol_event(codec, res);
15044 break;
15048 static struct hda_verb alc861vd_dallas_verbs[] = {
15049 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15054 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15057 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15058 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15059 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15060 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15061 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15064 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15065 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15067 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15069 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15072 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15074 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15076 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15077 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15078 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15079 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15081 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15082 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15083 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15084 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15086 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15088 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15090 { } /* end */
15093 /* toggle speaker-output according to the hp-jack state */
15094 static void alc861vd_dallas_init_hook(struct hda_codec *codec)
15096 struct alc_spec *spec = codec->spec;
15098 spec->autocfg.hp_pins[0] = 0x15;
15099 spec->autocfg.speaker_pins[0] = 0x14;
15100 alc_automute_amp(codec);
15103 #ifdef CONFIG_SND_HDA_POWER_SAVE
15104 #define alc861vd_loopbacks alc880_loopbacks
15105 #endif
15107 /* pcm configuration: identical with ALC880 */
15108 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15109 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15110 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15111 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15114 * configuration and preset
15116 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15117 [ALC660VD_3ST] = "3stack-660",
15118 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15119 [ALC660VD_ASUS_V1S] = "asus-v1s",
15120 [ALC861VD_3ST] = "3stack",
15121 [ALC861VD_3ST_DIG] = "3stack-digout",
15122 [ALC861VD_6ST_DIG] = "6stack-digout",
15123 [ALC861VD_LENOVO] = "lenovo",
15124 [ALC861VD_DALLAS] = "dallas",
15125 [ALC861VD_HP] = "hp",
15126 [ALC861VD_AUTO] = "auto",
15129 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
15130 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
15131 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
15132 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
15133 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
15134 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
15135 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
15136 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
15137 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
15138 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
15139 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
15140 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
15141 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
15142 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
15143 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
15144 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
15148 static struct alc_config_preset alc861vd_presets[] = {
15149 [ALC660VD_3ST] = {
15150 .mixers = { alc861vd_3st_mixer },
15151 .init_verbs = { alc861vd_volume_init_verbs,
15152 alc861vd_3stack_init_verbs },
15153 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15154 .dac_nids = alc660vd_dac_nids,
15155 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15156 .channel_mode = alc861vd_3stack_2ch_modes,
15157 .input_mux = &alc861vd_capture_source,
15159 [ALC660VD_3ST_DIG] = {
15160 .mixers = { alc861vd_3st_mixer },
15161 .init_verbs = { alc861vd_volume_init_verbs,
15162 alc861vd_3stack_init_verbs },
15163 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15164 .dac_nids = alc660vd_dac_nids,
15165 .dig_out_nid = ALC861VD_DIGOUT_NID,
15166 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15167 .channel_mode = alc861vd_3stack_2ch_modes,
15168 .input_mux = &alc861vd_capture_source,
15170 [ALC861VD_3ST] = {
15171 .mixers = { alc861vd_3st_mixer },
15172 .init_verbs = { alc861vd_volume_init_verbs,
15173 alc861vd_3stack_init_verbs },
15174 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15175 .dac_nids = alc861vd_dac_nids,
15176 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15177 .channel_mode = alc861vd_3stack_2ch_modes,
15178 .input_mux = &alc861vd_capture_source,
15180 [ALC861VD_3ST_DIG] = {
15181 .mixers = { alc861vd_3st_mixer },
15182 .init_verbs = { alc861vd_volume_init_verbs,
15183 alc861vd_3stack_init_verbs },
15184 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15185 .dac_nids = alc861vd_dac_nids,
15186 .dig_out_nid = ALC861VD_DIGOUT_NID,
15187 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15188 .channel_mode = alc861vd_3stack_2ch_modes,
15189 .input_mux = &alc861vd_capture_source,
15191 [ALC861VD_6ST_DIG] = {
15192 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
15193 .init_verbs = { alc861vd_volume_init_verbs,
15194 alc861vd_6stack_init_verbs },
15195 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15196 .dac_nids = alc861vd_dac_nids,
15197 .dig_out_nid = ALC861VD_DIGOUT_NID,
15198 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
15199 .channel_mode = alc861vd_6stack_modes,
15200 .input_mux = &alc861vd_capture_source,
15202 [ALC861VD_LENOVO] = {
15203 .mixers = { alc861vd_lenovo_mixer },
15204 .init_verbs = { alc861vd_volume_init_verbs,
15205 alc861vd_3stack_init_verbs,
15206 alc861vd_eapd_verbs,
15207 alc861vd_lenovo_unsol_verbs },
15208 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15209 .dac_nids = alc660vd_dac_nids,
15210 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15211 .channel_mode = alc861vd_3stack_2ch_modes,
15212 .input_mux = &alc861vd_capture_source,
15213 .unsol_event = alc861vd_lenovo_unsol_event,
15214 .init_hook = alc861vd_lenovo_init_hook,
15216 [ALC861VD_DALLAS] = {
15217 .mixers = { alc861vd_dallas_mixer },
15218 .init_verbs = { alc861vd_dallas_verbs },
15219 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15220 .dac_nids = alc861vd_dac_nids,
15221 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15222 .channel_mode = alc861vd_3stack_2ch_modes,
15223 .input_mux = &alc861vd_dallas_capture_source,
15224 .unsol_event = alc_automute_amp_unsol_event,
15225 .init_hook = alc861vd_dallas_init_hook,
15227 [ALC861VD_HP] = {
15228 .mixers = { alc861vd_hp_mixer },
15229 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
15230 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
15231 .dac_nids = alc861vd_dac_nids,
15232 .dig_out_nid = ALC861VD_DIGOUT_NID,
15233 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15234 .channel_mode = alc861vd_3stack_2ch_modes,
15235 .input_mux = &alc861vd_hp_capture_source,
15236 .unsol_event = alc_automute_amp_unsol_event,
15237 .init_hook = alc861vd_dallas_init_hook,
15239 [ALC660VD_ASUS_V1S] = {
15240 .mixers = { alc861vd_lenovo_mixer },
15241 .init_verbs = { alc861vd_volume_init_verbs,
15242 alc861vd_3stack_init_verbs,
15243 alc861vd_eapd_verbs,
15244 alc861vd_lenovo_unsol_verbs },
15245 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
15246 .dac_nids = alc660vd_dac_nids,
15247 .dig_out_nid = ALC861VD_DIGOUT_NID,
15248 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
15249 .channel_mode = alc861vd_3stack_2ch_modes,
15250 .input_mux = &alc861vd_capture_source,
15251 .unsol_event = alc861vd_lenovo_unsol_event,
15252 .init_hook = alc861vd_lenovo_init_hook,
15257 * BIOS auto configuration
15259 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15260 hda_nid_t nid, int pin_type, int dac_idx)
15262 alc_set_pin_output(codec, nid, pin_type);
15265 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
15267 struct alc_spec *spec = codec->spec;
15268 int i;
15270 for (i = 0; i <= HDA_SIDE; i++) {
15271 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15272 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15273 if (nid)
15274 alc861vd_auto_set_output_and_unmute(codec, nid,
15275 pin_type, i);
15280 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15282 struct alc_spec *spec = codec->spec;
15283 hda_nid_t pin;
15285 pin = spec->autocfg.hp_pins[0];
15286 if (pin) /* connect to front and use dac 0 */
15287 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
15288 pin = spec->autocfg.speaker_pins[0];
15289 if (pin)
15290 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15293 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
15294 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15296 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15298 struct alc_spec *spec = codec->spec;
15299 int i;
15301 for (i = 0; i < AUTO_PIN_LAST; i++) {
15302 hda_nid_t nid = spec->autocfg.input_pins[i];
15303 if (alc861vd_is_input_pin(nid)) {
15304 alc_set_input_pin(codec, nid, i);
15305 if (nid != ALC861VD_PIN_CD_NID &&
15306 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
15307 snd_hda_codec_write(codec, nid, 0,
15308 AC_VERB_SET_AMP_GAIN_MUTE,
15309 AMP_OUT_MUTE);
15314 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
15316 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
15317 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
15319 /* add playback controls from the parsed DAC table */
15320 /* Based on ALC880 version. But ALC861VD has separate,
15321 * different NIDs for mute/unmute switch and volume control */
15322 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15323 const struct auto_pin_cfg *cfg)
15325 char name[32];
15326 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
15327 hda_nid_t nid_v, nid_s;
15328 int i, err;
15330 for (i = 0; i < cfg->line_outs; i++) {
15331 if (!spec->multiout.dac_nids[i])
15332 continue;
15333 nid_v = alc861vd_idx_to_mixer_vol(
15334 alc880_dac_to_idx(
15335 spec->multiout.dac_nids[i]));
15336 nid_s = alc861vd_idx_to_mixer_switch(
15337 alc880_dac_to_idx(
15338 spec->multiout.dac_nids[i]));
15340 if (i == 2) {
15341 /* Center/LFE */
15342 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15343 "Center Playback Volume",
15344 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
15345 HDA_OUTPUT));
15346 if (err < 0)
15347 return err;
15348 err = add_control(spec, ALC_CTL_WIDGET_VOL,
15349 "LFE Playback Volume",
15350 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
15351 HDA_OUTPUT));
15352 if (err < 0)
15353 return err;
15354 err = add_control(spec, ALC_CTL_BIND_MUTE,
15355 "Center Playback Switch",
15356 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
15357 HDA_INPUT));
15358 if (err < 0)
15359 return err;
15360 err = add_control(spec, ALC_CTL_BIND_MUTE,
15361 "LFE Playback Switch",
15362 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
15363 HDA_INPUT));
15364 if (err < 0)
15365 return err;
15366 } else {
15367 sprintf(name, "%s Playback Volume", chname[i]);
15368 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15369 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15370 HDA_OUTPUT));
15371 if (err < 0)
15372 return err;
15373 sprintf(name, "%s Playback Switch", chname[i]);
15374 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15375 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15376 HDA_INPUT));
15377 if (err < 0)
15378 return err;
15381 return 0;
15384 /* add playback controls for speaker and HP outputs */
15385 /* Based on ALC880 version. But ALC861VD has separate,
15386 * different NIDs for mute/unmute switch and volume control */
15387 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
15388 hda_nid_t pin, const char *pfx)
15390 hda_nid_t nid_v, nid_s;
15391 int err;
15392 char name[32];
15394 if (!pin)
15395 return 0;
15397 if (alc880_is_fixed_pin(pin)) {
15398 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
15399 /* specify the DAC as the extra output */
15400 if (!spec->multiout.hp_nid)
15401 spec->multiout.hp_nid = nid_v;
15402 else
15403 spec->multiout.extra_out_nid[0] = nid_v;
15404 /* control HP volume/switch on the output mixer amp */
15405 nid_v = alc861vd_idx_to_mixer_vol(
15406 alc880_fixed_pin_idx(pin));
15407 nid_s = alc861vd_idx_to_mixer_switch(
15408 alc880_fixed_pin_idx(pin));
15410 sprintf(name, "%s Playback Volume", pfx);
15411 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15412 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
15413 if (err < 0)
15414 return err;
15415 sprintf(name, "%s Playback Switch", pfx);
15416 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15417 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
15418 if (err < 0)
15419 return err;
15420 } else if (alc880_is_multi_pin(pin)) {
15421 /* set manual connection */
15422 /* we have only a switch on HP-out PIN */
15423 sprintf(name, "%s Playback Switch", pfx);
15424 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
15425 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
15426 if (err < 0)
15427 return err;
15429 return 0;
15432 /* parse the BIOS configuration and set up the alc_spec
15433 * return 1 if successful, 0 if the proper config is not found,
15434 * or a negative error code
15435 * Based on ALC880 version - had to change it to override
15436 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
15437 static int alc861vd_parse_auto_config(struct hda_codec *codec)
15439 struct alc_spec *spec = codec->spec;
15440 int err;
15441 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
15443 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15444 alc861vd_ignore);
15445 if (err < 0)
15446 return err;
15447 if (!spec->autocfg.line_outs)
15448 return 0; /* can't find valid BIOS pin config */
15450 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
15451 if (err < 0)
15452 return err;
15453 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
15454 if (err < 0)
15455 return err;
15456 err = alc861vd_auto_create_extra_out(spec,
15457 spec->autocfg.speaker_pins[0],
15458 "Speaker");
15459 if (err < 0)
15460 return err;
15461 err = alc861vd_auto_create_extra_out(spec,
15462 spec->autocfg.hp_pins[0],
15463 "Headphone");
15464 if (err < 0)
15465 return err;
15466 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
15467 if (err < 0)
15468 return err;
15470 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15472 if (spec->autocfg.dig_outs)
15473 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
15475 if (spec->kctls.list)
15476 add_mixer(spec, spec->kctls.list);
15478 add_verb(spec, alc861vd_volume_init_verbs);
15480 spec->num_mux_defs = 1;
15481 spec->input_mux = &spec->private_imux[0];
15483 err = alc_auto_add_mic_boost(codec);
15484 if (err < 0)
15485 return err;
15487 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15489 return 1;
15492 /* additional initialization for auto-configuration model */
15493 static void alc861vd_auto_init(struct hda_codec *codec)
15495 struct alc_spec *spec = codec->spec;
15496 alc861vd_auto_init_multi_out(codec);
15497 alc861vd_auto_init_hp_out(codec);
15498 alc861vd_auto_init_analog_input(codec);
15499 alc861vd_auto_init_input_src(codec);
15500 if (spec->unsol_event)
15501 alc_inithook(codec);
15504 static int patch_alc861vd(struct hda_codec *codec)
15506 struct alc_spec *spec;
15507 int err, board_config;
15509 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15510 if (spec == NULL)
15511 return -ENOMEM;
15513 codec->spec = spec;
15515 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
15516 alc861vd_models,
15517 alc861vd_cfg_tbl);
15519 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15520 printk(KERN_INFO "hda_codec: Unknown model for %s, "
15521 "trying auto-probe from BIOS...\n", codec->chip_name);
15522 board_config = ALC861VD_AUTO;
15525 if (board_config == ALC861VD_AUTO) {
15526 /* automatic parse from the BIOS config */
15527 err = alc861vd_parse_auto_config(codec);
15528 if (err < 0) {
15529 alc_free(codec);
15530 return err;
15531 } else if (!err) {
15532 printk(KERN_INFO
15533 "hda_codec: Cannot set up configuration "
15534 "from BIOS. Using base mode...\n");
15535 board_config = ALC861VD_3ST;
15539 err = snd_hda_attach_beep_device(codec, 0x23);
15540 if (err < 0) {
15541 alc_free(codec);
15542 return err;
15545 if (board_config != ALC861VD_AUTO)
15546 setup_preset(spec, &alc861vd_presets[board_config]);
15548 if (codec->vendor_id == 0x10ec0660) {
15549 /* always turn on EAPD */
15550 add_verb(spec, alc660vd_eapd_verbs);
15553 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
15554 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
15556 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
15557 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
15559 spec->adc_nids = alc861vd_adc_nids;
15560 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
15561 spec->capsrc_nids = alc861vd_capsrc_nids;
15563 set_capture_mixer(spec);
15564 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15566 spec->vmaster_nid = 0x02;
15568 codec->patch_ops = alc_patch_ops;
15570 if (board_config == ALC861VD_AUTO)
15571 spec->init_hook = alc861vd_auto_init;
15572 #ifdef CONFIG_SND_HDA_POWER_SAVE
15573 if (!spec->loopback.amplist)
15574 spec->loopback.amplist = alc861vd_loopbacks;
15575 #endif
15576 codec->proc_widget_hook = print_realtek_coef;
15578 return 0;
15582 * ALC662 support
15584 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
15585 * configuration. Each pin widget can choose any input DACs and a mixer.
15586 * Each ADC is connected from a mixer of all inputs. This makes possible
15587 * 6-channel independent captures.
15589 * In addition, an independent DAC for the multi-playback (not used in this
15590 * driver yet).
15592 #define ALC662_DIGOUT_NID 0x06
15593 #define ALC662_DIGIN_NID 0x0a
15595 static hda_nid_t alc662_dac_nids[4] = {
15596 /* front, rear, clfe, rear_surr */
15597 0x02, 0x03, 0x04
15600 static hda_nid_t alc272_dac_nids[2] = {
15601 0x02, 0x03
15604 static hda_nid_t alc662_adc_nids[1] = {
15605 /* ADC1-2 */
15606 0x09,
15609 static hda_nid_t alc272_adc_nids[1] = {
15610 /* ADC1-2 */
15611 0x08,
15614 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
15615 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15618 /* input MUX */
15619 /* FIXME: should be a matrix-type input source selection */
15620 static struct hda_input_mux alc662_capture_source = {
15621 .num_items = 4,
15622 .items = {
15623 { "Mic", 0x0 },
15624 { "Front Mic", 0x1 },
15625 { "Line", 0x2 },
15626 { "CD", 0x4 },
15630 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15631 .num_items = 2,
15632 .items = {
15633 { "Mic", 0x1 },
15634 { "Line", 0x2 },
15638 static struct hda_input_mux alc662_eeepc_capture_source = {
15639 .num_items = 2,
15640 .items = {
15641 { "i-Mic", 0x1 },
15642 { "e-Mic", 0x0 },
15646 static struct hda_input_mux alc663_capture_source = {
15647 .num_items = 3,
15648 .items = {
15649 { "Mic", 0x0 },
15650 { "Front Mic", 0x1 },
15651 { "Line", 0x2 },
15655 static struct hda_input_mux alc663_m51va_capture_source = {
15656 .num_items = 2,
15657 .items = {
15658 { "Ext-Mic", 0x0 },
15659 { "D-Mic", 0x9 },
15663 #if 1 /* set to 0 for testing other input sources below */
15664 static struct hda_input_mux alc272_nc10_capture_source = {
15665 .num_items = 2,
15666 .items = {
15667 { "Autoselect Mic", 0x0 },
15668 { "Internal Mic", 0x1 },
15671 #else
15672 static struct hda_input_mux alc272_nc10_capture_source = {
15673 .num_items = 16,
15674 .items = {
15675 { "Autoselect Mic", 0x0 },
15676 { "Internal Mic", 0x1 },
15677 { "In-0x02", 0x2 },
15678 { "In-0x03", 0x3 },
15679 { "In-0x04", 0x4 },
15680 { "In-0x05", 0x5 },
15681 { "In-0x06", 0x6 },
15682 { "In-0x07", 0x7 },
15683 { "In-0x08", 0x8 },
15684 { "In-0x09", 0x9 },
15685 { "In-0x0a", 0x0a },
15686 { "In-0x0b", 0x0b },
15687 { "In-0x0c", 0x0c },
15688 { "In-0x0d", 0x0d },
15689 { "In-0x0e", 0x0e },
15690 { "In-0x0f", 0x0f },
15693 #endif
15696 * 2ch mode
15698 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
15699 { 2, NULL }
15703 * 2ch mode
15705 static struct hda_verb alc662_3ST_ch2_init[] = {
15706 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
15707 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
15709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
15710 { } /* end */
15714 * 6ch mode
15716 static struct hda_verb alc662_3ST_ch6_init[] = {
15717 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15718 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15719 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
15720 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15721 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
15722 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
15723 { } /* end */
15726 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
15727 { 2, alc662_3ST_ch2_init },
15728 { 6, alc662_3ST_ch6_init },
15732 * 2ch mode
15734 static struct hda_verb alc662_sixstack_ch6_init[] = {
15735 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15736 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15737 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15738 { } /* end */
15742 * 6ch mode
15744 static struct hda_verb alc662_sixstack_ch8_init[] = {
15745 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15746 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15747 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15748 { } /* end */
15751 static struct hda_channel_mode alc662_5stack_modes[2] = {
15752 { 2, alc662_sixstack_ch6_init },
15753 { 6, alc662_sixstack_ch8_init },
15756 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15757 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15760 static struct snd_kcontrol_new alc662_base_mixer[] = {
15761 /* output mixer control */
15762 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
15763 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15764 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
15765 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15766 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15767 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15768 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15769 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15770 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15772 /*Input mixer control */
15773 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
15774 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
15775 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
15776 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
15777 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
15778 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
15779 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
15780 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
15781 { } /* end */
15784 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
15785 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15786 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15787 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15788 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15789 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15790 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15791 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15794 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15795 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15796 { } /* end */
15799 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
15800 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15801 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
15802 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15803 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
15804 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15805 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15806 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
15807 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
15808 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15809 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15810 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15811 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15812 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15815 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15816 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15817 { } /* end */
15820 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
15821 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15822 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
15823 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15824 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
15825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15828 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15829 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15830 { } /* end */
15833 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
15834 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15835 ALC262_HIPPO_MASTER_SWITCH,
15837 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
15838 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15839 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15841 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15842 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15843 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15844 { } /* end */
15847 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
15848 ALC262_HIPPO_MASTER_SWITCH,
15849 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15850 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15851 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
15852 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
15853 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
15854 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15855 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15858 { } /* end */
15861 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
15862 .ops = &snd_hda_bind_vol,
15863 .values = {
15864 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15865 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
15870 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
15871 .ops = &snd_hda_bind_sw,
15872 .values = {
15873 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15874 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15879 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
15880 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15881 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
15882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15883 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15884 { } /* end */
15887 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
15888 .ops = &snd_hda_bind_sw,
15889 .values = {
15890 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15891 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15892 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
15897 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
15898 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15899 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
15900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15901 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15902 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15903 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15905 { } /* end */
15908 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
15909 .ops = &snd_hda_bind_sw,
15910 .values = {
15911 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15912 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
15913 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15918 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
15919 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15920 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
15921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15923 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15924 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15925 { } /* end */
15928 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
15929 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15930 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15931 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15933 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15934 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15935 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15936 { } /* end */
15939 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
15940 .ops = &snd_hda_bind_vol,
15941 .values = {
15942 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
15943 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
15948 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
15949 .ops = &snd_hda_bind_sw,
15950 .values = {
15951 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
15952 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
15957 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
15958 HDA_BIND_VOL("Master Playback Volume",
15959 &alc663_asus_two_bind_master_vol),
15960 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15962 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15963 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15965 { } /* end */
15968 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
15969 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
15970 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
15971 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15972 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15974 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15975 { } /* end */
15978 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
15979 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15980 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15981 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15982 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15983 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15987 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15988 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15989 { } /* end */
15992 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
15993 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15994 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15995 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
15997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15999 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16000 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16001 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16002 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16003 { } /* end */
16006 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16008 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16009 .name = "Channel Mode",
16010 .info = alc_ch_mode_info,
16011 .get = alc_ch_mode_get,
16012 .put = alc_ch_mode_put,
16014 { } /* end */
16017 static struct hda_verb alc662_init_verbs[] = {
16018 /* ADC: mute amp left and right */
16019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16020 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16021 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16029 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16030 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16032 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16033 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16034 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16036 /* Front Pin: output 0 (0x0c) */
16037 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16038 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16040 /* Rear Pin: output 1 (0x0d) */
16041 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16042 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16044 /* CLFE Pin: output 2 (0x0e) */
16045 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16046 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16048 /* Mic (rear) pin: input vref at 80% */
16049 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16050 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16051 /* Front Mic pin: input vref at 80% */
16052 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16053 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16054 /* Line In pin: input */
16055 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16056 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16057 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16058 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16059 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16060 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16061 /* CD pin widget for input */
16062 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16064 /* FIXME: use matrix-type input source selection */
16065 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16066 /* Input mixer */
16067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16068 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16070 /* always trun on EAPD */
16071 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16072 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16077 static struct hda_verb alc662_sue_init_verbs[] = {
16078 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16079 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16083 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
16084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16085 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16089 /* Set Unsolicited Event*/
16090 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16091 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16092 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16097 * generic initialization of ADC, input mixers and output mixers
16099 static struct hda_verb alc662_auto_init_verbs[] = {
16101 * Unmute ADC and set the default input to mic-in
16103 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16104 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16106 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16107 * mixer widget
16108 * Note: PASD motherboards uses the Line In 2 as the input for front
16109 * panel mic (mic 2)
16111 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16112 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16113 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16114 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16119 * Set up output mixers (0x0c - 0x0f)
16121 /* set vol=0 to output mixers */
16122 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16123 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16124 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16126 /* set up input amps for analog loopback */
16127 /* Amp Indices: DAC = 0, mixer = 1 */
16128 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16129 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16130 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16131 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16132 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16133 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16136 /* FIXME: use matrix-type input source selection */
16137 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16138 /* Input mixer */
16139 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16140 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16144 /* additional verbs for ALC663 */
16145 static struct hda_verb alc663_auto_init_verbs[] = {
16146 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16147 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16151 static struct hda_verb alc663_m51va_init_verbs[] = {
16152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16153 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16154 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16155 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16156 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16158 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16159 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16160 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16164 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
16165 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16166 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16167 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16170 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16171 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16175 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
16176 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16177 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16178 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16179 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16181 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16182 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16187 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
16188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16190 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16191 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16192 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16193 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16194 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16198 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
16199 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16200 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16201 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16202 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16203 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16205 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
16206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16207 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16208 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16209 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16210 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16214 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
16215 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16216 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16217 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16218 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16219 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16220 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16222 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16223 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16224 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16225 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16226 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16230 static struct hda_verb alc663_g71v_init_verbs[] = {
16231 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16232 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
16233 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
16235 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16236 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16237 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16239 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16240 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
16241 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
16245 static struct hda_verb alc663_g50v_init_verbs[] = {
16246 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16247 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16248 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
16250 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16251 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16255 static struct hda_verb alc662_ecs_init_verbs[] = {
16256 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
16257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16258 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16259 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16263 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
16264 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16265 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16266 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16267 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16268 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16269 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16271 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16272 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16273 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16274 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16278 static struct hda_verb alc272_dell_init_verbs[] = {
16279 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16280 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16281 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16282 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16283 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16284 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16285 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
16286 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16287 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
16288 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16289 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16293 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
16294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
16295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
16296 { } /* end */
16299 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
16300 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
16301 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
16302 { } /* end */
16305 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
16307 unsigned int present;
16308 unsigned char bits;
16310 present = snd_hda_codec_read(codec, 0x14, 0,
16311 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16312 bits = present ? HDA_AMP_MUTE : 0;
16313 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16314 HDA_AMP_MUTE, bits);
16317 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
16319 unsigned int present;
16320 unsigned char bits;
16322 present = snd_hda_codec_read(codec, 0x1b, 0,
16323 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16324 bits = present ? HDA_AMP_MUTE : 0;
16325 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16326 HDA_AMP_MUTE, bits);
16327 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16328 HDA_AMP_MUTE, bits);
16331 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16332 unsigned int res)
16334 if ((res >> 26) == ALC880_HP_EVENT)
16335 alc662_lenovo_101e_all_automute(codec);
16336 if ((res >> 26) == ALC880_FRONT_EVENT)
16337 alc662_lenovo_101e_ispeaker_automute(codec);
16340 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
16342 unsigned int present;
16344 present = snd_hda_codec_read(codec, 0x18, 0,
16345 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16346 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16347 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16348 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16349 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16350 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16351 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16352 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16353 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16356 /* unsolicited event for HP jack sensing */
16357 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16358 unsigned int res)
16360 if ((res >> 26) == ALC880_MIC_EVENT)
16361 alc662_eeepc_mic_automute(codec);
16362 else
16363 alc262_hippo_unsol_event(codec, res);
16366 static void alc662_eeepc_inithook(struct hda_codec *codec)
16368 alc262_hippo1_init_hook(codec);
16369 alc662_eeepc_mic_automute(codec);
16372 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
16374 struct alc_spec *spec = codec->spec;
16376 spec->autocfg.hp_pins[0] = 0x14;
16377 spec->autocfg.speaker_pins[0] = 0x1b;
16378 alc262_hippo_master_update(codec);
16381 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16383 unsigned int present;
16384 unsigned char bits;
16386 present = snd_hda_codec_read(codec, 0x21, 0,
16387 AC_VERB_GET_PIN_SENSE, 0)
16388 & AC_PINSENSE_PRESENCE;
16389 bits = present ? HDA_AMP_MUTE : 0;
16390 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16391 AMP_IN_MUTE(0), bits);
16392 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16393 AMP_IN_MUTE(0), bits);
16396 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
16398 unsigned int present;
16399 unsigned char bits;
16401 present = snd_hda_codec_read(codec, 0x21, 0,
16402 AC_VERB_GET_PIN_SENSE, 0)
16403 & AC_PINSENSE_PRESENCE;
16404 bits = present ? HDA_AMP_MUTE : 0;
16405 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16406 AMP_IN_MUTE(0), bits);
16407 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16408 AMP_IN_MUTE(0), bits);
16409 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16410 AMP_IN_MUTE(0), bits);
16411 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16412 AMP_IN_MUTE(0), bits);
16415 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
16417 unsigned int present;
16418 unsigned char bits;
16420 present = snd_hda_codec_read(codec, 0x15, 0,
16421 AC_VERB_GET_PIN_SENSE, 0)
16422 & AC_PINSENSE_PRESENCE;
16423 bits = present ? HDA_AMP_MUTE : 0;
16424 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16425 AMP_IN_MUTE(0), bits);
16426 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16427 AMP_IN_MUTE(0), bits);
16428 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
16429 AMP_IN_MUTE(0), bits);
16430 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
16431 AMP_IN_MUTE(0), bits);
16434 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
16436 unsigned int present;
16437 unsigned char bits;
16439 present = snd_hda_codec_read(codec, 0x1b, 0,
16440 AC_VERB_GET_PIN_SENSE, 0)
16441 & AC_PINSENSE_PRESENCE;
16442 bits = present ? 0 : PIN_OUT;
16443 snd_hda_codec_write(codec, 0x14, 0,
16444 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
16447 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
16449 unsigned int present1, present2;
16451 present1 = snd_hda_codec_read(codec, 0x21, 0,
16452 AC_VERB_GET_PIN_SENSE, 0)
16453 & AC_PINSENSE_PRESENCE;
16454 present2 = snd_hda_codec_read(codec, 0x15, 0,
16455 AC_VERB_GET_PIN_SENSE, 0)
16456 & AC_PINSENSE_PRESENCE;
16458 if (present1 || present2) {
16459 snd_hda_codec_write_cache(codec, 0x14, 0,
16460 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
16461 } else {
16462 snd_hda_codec_write_cache(codec, 0x14, 0,
16463 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
16467 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16469 unsigned int present1, present2;
16471 present1 = snd_hda_codec_read(codec, 0x1b, 0,
16472 AC_VERB_GET_PIN_SENSE, 0)
16473 & AC_PINSENSE_PRESENCE;
16474 present2 = snd_hda_codec_read(codec, 0x15, 0,
16475 AC_VERB_GET_PIN_SENSE, 0)
16476 & AC_PINSENSE_PRESENCE;
16478 if (present1 || present2) {
16479 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16480 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16481 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16482 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
16483 } else {
16484 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
16485 AMP_IN_MUTE(0), 0);
16486 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
16487 AMP_IN_MUTE(0), 0);
16491 static void alc663_m51va_mic_automute(struct hda_codec *codec)
16493 unsigned int present;
16495 present = snd_hda_codec_read(codec, 0x18, 0,
16496 AC_VERB_GET_PIN_SENSE, 0)
16497 & AC_PINSENSE_PRESENCE;
16498 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16499 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16500 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16501 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16502 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16503 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16504 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16505 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16508 static void alc663_m51va_unsol_event(struct hda_codec *codec,
16509 unsigned int res)
16511 switch (res >> 26) {
16512 case ALC880_HP_EVENT:
16513 alc663_m51va_speaker_automute(codec);
16514 break;
16515 case ALC880_MIC_EVENT:
16516 alc663_m51va_mic_automute(codec);
16517 break;
16521 static void alc663_m51va_inithook(struct hda_codec *codec)
16523 alc663_m51va_speaker_automute(codec);
16524 alc663_m51va_mic_automute(codec);
16527 /* ***************** Mode1 ******************************/
16528 static void alc663_mode1_unsol_event(struct hda_codec *codec,
16529 unsigned int res)
16531 switch (res >> 26) {
16532 case ALC880_HP_EVENT:
16533 alc663_m51va_speaker_automute(codec);
16534 break;
16535 case ALC880_MIC_EVENT:
16536 alc662_eeepc_mic_automute(codec);
16537 break;
16541 static void alc663_mode1_inithook(struct hda_codec *codec)
16543 alc663_m51va_speaker_automute(codec);
16544 alc662_eeepc_mic_automute(codec);
16546 /* ***************** Mode2 ******************************/
16547 static void alc662_mode2_unsol_event(struct hda_codec *codec,
16548 unsigned int res)
16550 switch (res >> 26) {
16551 case ALC880_HP_EVENT:
16552 alc662_f5z_speaker_automute(codec);
16553 break;
16554 case ALC880_MIC_EVENT:
16555 alc662_eeepc_mic_automute(codec);
16556 break;
16560 static void alc662_mode2_inithook(struct hda_codec *codec)
16562 alc662_f5z_speaker_automute(codec);
16563 alc662_eeepc_mic_automute(codec);
16565 /* ***************** Mode3 ******************************/
16566 static void alc663_mode3_unsol_event(struct hda_codec *codec,
16567 unsigned int res)
16569 switch (res >> 26) {
16570 case ALC880_HP_EVENT:
16571 alc663_two_hp_m1_speaker_automute(codec);
16572 break;
16573 case ALC880_MIC_EVENT:
16574 alc662_eeepc_mic_automute(codec);
16575 break;
16579 static void alc663_mode3_inithook(struct hda_codec *codec)
16581 alc663_two_hp_m1_speaker_automute(codec);
16582 alc662_eeepc_mic_automute(codec);
16584 /* ***************** Mode4 ******************************/
16585 static void alc663_mode4_unsol_event(struct hda_codec *codec,
16586 unsigned int res)
16588 switch (res >> 26) {
16589 case ALC880_HP_EVENT:
16590 alc663_21jd_two_speaker_automute(codec);
16591 break;
16592 case ALC880_MIC_EVENT:
16593 alc662_eeepc_mic_automute(codec);
16594 break;
16598 static void alc663_mode4_inithook(struct hda_codec *codec)
16600 alc663_21jd_two_speaker_automute(codec);
16601 alc662_eeepc_mic_automute(codec);
16603 /* ***************** Mode5 ******************************/
16604 static void alc663_mode5_unsol_event(struct hda_codec *codec,
16605 unsigned int res)
16607 switch (res >> 26) {
16608 case ALC880_HP_EVENT:
16609 alc663_15jd_two_speaker_automute(codec);
16610 break;
16611 case ALC880_MIC_EVENT:
16612 alc662_eeepc_mic_automute(codec);
16613 break;
16617 static void alc663_mode5_inithook(struct hda_codec *codec)
16619 alc663_15jd_two_speaker_automute(codec);
16620 alc662_eeepc_mic_automute(codec);
16622 /* ***************** Mode6 ******************************/
16623 static void alc663_mode6_unsol_event(struct hda_codec *codec,
16624 unsigned int res)
16626 switch (res >> 26) {
16627 case ALC880_HP_EVENT:
16628 alc663_two_hp_m2_speaker_automute(codec);
16629 break;
16630 case ALC880_MIC_EVENT:
16631 alc662_eeepc_mic_automute(codec);
16632 break;
16636 static void alc663_mode6_inithook(struct hda_codec *codec)
16638 alc663_two_hp_m2_speaker_automute(codec);
16639 alc662_eeepc_mic_automute(codec);
16642 static void alc663_g71v_hp_automute(struct hda_codec *codec)
16644 unsigned int present;
16645 unsigned char bits;
16647 present = snd_hda_codec_read(codec, 0x21, 0,
16648 AC_VERB_GET_PIN_SENSE, 0)
16649 & AC_PINSENSE_PRESENCE;
16650 bits = present ? HDA_AMP_MUTE : 0;
16651 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
16652 HDA_AMP_MUTE, bits);
16653 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16654 HDA_AMP_MUTE, bits);
16657 static void alc663_g71v_front_automute(struct hda_codec *codec)
16659 unsigned int present;
16660 unsigned char bits;
16662 present = snd_hda_codec_read(codec, 0x15, 0,
16663 AC_VERB_GET_PIN_SENSE, 0)
16664 & AC_PINSENSE_PRESENCE;
16665 bits = present ? HDA_AMP_MUTE : 0;
16666 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
16667 HDA_AMP_MUTE, bits);
16670 static void alc663_g71v_unsol_event(struct hda_codec *codec,
16671 unsigned int res)
16673 switch (res >> 26) {
16674 case ALC880_HP_EVENT:
16675 alc663_g71v_hp_automute(codec);
16676 break;
16677 case ALC880_FRONT_EVENT:
16678 alc663_g71v_front_automute(codec);
16679 break;
16680 case ALC880_MIC_EVENT:
16681 alc662_eeepc_mic_automute(codec);
16682 break;
16686 static void alc663_g71v_inithook(struct hda_codec *codec)
16688 alc663_g71v_front_automute(codec);
16689 alc663_g71v_hp_automute(codec);
16690 alc662_eeepc_mic_automute(codec);
16693 static void alc663_g50v_unsol_event(struct hda_codec *codec,
16694 unsigned int res)
16696 switch (res >> 26) {
16697 case ALC880_HP_EVENT:
16698 alc663_m51va_speaker_automute(codec);
16699 break;
16700 case ALC880_MIC_EVENT:
16701 alc662_eeepc_mic_automute(codec);
16702 break;
16706 static void alc663_g50v_inithook(struct hda_codec *codec)
16708 alc663_m51va_speaker_automute(codec);
16709 alc662_eeepc_mic_automute(codec);
16712 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
16713 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16714 ALC262_HIPPO_MASTER_SWITCH,
16716 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
16717 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
16718 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
16720 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16721 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16722 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16723 { } /* end */
16726 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
16727 /* Master Playback automatically created from Speaker and Headphone */
16728 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16729 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16730 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16731 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16733 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16734 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16735 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
16737 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16738 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16739 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
16740 { } /* end */
16743 #ifdef CONFIG_SND_HDA_POWER_SAVE
16744 #define alc662_loopbacks alc880_loopbacks
16745 #endif
16748 /* pcm configuration: identical with ALC880 */
16749 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
16750 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
16751 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
16752 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
16755 * configuration and preset
16757 static const char *alc662_models[ALC662_MODEL_LAST] = {
16758 [ALC662_3ST_2ch_DIG] = "3stack-dig",
16759 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
16760 [ALC662_3ST_6ch] = "3stack-6ch",
16761 [ALC662_5ST_DIG] = "6stack-dig",
16762 [ALC662_LENOVO_101E] = "lenovo-101e",
16763 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
16764 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
16765 [ALC662_ECS] = "ecs",
16766 [ALC663_ASUS_M51VA] = "m51va",
16767 [ALC663_ASUS_G71V] = "g71v",
16768 [ALC663_ASUS_H13] = "h13",
16769 [ALC663_ASUS_G50V] = "g50v",
16770 [ALC663_ASUS_MODE1] = "asus-mode1",
16771 [ALC662_ASUS_MODE2] = "asus-mode2",
16772 [ALC663_ASUS_MODE3] = "asus-mode3",
16773 [ALC663_ASUS_MODE4] = "asus-mode4",
16774 [ALC663_ASUS_MODE5] = "asus-mode5",
16775 [ALC663_ASUS_MODE6] = "asus-mode6",
16776 [ALC272_DELL] = "dell",
16777 [ALC272_DELL_ZM1] = "dell-zm1",
16778 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
16779 [ALC662_AUTO] = "auto",
16782 static struct snd_pci_quirk alc662_cfg_tbl[] = {
16783 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
16784 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
16785 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
16786 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
16787 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
16788 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
16789 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
16790 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
16791 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
16792 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
16793 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
16794 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
16795 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
16796 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
16797 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
16798 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
16799 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
16800 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
16801 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
16802 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
16803 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
16804 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
16805 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
16806 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
16807 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
16808 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
16809 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
16810 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
16811 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
16812 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
16813 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
16814 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
16815 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
16816 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
16817 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
16818 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
16819 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
16820 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
16821 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
16822 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
16823 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
16824 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
16825 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
16826 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
16827 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
16828 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
16829 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
16830 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
16831 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
16832 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
16833 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
16834 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
16835 ALC662_3ST_6ch_DIG),
16836 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
16837 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
16838 ALC662_3ST_6ch_DIG),
16839 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
16840 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
16841 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
16842 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
16843 ALC662_3ST_6ch_DIG),
16844 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
16845 ALC663_ASUS_H13),
16849 static struct alc_config_preset alc662_presets[] = {
16850 [ALC662_3ST_2ch_DIG] = {
16851 .mixers = { alc662_3ST_2ch_mixer },
16852 .init_verbs = { alc662_init_verbs },
16853 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16854 .dac_nids = alc662_dac_nids,
16855 .dig_out_nid = ALC662_DIGOUT_NID,
16856 .dig_in_nid = ALC662_DIGIN_NID,
16857 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16858 .channel_mode = alc662_3ST_2ch_modes,
16859 .input_mux = &alc662_capture_source,
16861 [ALC662_3ST_6ch_DIG] = {
16862 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16863 .init_verbs = { alc662_init_verbs },
16864 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16865 .dac_nids = alc662_dac_nids,
16866 .dig_out_nid = ALC662_DIGOUT_NID,
16867 .dig_in_nid = ALC662_DIGIN_NID,
16868 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16869 .channel_mode = alc662_3ST_6ch_modes,
16870 .need_dac_fix = 1,
16871 .input_mux = &alc662_capture_source,
16873 [ALC662_3ST_6ch] = {
16874 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
16875 .init_verbs = { alc662_init_verbs },
16876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16877 .dac_nids = alc662_dac_nids,
16878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16879 .channel_mode = alc662_3ST_6ch_modes,
16880 .need_dac_fix = 1,
16881 .input_mux = &alc662_capture_source,
16883 [ALC662_5ST_DIG] = {
16884 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
16885 .init_verbs = { alc662_init_verbs },
16886 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16887 .dac_nids = alc662_dac_nids,
16888 .dig_out_nid = ALC662_DIGOUT_NID,
16889 .dig_in_nid = ALC662_DIGIN_NID,
16890 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
16891 .channel_mode = alc662_5stack_modes,
16892 .input_mux = &alc662_capture_source,
16894 [ALC662_LENOVO_101E] = {
16895 .mixers = { alc662_lenovo_101e_mixer },
16896 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
16897 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16898 .dac_nids = alc662_dac_nids,
16899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16900 .channel_mode = alc662_3ST_2ch_modes,
16901 .input_mux = &alc662_lenovo_101e_capture_source,
16902 .unsol_event = alc662_lenovo_101e_unsol_event,
16903 .init_hook = alc662_lenovo_101e_all_automute,
16905 [ALC662_ASUS_EEEPC_P701] = {
16906 .mixers = { alc662_eeepc_p701_mixer },
16907 .init_verbs = { alc662_init_verbs,
16908 alc662_eeepc_sue_init_verbs },
16909 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16910 .dac_nids = alc662_dac_nids,
16911 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16912 .channel_mode = alc662_3ST_2ch_modes,
16913 .input_mux = &alc662_eeepc_capture_source,
16914 .unsol_event = alc662_eeepc_unsol_event,
16915 .init_hook = alc662_eeepc_inithook,
16917 [ALC662_ASUS_EEEPC_EP20] = {
16918 .mixers = { alc662_eeepc_ep20_mixer,
16919 alc662_chmode_mixer },
16920 .init_verbs = { alc662_init_verbs,
16921 alc662_eeepc_ep20_sue_init_verbs },
16922 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16923 .dac_nids = alc662_dac_nids,
16924 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16925 .channel_mode = alc662_3ST_6ch_modes,
16926 .input_mux = &alc662_lenovo_101e_capture_source,
16927 .unsol_event = alc662_eeepc_unsol_event,
16928 .init_hook = alc662_eeepc_ep20_inithook,
16930 [ALC662_ECS] = {
16931 .mixers = { alc662_ecs_mixer },
16932 .init_verbs = { alc662_init_verbs,
16933 alc662_ecs_init_verbs },
16934 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16935 .dac_nids = alc662_dac_nids,
16936 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16937 .channel_mode = alc662_3ST_2ch_modes,
16938 .input_mux = &alc662_eeepc_capture_source,
16939 .unsol_event = alc662_eeepc_unsol_event,
16940 .init_hook = alc662_eeepc_inithook,
16942 [ALC663_ASUS_M51VA] = {
16943 .mixers = { alc663_m51va_mixer },
16944 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16946 .dac_nids = alc662_dac_nids,
16947 .dig_out_nid = ALC662_DIGOUT_NID,
16948 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16949 .channel_mode = alc662_3ST_2ch_modes,
16950 .input_mux = &alc663_m51va_capture_source,
16951 .unsol_event = alc663_m51va_unsol_event,
16952 .init_hook = alc663_m51va_inithook,
16954 [ALC663_ASUS_G71V] = {
16955 .mixers = { alc663_g71v_mixer },
16956 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
16957 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16958 .dac_nids = alc662_dac_nids,
16959 .dig_out_nid = ALC662_DIGOUT_NID,
16960 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16961 .channel_mode = alc662_3ST_2ch_modes,
16962 .input_mux = &alc662_eeepc_capture_source,
16963 .unsol_event = alc663_g71v_unsol_event,
16964 .init_hook = alc663_g71v_inithook,
16966 [ALC663_ASUS_H13] = {
16967 .mixers = { alc663_m51va_mixer },
16968 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
16969 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16970 .dac_nids = alc662_dac_nids,
16971 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16972 .channel_mode = alc662_3ST_2ch_modes,
16973 .input_mux = &alc663_m51va_capture_source,
16974 .unsol_event = alc663_m51va_unsol_event,
16975 .init_hook = alc663_m51va_inithook,
16977 [ALC663_ASUS_G50V] = {
16978 .mixers = { alc663_g50v_mixer },
16979 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16980 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16981 .dac_nids = alc662_dac_nids,
16982 .dig_out_nid = ALC662_DIGOUT_NID,
16983 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
16984 .channel_mode = alc662_3ST_6ch_modes,
16985 .input_mux = &alc663_capture_source,
16986 .unsol_event = alc663_g50v_unsol_event,
16987 .init_hook = alc663_g50v_inithook,
16989 [ALC663_ASUS_MODE1] = {
16990 .mixers = { alc663_m51va_mixer },
16991 .cap_mixer = alc662_auto_capture_mixer,
16992 .init_verbs = { alc662_init_verbs,
16993 alc663_21jd_amic_init_verbs },
16994 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16995 .hp_nid = 0x03,
16996 .dac_nids = alc662_dac_nids,
16997 .dig_out_nid = ALC662_DIGOUT_NID,
16998 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16999 .channel_mode = alc662_3ST_2ch_modes,
17000 .input_mux = &alc662_eeepc_capture_source,
17001 .unsol_event = alc663_mode1_unsol_event,
17002 .init_hook = alc663_mode1_inithook,
17004 [ALC662_ASUS_MODE2] = {
17005 .mixers = { alc662_1bjd_mixer },
17006 .cap_mixer = alc662_auto_capture_mixer,
17007 .init_verbs = { alc662_init_verbs,
17008 alc662_1bjd_amic_init_verbs },
17009 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17010 .dac_nids = alc662_dac_nids,
17011 .dig_out_nid = ALC662_DIGOUT_NID,
17012 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17013 .channel_mode = alc662_3ST_2ch_modes,
17014 .input_mux = &alc662_eeepc_capture_source,
17015 .unsol_event = alc662_mode2_unsol_event,
17016 .init_hook = alc662_mode2_inithook,
17018 [ALC663_ASUS_MODE3] = {
17019 .mixers = { alc663_two_hp_m1_mixer },
17020 .cap_mixer = alc662_auto_capture_mixer,
17021 .init_verbs = { alc662_init_verbs,
17022 alc663_two_hp_amic_m1_init_verbs },
17023 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17024 .hp_nid = 0x03,
17025 .dac_nids = alc662_dac_nids,
17026 .dig_out_nid = ALC662_DIGOUT_NID,
17027 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17028 .channel_mode = alc662_3ST_2ch_modes,
17029 .input_mux = &alc662_eeepc_capture_source,
17030 .unsol_event = alc663_mode3_unsol_event,
17031 .init_hook = alc663_mode3_inithook,
17033 [ALC663_ASUS_MODE4] = {
17034 .mixers = { alc663_asus_21jd_clfe_mixer },
17035 .cap_mixer = alc662_auto_capture_mixer,
17036 .init_verbs = { alc662_init_verbs,
17037 alc663_21jd_amic_init_verbs},
17038 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17039 .hp_nid = 0x03,
17040 .dac_nids = alc662_dac_nids,
17041 .dig_out_nid = ALC662_DIGOUT_NID,
17042 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17043 .channel_mode = alc662_3ST_2ch_modes,
17044 .input_mux = &alc662_eeepc_capture_source,
17045 .unsol_event = alc663_mode4_unsol_event,
17046 .init_hook = alc663_mode4_inithook,
17048 [ALC663_ASUS_MODE5] = {
17049 .mixers = { alc663_asus_15jd_clfe_mixer },
17050 .cap_mixer = alc662_auto_capture_mixer,
17051 .init_verbs = { alc662_init_verbs,
17052 alc663_15jd_amic_init_verbs },
17053 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17054 .hp_nid = 0x03,
17055 .dac_nids = alc662_dac_nids,
17056 .dig_out_nid = ALC662_DIGOUT_NID,
17057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17058 .channel_mode = alc662_3ST_2ch_modes,
17059 .input_mux = &alc662_eeepc_capture_source,
17060 .unsol_event = alc663_mode5_unsol_event,
17061 .init_hook = alc663_mode5_inithook,
17063 [ALC663_ASUS_MODE6] = {
17064 .mixers = { alc663_two_hp_m2_mixer },
17065 .cap_mixer = alc662_auto_capture_mixer,
17066 .init_verbs = { alc662_init_verbs,
17067 alc663_two_hp_amic_m2_init_verbs },
17068 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17069 .hp_nid = 0x03,
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 .input_mux = &alc662_eeepc_capture_source,
17075 .unsol_event = alc663_mode6_unsol_event,
17076 .init_hook = alc663_mode6_inithook,
17078 [ALC272_DELL] = {
17079 .mixers = { alc663_m51va_mixer },
17080 .cap_mixer = alc272_auto_capture_mixer,
17081 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
17082 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17083 .dac_nids = alc662_dac_nids,
17084 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17085 .adc_nids = alc272_adc_nids,
17086 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17087 .capsrc_nids = alc272_capsrc_nids,
17088 .channel_mode = alc662_3ST_2ch_modes,
17089 .input_mux = &alc663_m51va_capture_source,
17090 .unsol_event = alc663_m51va_unsol_event,
17091 .init_hook = alc663_m51va_inithook,
17093 [ALC272_DELL_ZM1] = {
17094 .mixers = { alc663_m51va_mixer },
17095 .cap_mixer = alc662_auto_capture_mixer,
17096 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
17097 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17098 .dac_nids = alc662_dac_nids,
17099 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17100 .adc_nids = alc662_adc_nids,
17101 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
17102 .capsrc_nids = alc662_capsrc_nids,
17103 .channel_mode = alc662_3ST_2ch_modes,
17104 .input_mux = &alc663_m51va_capture_source,
17105 .unsol_event = alc663_m51va_unsol_event,
17106 .init_hook = alc663_m51va_inithook,
17108 [ALC272_SAMSUNG_NC10] = {
17109 .mixers = { alc272_nc10_mixer },
17110 .init_verbs = { alc662_init_verbs,
17111 alc663_21jd_amic_init_verbs },
17112 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
17113 .dac_nids = alc272_dac_nids,
17114 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17115 .channel_mode = alc662_3ST_2ch_modes,
17116 .input_mux = &alc272_nc10_capture_source,
17117 .unsol_event = alc663_mode4_unsol_event,
17118 .init_hook = alc663_mode4_inithook,
17124 * BIOS auto configuration
17127 /* add playback controls from the parsed DAC table */
17128 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
17129 const struct auto_pin_cfg *cfg)
17131 char name[32];
17132 static const char *chname[4] = {
17133 "Front", "Surround", NULL /*CLFE*/, "Side"
17135 hda_nid_t nid;
17136 int i, err;
17138 for (i = 0; i < cfg->line_outs; i++) {
17139 if (!spec->multiout.dac_nids[i])
17140 continue;
17141 nid = alc880_idx_to_dac(i);
17142 if (i == 2) {
17143 /* Center/LFE */
17144 err = add_control(spec, ALC_CTL_WIDGET_VOL,
17145 "Center Playback Volume",
17146 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
17147 HDA_OUTPUT));
17148 if (err < 0)
17149 return err;
17150 err = add_control(spec, ALC_CTL_WIDGET_VOL,
17151 "LFE Playback Volume",
17152 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
17153 HDA_OUTPUT));
17154 if (err < 0)
17155 return err;
17156 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
17157 "Center Playback Switch",
17158 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
17159 HDA_INPUT));
17160 if (err < 0)
17161 return err;
17162 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
17163 "LFE Playback Switch",
17164 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
17165 HDA_INPUT));
17166 if (err < 0)
17167 return err;
17168 } else {
17169 sprintf(name, "%s Playback Volume", chname[i]);
17170 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17171 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17172 HDA_OUTPUT));
17173 if (err < 0)
17174 return err;
17175 sprintf(name, "%s Playback Switch", chname[i]);
17176 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17177 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
17178 3, 0, HDA_INPUT));
17179 if (err < 0)
17180 return err;
17183 return 0;
17186 /* add playback controls for speaker and HP outputs */
17187 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
17188 const char *pfx)
17190 hda_nid_t nid;
17191 int err;
17192 char name[32];
17194 if (!pin)
17195 return 0;
17197 if (pin == 0x17) {
17198 /* ALC663 has a mono output pin on 0x17 */
17199 sprintf(name, "%s Playback Switch", pfx);
17200 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17201 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
17202 return err;
17205 if (alc880_is_fixed_pin(pin)) {
17206 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17207 /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
17208 /* specify the DAC as the extra output */
17209 if (!spec->multiout.hp_nid)
17210 spec->multiout.hp_nid = nid;
17211 else
17212 spec->multiout.extra_out_nid[0] = nid;
17213 /* control HP volume/switch on the output mixer amp */
17214 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17215 sprintf(name, "%s Playback Volume", pfx);
17216 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17217 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
17218 if (err < 0)
17219 return err;
17220 sprintf(name, "%s Playback Switch", pfx);
17221 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
17222 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
17223 if (err < 0)
17224 return err;
17225 } else if (alc880_is_multi_pin(pin)) {
17226 /* set manual connection */
17227 /* we have only a switch on HP-out PIN */
17228 sprintf(name, "%s Playback Switch", pfx);
17229 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17230 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17231 if (err < 0)
17232 return err;
17234 return 0;
17237 /* return the index of the src widget from the connection list of the nid.
17238 * return -1 if not found
17240 static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
17241 hda_nid_t src)
17243 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
17244 int i, conns;
17246 conns = snd_hda_get_connections(codec, nid, conn_list,
17247 ARRAY_SIZE(conn_list));
17248 if (conns < 0)
17249 return -1;
17250 for (i = 0; i < conns; i++)
17251 if (conn_list[i] == src)
17252 return i;
17253 return -1;
17256 static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
17258 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
17259 return (pincap & AC_PINCAP_IN) != 0;
17262 /* create playback/capture controls for input pins */
17263 static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec,
17264 const struct auto_pin_cfg *cfg)
17266 struct alc_spec *spec = codec->spec;
17267 struct hda_input_mux *imux = &spec->private_imux[0];
17268 int i, err, idx;
17270 for (i = 0; i < AUTO_PIN_LAST; i++) {
17271 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
17272 idx = alc662_input_pin_idx(codec, 0x0b,
17273 cfg->input_pins[i]);
17274 if (idx >= 0) {
17275 err = new_analog_input(spec, cfg->input_pins[i],
17276 auto_pin_cfg_labels[i],
17277 idx, 0x0b);
17278 if (err < 0)
17279 return err;
17281 idx = alc662_input_pin_idx(codec, 0x22,
17282 cfg->input_pins[i]);
17283 if (idx >= 0) {
17284 imux->items[imux->num_items].label =
17285 auto_pin_cfg_labels[i];
17286 imux->items[imux->num_items].index = idx;
17287 imux->num_items++;
17291 return 0;
17294 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17295 hda_nid_t nid, int pin_type,
17296 int dac_idx)
17298 alc_set_pin_output(codec, nid, pin_type);
17299 /* need the manual connection? */
17300 if (alc880_is_multi_pin(nid)) {
17301 struct alc_spec *spec = codec->spec;
17302 int idx = alc880_multi_pin_idx(nid);
17303 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
17304 AC_VERB_SET_CONNECT_SEL,
17305 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
17309 static void alc662_auto_init_multi_out(struct hda_codec *codec)
17311 struct alc_spec *spec = codec->spec;
17312 int i;
17314 for (i = 0; i <= HDA_SIDE; i++) {
17315 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17316 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17317 if (nid)
17318 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
17323 static void alc662_auto_init_hp_out(struct hda_codec *codec)
17325 struct alc_spec *spec = codec->spec;
17326 hda_nid_t pin;
17328 pin = spec->autocfg.hp_pins[0];
17329 if (pin) /* connect to front */
17330 /* use dac 0 */
17331 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17332 pin = spec->autocfg.speaker_pins[0];
17333 if (pin)
17334 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17337 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
17339 static void alc662_auto_init_analog_input(struct hda_codec *codec)
17341 struct alc_spec *spec = codec->spec;
17342 int i;
17344 for (i = 0; i < AUTO_PIN_LAST; i++) {
17345 hda_nid_t nid = spec->autocfg.input_pins[i];
17346 if (alc662_is_input_pin(codec, nid)) {
17347 alc_set_input_pin(codec, nid, i);
17348 if (nid != ALC662_PIN_CD_NID &&
17349 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17350 snd_hda_codec_write(codec, nid, 0,
17351 AC_VERB_SET_AMP_GAIN_MUTE,
17352 AMP_OUT_MUTE);
17357 #define alc662_auto_init_input_src alc882_auto_init_input_src
17359 static int alc662_parse_auto_config(struct hda_codec *codec)
17361 struct alc_spec *spec = codec->spec;
17362 int err;
17363 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
17365 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17366 alc662_ignore);
17367 if (err < 0)
17368 return err;
17369 if (!spec->autocfg.line_outs)
17370 return 0; /* can't find valid BIOS pin config */
17372 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17373 if (err < 0)
17374 return err;
17375 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
17376 if (err < 0)
17377 return err;
17378 err = alc662_auto_create_extra_out(spec,
17379 spec->autocfg.speaker_pins[0],
17380 "Speaker");
17381 if (err < 0)
17382 return err;
17383 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
17384 "Headphone");
17385 if (err < 0)
17386 return err;
17387 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg);
17388 if (err < 0)
17389 return err;
17391 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17393 if (spec->autocfg.dig_outs)
17394 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
17396 if (spec->kctls.list)
17397 add_mixer(spec, spec->kctls.list);
17399 spec->num_mux_defs = 1;
17400 spec->input_mux = &spec->private_imux[0];
17402 add_verb(spec, alc662_auto_init_verbs);
17403 if (codec->vendor_id == 0x10ec0663)
17404 add_verb(spec, alc663_auto_init_verbs);
17406 err = alc_auto_add_mic_boost(codec);
17407 if (err < 0)
17408 return err;
17410 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17412 return 1;
17415 /* additional initialization for auto-configuration model */
17416 static void alc662_auto_init(struct hda_codec *codec)
17418 struct alc_spec *spec = codec->spec;
17419 alc662_auto_init_multi_out(codec);
17420 alc662_auto_init_hp_out(codec);
17421 alc662_auto_init_analog_input(codec);
17422 alc662_auto_init_input_src(codec);
17423 if (spec->unsol_event)
17424 alc_inithook(codec);
17427 static int patch_alc662(struct hda_codec *codec)
17429 struct alc_spec *spec;
17430 int err, board_config;
17432 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17433 if (!spec)
17434 return -ENOMEM;
17436 codec->spec = spec;
17438 alc_fix_pll_init(codec, 0x20, 0x04, 15);
17440 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
17441 alc662_models,
17442 alc662_cfg_tbl);
17443 if (board_config < 0) {
17444 printk(KERN_INFO "hda_codec: Unknown model for %s, "
17445 "trying auto-probe from BIOS...\n", codec->chip_name);
17446 board_config = ALC662_AUTO;
17449 if (board_config == ALC662_AUTO) {
17450 /* automatic parse from the BIOS config */
17451 err = alc662_parse_auto_config(codec);
17452 if (err < 0) {
17453 alc_free(codec);
17454 return err;
17455 } else if (!err) {
17456 printk(KERN_INFO
17457 "hda_codec: Cannot set up configuration "
17458 "from BIOS. Using base mode...\n");
17459 board_config = ALC662_3ST_2ch_DIG;
17463 err = snd_hda_attach_beep_device(codec, 0x1);
17464 if (err < 0) {
17465 alc_free(codec);
17466 return err;
17469 if (board_config != ALC662_AUTO)
17470 setup_preset(spec, &alc662_presets[board_config]);
17472 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17473 spec->stream_analog_capture = &alc662_pcm_analog_capture;
17475 spec->stream_digital_playback = &alc662_pcm_digital_playback;
17476 spec->stream_digital_capture = &alc662_pcm_digital_capture;
17478 spec->adc_nids = alc662_adc_nids;
17479 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
17480 spec->capsrc_nids = alc662_capsrc_nids;
17482 if (!spec->cap_mixer)
17483 set_capture_mixer(spec);
17484 if (codec->vendor_id == 0x10ec0662)
17485 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17486 else
17487 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
17489 spec->vmaster_nid = 0x02;
17491 codec->patch_ops = alc_patch_ops;
17492 if (board_config == ALC662_AUTO)
17493 spec->init_hook = alc662_auto_init;
17494 #ifdef CONFIG_SND_HDA_POWER_SAVE
17495 if (!spec->loopback.amplist)
17496 spec->loopback.amplist = alc662_loopbacks;
17497 #endif
17498 codec->proc_widget_hook = print_realtek_coef;
17500 return 0;
17504 * patch entries
17506 static struct hda_codec_preset snd_hda_preset_realtek[] = {
17507 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
17508 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
17509 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
17510 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
17511 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
17512 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
17513 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
17514 .patch = patch_alc861 },
17515 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
17516 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17517 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17518 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17519 .patch = patch_alc883 },
17520 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17521 .patch = patch_alc662 },
17522 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17523 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17524 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17525 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
17526 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17527 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17528 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17529 .patch = patch_alc882 }, /* should be patch_alc883() in future */
17530 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17531 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
17532 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17533 .patch = patch_alc883 },
17534 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
17535 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
17536 {} /* terminator */
17539 MODULE_ALIAS("snd-hda-codec-id:10ec*");
17541 MODULE_LICENSE("GPL");
17542 MODULE_DESCRIPTION("Realtek HD-audio codec");
17544 static struct hda_codec_preset_list realtek_list = {
17545 .preset = snd_hda_preset_realtek,
17546 .owner = THIS_MODULE,
17549 static int __init patch_realtek_init(void)
17551 return snd_hda_add_codec_preset(&realtek_list);
17554 static void __exit patch_realtek_exit(void)
17556 snd_hda_delete_codec_preset(&realtek_list);
17559 module_init(patch_realtek_init)
17560 module_exit(patch_realtek_exit)