ALSA: hda - Fix ALC882 DAC connections in auto mode
[deliverable/linux.git] / sound / pci / hda / patch_realtek.c
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
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>
10 *
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.
15 *
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.
20 *
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
24 */
25
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"
34
35 #define ALC880_FRONT_EVENT 0x01
36 #define ALC880_DCVOL_EVENT 0x02
37 #define ALC880_HP_EVENT 0x04
38 #define ALC880_MIC_EVENT 0x08
39
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 */
69 };
70
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 */
87 };
88
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 */
111 };
112
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 */
128 };
129
130 /* ALC269 models */
131 enum {
132 ALC269_BASIC,
133 ALC269_QUANTA_FL1,
134 ALC269_AMIC,
135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
138 ALC269_FUJITSU,
139 ALC269_LIFEBOOK,
140 ALC269_AUTO,
141 ALC269_MODEL_LAST /* last tag */
142 };
143
144 /* ALC861 models */
145 enum {
146 ALC861_3ST,
147 ALC660_3ST,
148 ALC861_3ST_DIG,
149 ALC861_6ST_DIG,
150 ALC861_UNIWILL_M31,
151 ALC861_TOSHIBA,
152 ALC861_ASUS,
153 ALC861_ASUS_LAPTOP,
154 ALC861_AUTO,
155 ALC861_MODEL_LAST,
156 };
157
158 /* ALC861-VD models */
159 enum {
160 ALC660VD_3ST,
161 ALC660VD_3ST_DIG,
162 ALC660VD_ASUS_V1S,
163 ALC861VD_3ST,
164 ALC861VD_3ST_DIG,
165 ALC861VD_6ST_DIG,
166 ALC861VD_LENOVO,
167 ALC861VD_DALLAS,
168 ALC861VD_HP,
169 ALC861VD_AUTO,
170 ALC861VD_MODEL_LAST,
171 };
172
173 /* ALC662 models */
174 enum {
175 ALC662_3ST_2ch_DIG,
176 ALC662_3ST_6ch_DIG,
177 ALC662_3ST_6ch,
178 ALC662_5ST_DIG,
179 ALC662_LENOVO_101E,
180 ALC662_ASUS_EEEPC_P701,
181 ALC662_ASUS_EEEPC_EP20,
182 ALC663_ASUS_M51VA,
183 ALC663_ASUS_G71V,
184 ALC663_ASUS_H13,
185 ALC663_ASUS_G50V,
186 ALC662_ECS,
187 ALC663_ASUS_MODE1,
188 ALC662_ASUS_MODE2,
189 ALC663_ASUS_MODE3,
190 ALC663_ASUS_MODE4,
191 ALC663_ASUS_MODE5,
192 ALC663_ASUS_MODE6,
193 ALC663_ASUS_MODE7,
194 ALC663_ASUS_MODE8,
195 ALC272_DELL,
196 ALC272_DELL_ZM1,
197 ALC272_SAMSUNG_NC10,
198 ALC662_AUTO,
199 ALC662_MODEL_LAST,
200 };
201
202 /* ALC882 models */
203 enum {
204 ALC882_3ST_DIG,
205 ALC882_6ST_DIG,
206 ALC882_ARIMA,
207 ALC882_W2JC,
208 ALC882_TARGA,
209 ALC882_ASUS_A7J,
210 ALC882_ASUS_A7M,
211 ALC885_MACPRO,
212 ALC885_MBA21,
213 ALC885_MBP3,
214 ALC885_MB5,
215 ALC885_MACMINI3,
216 ALC885_IMAC24,
217 ALC885_IMAC91,
218 ALC883_3ST_2ch_DIG,
219 ALC883_3ST_6ch_DIG,
220 ALC883_3ST_6ch,
221 ALC883_6ST_DIG,
222 ALC883_TARGA_DIG,
223 ALC883_TARGA_2ch_DIG,
224 ALC883_TARGA_8ch_DIG,
225 ALC883_ACER,
226 ALC883_ACER_ASPIRE,
227 ALC888_ACER_ASPIRE_4930G,
228 ALC888_ACER_ASPIRE_6530G,
229 ALC888_ACER_ASPIRE_8930G,
230 ALC888_ACER_ASPIRE_7730G,
231 ALC883_MEDION,
232 ALC883_MEDION_MD2,
233 ALC883_LAPTOP_EAPD,
234 ALC883_LENOVO_101E_2ch,
235 ALC883_LENOVO_NB0763,
236 ALC888_LENOVO_MS7195_DIG,
237 ALC888_LENOVO_SKY,
238 ALC883_HAIER_W66,
239 ALC888_3ST_HP,
240 ALC888_6ST_DELL,
241 ALC883_MITAC,
242 ALC883_CLEVO_M540R,
243 ALC883_CLEVO_M720,
244 ALC883_FUJITSU_PI2515,
245 ALC888_FUJITSU_XA3530,
246 ALC883_3ST_6ch_INTEL,
247 ALC889A_INTEL,
248 ALC889_INTEL,
249 ALC888_ASUS_M90V,
250 ALC888_ASUS_EEE1601,
251 ALC889A_MB31,
252 ALC1200_ASUS_P5Q,
253 ALC883_SONY_VAIO_TT,
254 ALC882_AUTO,
255 ALC882_MODEL_LAST,
256 };
257
258 /* for GPIO Poll */
259 #define GPIO_MASK 0x03
260
261 /* extra amp-initialization sequence types */
262 enum {
263 ALC_INIT_NONE,
264 ALC_INIT_DEFAULT,
265 ALC_INIT_GPIO1,
266 ALC_INIT_GPIO2,
267 ALC_INIT_GPIO3,
268 };
269
270 struct alc_mic_route {
271 hda_nid_t pin;
272 unsigned char mux_idx;
273 unsigned char amix_idx;
274 };
275
276 #define MUX_IDX_UNDEF ((unsigned char)-1)
277
278 struct alc_customize_define {
279 unsigned int sku_cfg;
280 unsigned char port_connectivity;
281 unsigned char check_sum;
282 unsigned char customization;
283 unsigned char external_amp;
284 unsigned int enable_pcbeep:1;
285 unsigned int platform_type:1;
286 unsigned int swap:1;
287 unsigned int override:1;
288 };
289
290 struct alc_spec {
291 /* codec parameterization */
292 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
293 unsigned int num_mixers;
294 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
295 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
296
297 const struct hda_verb *init_verbs[10]; /* initialization verbs
298 * don't forget NULL
299 * termination!
300 */
301 unsigned int num_init_verbs;
302
303 char stream_name_analog[32]; /* analog PCM stream */
304 struct hda_pcm_stream *stream_analog_playback;
305 struct hda_pcm_stream *stream_analog_capture;
306 struct hda_pcm_stream *stream_analog_alt_playback;
307 struct hda_pcm_stream *stream_analog_alt_capture;
308
309 char stream_name_digital[32]; /* digital PCM stream */
310 struct hda_pcm_stream *stream_digital_playback;
311 struct hda_pcm_stream *stream_digital_capture;
312
313 /* playback */
314 struct hda_multi_out multiout; /* playback set-up
315 * max_channels, dacs must be set
316 * dig_out_nid and hp_nid are optional
317 */
318 hda_nid_t alt_dac_nid;
319 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
320 int dig_out_type;
321
322 /* capture */
323 unsigned int num_adc_nids;
324 hda_nid_t *adc_nids;
325 hda_nid_t *capsrc_nids;
326 hda_nid_t dig_in_nid; /* digital-in NID; optional */
327
328 /* capture source */
329 unsigned int num_mux_defs;
330 const struct hda_input_mux *input_mux;
331 unsigned int cur_mux[3];
332 struct alc_mic_route ext_mic;
333 struct alc_mic_route int_mic;
334
335 /* channel model */
336 const struct hda_channel_mode *channel_mode;
337 int num_channel_mode;
338 int need_dac_fix;
339 int const_channel_count;
340 int ext_channel_count;
341
342 /* PCM information */
343 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
344
345 /* dynamic controls, init_verbs and input_mux */
346 struct auto_pin_cfg autocfg;
347 struct alc_customize_define cdefine;
348 struct snd_array kctls;
349 struct hda_input_mux private_imux[3];
350 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
351 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
352 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
353
354 /* hooks */
355 void (*init_hook)(struct hda_codec *codec);
356 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
357 #ifdef CONFIG_SND_HDA_POWER_SAVE
358 void (*power_hook)(struct hda_codec *codec);
359 #endif
360
361 /* for pin sensing */
362 unsigned int sense_updated: 1;
363 unsigned int jack_present: 1;
364 unsigned int master_sw: 1;
365 unsigned int auto_mic:1;
366
367 /* other flags */
368 unsigned int no_analog :1; /* digital I/O only */
369 int init_amp;
370
371 /* for virtual master */
372 hda_nid_t vmaster_nid;
373 #ifdef CONFIG_SND_HDA_POWER_SAVE
374 struct hda_loopback_check loopback;
375 #endif
376
377 /* for PLL fix */
378 hda_nid_t pll_nid;
379 unsigned int pll_coef_idx, pll_coef_bit;
380 };
381
382 /*
383 * configuration template - to be copied to the spec instance
384 */
385 struct alc_config_preset {
386 struct snd_kcontrol_new *mixers[5]; /* should be identical size
387 * with spec
388 */
389 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
390 const struct hda_verb *init_verbs[5];
391 unsigned int num_dacs;
392 hda_nid_t *dac_nids;
393 hda_nid_t dig_out_nid; /* optional */
394 hda_nid_t hp_nid; /* optional */
395 hda_nid_t *slave_dig_outs;
396 unsigned int num_adc_nids;
397 hda_nid_t *adc_nids;
398 hda_nid_t *capsrc_nids;
399 hda_nid_t dig_in_nid;
400 unsigned int num_channel_mode;
401 const struct hda_channel_mode *channel_mode;
402 int need_dac_fix;
403 int const_channel_count;
404 unsigned int num_mux_defs;
405 const struct hda_input_mux *input_mux;
406 void (*unsol_event)(struct hda_codec *, unsigned int);
407 void (*setup)(struct hda_codec *);
408 void (*init_hook)(struct hda_codec *);
409 #ifdef CONFIG_SND_HDA_POWER_SAVE
410 struct hda_amp_list *loopbacks;
411 void (*power_hook)(struct hda_codec *codec);
412 #endif
413 };
414
415
416 /*
417 * input MUX handling
418 */
419 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
420 struct snd_ctl_elem_info *uinfo)
421 {
422 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
423 struct alc_spec *spec = codec->spec;
424 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
425 if (mux_idx >= spec->num_mux_defs)
426 mux_idx = 0;
427 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
428 mux_idx = 0;
429 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
430 }
431
432 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
433 struct snd_ctl_elem_value *ucontrol)
434 {
435 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
436 struct alc_spec *spec = codec->spec;
437 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
438
439 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
440 return 0;
441 }
442
443 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
444 struct snd_ctl_elem_value *ucontrol)
445 {
446 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
447 struct alc_spec *spec = codec->spec;
448 const struct hda_input_mux *imux;
449 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
450 unsigned int mux_idx;
451 hda_nid_t nid = spec->capsrc_nids ?
452 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
453 unsigned int type;
454
455 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
456 imux = &spec->input_mux[mux_idx];
457 if (!imux->num_items && mux_idx > 0)
458 imux = &spec->input_mux[0];
459
460 type = get_wcaps_type(get_wcaps(codec, nid));
461 if (type == AC_WID_AUD_MIX) {
462 /* Matrix-mixer style (e.g. ALC882) */
463 unsigned int *cur_val = &spec->cur_mux[adc_idx];
464 unsigned int i, idx;
465
466 idx = ucontrol->value.enumerated.item[0];
467 if (idx >= imux->num_items)
468 idx = imux->num_items - 1;
469 if (*cur_val == idx)
470 return 0;
471 for (i = 0; i < imux->num_items; i++) {
472 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
473 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
474 imux->items[i].index,
475 HDA_AMP_MUTE, v);
476 }
477 *cur_val = idx;
478 return 1;
479 } else {
480 /* MUX style (e.g. ALC880) */
481 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
482 &spec->cur_mux[adc_idx]);
483 }
484 }
485
486 /*
487 * channel mode setting
488 */
489 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
490 struct snd_ctl_elem_info *uinfo)
491 {
492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
493 struct alc_spec *spec = codec->spec;
494 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
495 spec->num_channel_mode);
496 }
497
498 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
500 {
501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502 struct alc_spec *spec = codec->spec;
503 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
504 spec->num_channel_mode,
505 spec->ext_channel_count);
506 }
507
508 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
509 struct snd_ctl_elem_value *ucontrol)
510 {
511 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
512 struct alc_spec *spec = codec->spec;
513 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
514 spec->num_channel_mode,
515 &spec->ext_channel_count);
516 if (err >= 0 && !spec->const_channel_count) {
517 spec->multiout.max_channels = spec->ext_channel_count;
518 if (spec->need_dac_fix)
519 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
520 }
521 return err;
522 }
523
524 /*
525 * Control the mode of pin widget settings via the mixer. "pc" is used
526 * instead of "%" to avoid consequences of accidently treating the % as
527 * being part of a format specifier. Maximum allowed length of a value is
528 * 63 characters plus NULL terminator.
529 *
530 * Note: some retasking pin complexes seem to ignore requests for input
531 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
532 * are requested. Therefore order this list so that this behaviour will not
533 * cause problems when mixer clients move through the enum sequentially.
534 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
535 * March 2006.
536 */
537 static char *alc_pin_mode_names[] = {
538 "Mic 50pc bias", "Mic 80pc bias",
539 "Line in", "Line out", "Headphone out",
540 };
541 static unsigned char alc_pin_mode_values[] = {
542 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
543 };
544 /* The control can present all 5 options, or it can limit the options based
545 * in the pin being assumed to be exclusively an input or an output pin. In
546 * addition, "input" pins may or may not process the mic bias option
547 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
548 * accept requests for bias as of chip versions up to March 2006) and/or
549 * wiring in the computer.
550 */
551 #define ALC_PIN_DIR_IN 0x00
552 #define ALC_PIN_DIR_OUT 0x01
553 #define ALC_PIN_DIR_INOUT 0x02
554 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
555 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
556
557 /* Info about the pin modes supported by the different pin direction modes.
558 * For each direction the minimum and maximum values are given.
559 */
560 static signed char alc_pin_mode_dir_info[5][2] = {
561 { 0, 2 }, /* ALC_PIN_DIR_IN */
562 { 3, 4 }, /* ALC_PIN_DIR_OUT */
563 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
564 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
565 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
566 };
567 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
568 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
569 #define alc_pin_mode_n_items(_dir) \
570 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
571
572 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
573 struct snd_ctl_elem_info *uinfo)
574 {
575 unsigned int item_num = uinfo->value.enumerated.item;
576 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
577
578 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
579 uinfo->count = 1;
580 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
581
582 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
583 item_num = alc_pin_mode_min(dir);
584 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
585 return 0;
586 }
587
588 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
589 struct snd_ctl_elem_value *ucontrol)
590 {
591 unsigned int i;
592 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
593 hda_nid_t nid = kcontrol->private_value & 0xffff;
594 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
595 long *valp = ucontrol->value.integer.value;
596 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
597 AC_VERB_GET_PIN_WIDGET_CONTROL,
598 0x00);
599
600 /* Find enumerated value for current pinctl setting */
601 i = alc_pin_mode_min(dir);
602 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
603 i++;
604 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
605 return 0;
606 }
607
608 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
610 {
611 signed int change;
612 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613 hda_nid_t nid = kcontrol->private_value & 0xffff;
614 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
615 long val = *ucontrol->value.integer.value;
616 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
617 AC_VERB_GET_PIN_WIDGET_CONTROL,
618 0x00);
619
620 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
621 val = alc_pin_mode_min(dir);
622
623 change = pinctl != alc_pin_mode_values[val];
624 if (change) {
625 /* Set pin mode to that requested */
626 snd_hda_codec_write_cache(codec, nid, 0,
627 AC_VERB_SET_PIN_WIDGET_CONTROL,
628 alc_pin_mode_values[val]);
629
630 /* Also enable the retasking pin's input/output as required
631 * for the requested pin mode. Enum values of 2 or less are
632 * input modes.
633 *
634 * Dynamically switching the input/output buffers probably
635 * reduces noise slightly (particularly on input) so we'll
636 * do it. However, having both input and output buffers
637 * enabled simultaneously doesn't seem to be problematic if
638 * this turns out to be necessary in the future.
639 */
640 if (val <= 2) {
641 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
642 HDA_AMP_MUTE, HDA_AMP_MUTE);
643 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
644 HDA_AMP_MUTE, 0);
645 } else {
646 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
647 HDA_AMP_MUTE, HDA_AMP_MUTE);
648 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
649 HDA_AMP_MUTE, 0);
650 }
651 }
652 return change;
653 }
654
655 #define ALC_PIN_MODE(xname, nid, dir) \
656 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
657 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
658 .info = alc_pin_mode_info, \
659 .get = alc_pin_mode_get, \
660 .put = alc_pin_mode_put, \
661 .private_value = nid | (dir<<16) }
662
663 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
664 * together using a mask with more than one bit set. This control is
665 * currently used only by the ALC260 test model. At this stage they are not
666 * needed for any "production" models.
667 */
668 #ifdef CONFIG_SND_DEBUG
669 #define alc_gpio_data_info snd_ctl_boolean_mono_info
670
671 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
672 struct snd_ctl_elem_value *ucontrol)
673 {
674 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
675 hda_nid_t nid = kcontrol->private_value & 0xffff;
676 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
677 long *valp = ucontrol->value.integer.value;
678 unsigned int val = snd_hda_codec_read(codec, nid, 0,
679 AC_VERB_GET_GPIO_DATA, 0x00);
680
681 *valp = (val & mask) != 0;
682 return 0;
683 }
684 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
686 {
687 signed int change;
688 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
689 hda_nid_t nid = kcontrol->private_value & 0xffff;
690 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
691 long val = *ucontrol->value.integer.value;
692 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
693 AC_VERB_GET_GPIO_DATA,
694 0x00);
695
696 /* Set/unset the masked GPIO bit(s) as needed */
697 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
698 if (val == 0)
699 gpio_data &= ~mask;
700 else
701 gpio_data |= mask;
702 snd_hda_codec_write_cache(codec, nid, 0,
703 AC_VERB_SET_GPIO_DATA, gpio_data);
704
705 return change;
706 }
707 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
708 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
709 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
710 .info = alc_gpio_data_info, \
711 .get = alc_gpio_data_get, \
712 .put = alc_gpio_data_put, \
713 .private_value = nid | (mask<<16) }
714 #endif /* CONFIG_SND_DEBUG */
715
716 /* A switch control to allow the enabling of the digital IO pins on the
717 * ALC260. This is incredibly simplistic; the intention of this control is
718 * to provide something in the test model allowing digital outputs to be
719 * identified if present. If models are found which can utilise these
720 * outputs a more complete mixer control can be devised for those models if
721 * necessary.
722 */
723 #ifdef CONFIG_SND_DEBUG
724 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
725
726 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
728 {
729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730 hda_nid_t nid = kcontrol->private_value & 0xffff;
731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732 long *valp = ucontrol->value.integer.value;
733 unsigned int val = snd_hda_codec_read(codec, nid, 0,
734 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
735
736 *valp = (val & mask) != 0;
737 return 0;
738 }
739 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
741 {
742 signed int change;
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 hda_nid_t nid = kcontrol->private_value & 0xffff;
745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746 long val = *ucontrol->value.integer.value;
747 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
748 AC_VERB_GET_DIGI_CONVERT_1,
749 0x00);
750
751 /* Set/unset the masked control bit(s) as needed */
752 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
753 if (val==0)
754 ctrl_data &= ~mask;
755 else
756 ctrl_data |= mask;
757 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
758 ctrl_data);
759
760 return change;
761 }
762 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
765 .info = alc_spdif_ctrl_info, \
766 .get = alc_spdif_ctrl_get, \
767 .put = alc_spdif_ctrl_put, \
768 .private_value = nid | (mask<<16) }
769 #endif /* CONFIG_SND_DEBUG */
770
771 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
772 * Again, this is only used in the ALC26x test models to help identify when
773 * the EAPD line must be asserted for features to work.
774 */
775 #ifdef CONFIG_SND_DEBUG
776 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
777
778 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
779 struct snd_ctl_elem_value *ucontrol)
780 {
781 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
782 hda_nid_t nid = kcontrol->private_value & 0xffff;
783 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
784 long *valp = ucontrol->value.integer.value;
785 unsigned int val = snd_hda_codec_read(codec, nid, 0,
786 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
787
788 *valp = (val & mask) != 0;
789 return 0;
790 }
791
792 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794 {
795 int change;
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long val = *ucontrol->value.integer.value;
800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_EAPD_BTLENABLE,
802 0x00);
803
804 /* Set/unset the masked control bit(s) as needed */
805 change = (!val ? 0 : mask) != (ctrl_data & mask);
806 if (!val)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
811 ctrl_data);
812
813 return change;
814 }
815
816 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
819 .info = alc_eapd_ctrl_info, \
820 .get = alc_eapd_ctrl_get, \
821 .put = alc_eapd_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823 #endif /* CONFIG_SND_DEBUG */
824
825 /*
826 * set up the input pin config (depending on the given auto-pin type)
827 */
828 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
829 int auto_pin_type)
830 {
831 unsigned int val = PIN_IN;
832
833 if (auto_pin_type <= AUTO_PIN_FRONT_MIC) {
834 unsigned int pincap;
835 pincap = snd_hda_query_pin_caps(codec, nid);
836 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
837 if (pincap & AC_PINCAP_VREF_80)
838 val = PIN_VREF80;
839 else if (pincap & AC_PINCAP_VREF_50)
840 val = PIN_VREF50;
841 else if (pincap & AC_PINCAP_VREF_100)
842 val = PIN_VREF100;
843 else if (pincap & AC_PINCAP_VREF_GRD)
844 val = PIN_VREFGRD;
845 }
846 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
847 }
848
849 /*
850 */
851 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
852 {
853 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
854 return;
855 spec->mixers[spec->num_mixers++] = mix;
856 }
857
858 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
859 {
860 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
861 return;
862 spec->init_verbs[spec->num_init_verbs++] = verb;
863 }
864
865 /*
866 * set up from the preset table
867 */
868 static void setup_preset(struct hda_codec *codec,
869 const struct alc_config_preset *preset)
870 {
871 struct alc_spec *spec = codec->spec;
872 int i;
873
874 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
875 add_mixer(spec, preset->mixers[i]);
876 spec->cap_mixer = preset->cap_mixer;
877 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
878 i++)
879 add_verb(spec, preset->init_verbs[i]);
880
881 spec->channel_mode = preset->channel_mode;
882 spec->num_channel_mode = preset->num_channel_mode;
883 spec->need_dac_fix = preset->need_dac_fix;
884 spec->const_channel_count = preset->const_channel_count;
885
886 if (preset->const_channel_count)
887 spec->multiout.max_channels = preset->const_channel_count;
888 else
889 spec->multiout.max_channels = spec->channel_mode[0].channels;
890 spec->ext_channel_count = spec->channel_mode[0].channels;
891
892 spec->multiout.num_dacs = preset->num_dacs;
893 spec->multiout.dac_nids = preset->dac_nids;
894 spec->multiout.dig_out_nid = preset->dig_out_nid;
895 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
896 spec->multiout.hp_nid = preset->hp_nid;
897
898 spec->num_mux_defs = preset->num_mux_defs;
899 if (!spec->num_mux_defs)
900 spec->num_mux_defs = 1;
901 spec->input_mux = preset->input_mux;
902
903 spec->num_adc_nids = preset->num_adc_nids;
904 spec->adc_nids = preset->adc_nids;
905 spec->capsrc_nids = preset->capsrc_nids;
906 spec->dig_in_nid = preset->dig_in_nid;
907
908 spec->unsol_event = preset->unsol_event;
909 spec->init_hook = preset->init_hook;
910 #ifdef CONFIG_SND_HDA_POWER_SAVE
911 spec->power_hook = preset->power_hook;
912 spec->loopback.amplist = preset->loopbacks;
913 #endif
914
915 if (preset->setup)
916 preset->setup(codec);
917 }
918
919 /* Enable GPIO mask and set output */
920 static struct hda_verb alc_gpio1_init_verbs[] = {
921 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
922 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
923 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
924 { }
925 };
926
927 static struct hda_verb alc_gpio2_init_verbs[] = {
928 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
929 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
930 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
931 { }
932 };
933
934 static struct hda_verb alc_gpio3_init_verbs[] = {
935 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
937 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
938 { }
939 };
940
941 /*
942 * Fix hardware PLL issue
943 * On some codecs, the analog PLL gating control must be off while
944 * the default value is 1.
945 */
946 static void alc_fix_pll(struct hda_codec *codec)
947 {
948 struct alc_spec *spec = codec->spec;
949 unsigned int val;
950
951 if (!spec->pll_nid)
952 return;
953 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
954 spec->pll_coef_idx);
955 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
956 AC_VERB_GET_PROC_COEF, 0);
957 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
958 spec->pll_coef_idx);
959 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
960 val & ~(1 << spec->pll_coef_bit));
961 }
962
963 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
964 unsigned int coef_idx, unsigned int coef_bit)
965 {
966 struct alc_spec *spec = codec->spec;
967 spec->pll_nid = nid;
968 spec->pll_coef_idx = coef_idx;
969 spec->pll_coef_bit = coef_bit;
970 alc_fix_pll(codec);
971 }
972
973 static void alc_automute_pin(struct hda_codec *codec)
974 {
975 struct alc_spec *spec = codec->spec;
976 unsigned int nid = spec->autocfg.hp_pins[0];
977 int i;
978
979 if (!nid)
980 return;
981 spec->jack_present = snd_hda_jack_detect(codec, nid);
982 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
983 nid = spec->autocfg.speaker_pins[i];
984 if (!nid)
985 break;
986 snd_hda_codec_write(codec, nid, 0,
987 AC_VERB_SET_PIN_WIDGET_CONTROL,
988 spec->jack_present ? 0 : PIN_OUT);
989 }
990 }
991
992 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
993 hda_nid_t nid)
994 {
995 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
996 int i, nums;
997
998 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
999 for (i = 0; i < nums; i++)
1000 if (conn[i] == nid)
1001 return i;
1002 return -1;
1003 }
1004
1005 static void alc_mic_automute(struct hda_codec *codec)
1006 {
1007 struct alc_spec *spec = codec->spec;
1008 struct alc_mic_route *dead, *alive;
1009 unsigned int present, type;
1010 hda_nid_t cap_nid;
1011
1012 if (!spec->auto_mic)
1013 return;
1014 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1015 return;
1016 if (snd_BUG_ON(!spec->adc_nids))
1017 return;
1018
1019 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1020
1021 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1022 if (present) {
1023 alive = &spec->ext_mic;
1024 dead = &spec->int_mic;
1025 } else {
1026 alive = &spec->int_mic;
1027 dead = &spec->ext_mic;
1028 }
1029
1030 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1031 if (type == AC_WID_AUD_MIX) {
1032 /* Matrix-mixer style (e.g. ALC882) */
1033 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1034 alive->mux_idx,
1035 HDA_AMP_MUTE, 0);
1036 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1037 dead->mux_idx,
1038 HDA_AMP_MUTE, HDA_AMP_MUTE);
1039 } else {
1040 /* MUX style (e.g. ALC880) */
1041 snd_hda_codec_write_cache(codec, cap_nid, 0,
1042 AC_VERB_SET_CONNECT_SEL,
1043 alive->mux_idx);
1044 }
1045
1046 /* FIXME: analog mixer */
1047 }
1048
1049 /* unsolicited event for HP jack sensing */
1050 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1051 {
1052 if (codec->vendor_id == 0x10ec0880)
1053 res >>= 28;
1054 else
1055 res >>= 26;
1056 switch (res) {
1057 case ALC880_HP_EVENT:
1058 alc_automute_pin(codec);
1059 break;
1060 case ALC880_MIC_EVENT:
1061 alc_mic_automute(codec);
1062 break;
1063 }
1064 }
1065
1066 static void alc_inithook(struct hda_codec *codec)
1067 {
1068 alc_automute_pin(codec);
1069 alc_mic_automute(codec);
1070 }
1071
1072 /* additional initialization for ALC888 variants */
1073 static void alc888_coef_init(struct hda_codec *codec)
1074 {
1075 unsigned int tmp;
1076
1077 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1078 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1079 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1080 if ((tmp & 0xf0) == 0x20)
1081 /* alc888S-VC */
1082 snd_hda_codec_read(codec, 0x20, 0,
1083 AC_VERB_SET_PROC_COEF, 0x830);
1084 else
1085 /* alc888-VB */
1086 snd_hda_codec_read(codec, 0x20, 0,
1087 AC_VERB_SET_PROC_COEF, 0x3030);
1088 }
1089
1090 static void alc889_coef_init(struct hda_codec *codec)
1091 {
1092 unsigned int tmp;
1093
1094 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1095 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1096 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1098 }
1099
1100 /* turn on/off EAPD control (only if available) */
1101 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1102 {
1103 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1104 return;
1105 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1106 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1107 on ? 2 : 0);
1108 }
1109
1110 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1111 {
1112 unsigned int tmp;
1113
1114 switch (type) {
1115 case ALC_INIT_GPIO1:
1116 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1117 break;
1118 case ALC_INIT_GPIO2:
1119 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1120 break;
1121 case ALC_INIT_GPIO3:
1122 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1123 break;
1124 case ALC_INIT_DEFAULT:
1125 switch (codec->vendor_id) {
1126 case 0x10ec0260:
1127 set_eapd(codec, 0x0f, 1);
1128 set_eapd(codec, 0x10, 1);
1129 break;
1130 case 0x10ec0262:
1131 case 0x10ec0267:
1132 case 0x10ec0268:
1133 case 0x10ec0269:
1134 case 0x10ec0270:
1135 case 0x10ec0272:
1136 case 0x10ec0660:
1137 case 0x10ec0662:
1138 case 0x10ec0663:
1139 case 0x10ec0862:
1140 case 0x10ec0889:
1141 set_eapd(codec, 0x14, 1);
1142 set_eapd(codec, 0x15, 1);
1143 break;
1144 }
1145 switch (codec->vendor_id) {
1146 case 0x10ec0260:
1147 snd_hda_codec_write(codec, 0x1a, 0,
1148 AC_VERB_SET_COEF_INDEX, 7);
1149 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1150 AC_VERB_GET_PROC_COEF, 0);
1151 snd_hda_codec_write(codec, 0x1a, 0,
1152 AC_VERB_SET_COEF_INDEX, 7);
1153 snd_hda_codec_write(codec, 0x1a, 0,
1154 AC_VERB_SET_PROC_COEF,
1155 tmp | 0x2010);
1156 break;
1157 case 0x10ec0262:
1158 case 0x10ec0880:
1159 case 0x10ec0882:
1160 case 0x10ec0883:
1161 case 0x10ec0885:
1162 case 0x10ec0887:
1163 case 0x10ec0889:
1164 alc889_coef_init(codec);
1165 break;
1166 case 0x10ec0888:
1167 alc888_coef_init(codec);
1168 break;
1169 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1170 case 0x10ec0267:
1171 case 0x10ec0268:
1172 snd_hda_codec_write(codec, 0x20, 0,
1173 AC_VERB_SET_COEF_INDEX, 7);
1174 tmp = snd_hda_codec_read(codec, 0x20, 0,
1175 AC_VERB_GET_PROC_COEF, 0);
1176 snd_hda_codec_write(codec, 0x20, 0,
1177 AC_VERB_SET_COEF_INDEX, 7);
1178 snd_hda_codec_write(codec, 0x20, 0,
1179 AC_VERB_SET_PROC_COEF,
1180 tmp | 0x3000);
1181 break;
1182 #endif /* XXX */
1183 }
1184 break;
1185 }
1186 }
1187
1188 static void alc_init_auto_hp(struct hda_codec *codec)
1189 {
1190 struct alc_spec *spec = codec->spec;
1191
1192 if (!spec->autocfg.hp_pins[0])
1193 return;
1194
1195 if (!spec->autocfg.speaker_pins[0]) {
1196 if (spec->autocfg.line_out_pins[0] &&
1197 spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
1198 spec->autocfg.speaker_pins[0] =
1199 spec->autocfg.line_out_pins[0];
1200 else
1201 return;
1202 }
1203
1204 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1205 spec->autocfg.hp_pins[0]);
1206 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1207 AC_VERB_SET_UNSOLICITED_ENABLE,
1208 AC_USRSP_EN | ALC880_HP_EVENT);
1209 spec->unsol_event = alc_sku_unsol_event;
1210 }
1211
1212 static void alc_init_auto_mic(struct hda_codec *codec)
1213 {
1214 struct alc_spec *spec = codec->spec;
1215 struct auto_pin_cfg *cfg = &spec->autocfg;
1216 hda_nid_t fixed, ext;
1217 int i;
1218
1219 /* there must be only two mic inputs exclusively */
1220 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1221 if (cfg->input_pins[i])
1222 return;
1223
1224 fixed = ext = 0;
1225 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1226 hda_nid_t nid = cfg->input_pins[i];
1227 unsigned int defcfg;
1228 if (!nid)
1229 return;
1230 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1231 switch (get_defcfg_connect(defcfg)) {
1232 case AC_JACK_PORT_FIXED:
1233 if (fixed)
1234 return; /* already occupied */
1235 fixed = nid;
1236 break;
1237 case AC_JACK_PORT_COMPLEX:
1238 if (ext)
1239 return; /* already occupied */
1240 ext = nid;
1241 break;
1242 default:
1243 return; /* invalid entry */
1244 }
1245 }
1246 if (!ext || !fixed)
1247 return;
1248 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1249 return; /* no unsol support */
1250 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1251 ext, fixed);
1252 spec->ext_mic.pin = ext;
1253 spec->int_mic.pin = fixed;
1254 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1255 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1256 spec->auto_mic = 1;
1257 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1258 AC_VERB_SET_UNSOLICITED_ENABLE,
1259 AC_USRSP_EN | ALC880_MIC_EVENT);
1260 spec->unsol_event = alc_sku_unsol_event;
1261 }
1262
1263 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1264 {
1265 unsigned int ass, tmp, i;
1266 unsigned nid = 0;
1267 struct alc_spec *spec = codec->spec;
1268
1269 ass = codec->subsystem_id & 0xffff;
1270 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1271 goto do_sku;
1272
1273 nid = 0x1d;
1274 if (codec->vendor_id == 0x10ec0260)
1275 nid = 0x17;
1276 ass = snd_hda_codec_get_pincfg(codec, nid);
1277
1278 if (!(ass & 1)) {
1279 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1280 codec->chip_name, ass);
1281 return -1;
1282 }
1283
1284 /* check sum */
1285 tmp = 0;
1286 for (i = 1; i < 16; i++) {
1287 if ((ass >> i) & 1)
1288 tmp++;
1289 }
1290 if (((ass >> 16) & 0xf) != tmp)
1291 return -1;
1292
1293 spec->cdefine.port_connectivity = ass >> 30;
1294 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1295 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1296 spec->cdefine.customization = ass >> 8;
1297 do_sku:
1298 spec->cdefine.sku_cfg = ass;
1299 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1300 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1301 spec->cdefine.swap = (ass & 0x2) >> 1;
1302 spec->cdefine.override = ass & 0x1;
1303
1304 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1305 nid, spec->cdefine.sku_cfg);
1306 snd_printd("SKU: port_connectivity=0x%x\n",
1307 spec->cdefine.port_connectivity);
1308 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1309 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1310 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1311 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1312 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1313 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1314 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1315
1316 return 0;
1317 }
1318
1319 /* check subsystem ID and set up device-specific initialization;
1320 * return 1 if initialized, 0 if invalid SSID
1321 */
1322 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1323 * 31 ~ 16 : Manufacture ID
1324 * 15 ~ 8 : SKU ID
1325 * 7 ~ 0 : Assembly ID
1326 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1327 */
1328 static int alc_subsystem_id(struct hda_codec *codec,
1329 hda_nid_t porta, hda_nid_t porte,
1330 hda_nid_t portd, hda_nid_t porti)
1331 {
1332 unsigned int ass, tmp, i;
1333 unsigned nid;
1334 struct alc_spec *spec = codec->spec;
1335
1336 ass = codec->subsystem_id & 0xffff;
1337 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1338 goto do_sku;
1339
1340 /* invalid SSID, check the special NID pin defcfg instead */
1341 /*
1342 * 31~30 : port connectivity
1343 * 29~21 : reserve
1344 * 20 : PCBEEP input
1345 * 19~16 : Check sum (15:1)
1346 * 15~1 : Custom
1347 * 0 : override
1348 */
1349 nid = 0x1d;
1350 if (codec->vendor_id == 0x10ec0260)
1351 nid = 0x17;
1352 ass = snd_hda_codec_get_pincfg(codec, nid);
1353 snd_printd("realtek: No valid SSID, "
1354 "checking pincfg 0x%08x for NID 0x%x\n",
1355 ass, nid);
1356 if (!(ass & 1))
1357 return 0;
1358 if ((ass >> 30) != 1) /* no physical connection */
1359 return 0;
1360
1361 /* check sum */
1362 tmp = 0;
1363 for (i = 1; i < 16; i++) {
1364 if ((ass >> i) & 1)
1365 tmp++;
1366 }
1367 if (((ass >> 16) & 0xf) != tmp)
1368 return 0;
1369 do_sku:
1370 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1371 ass & 0xffff, codec->vendor_id);
1372 /*
1373 * 0 : override
1374 * 1 : Swap Jack
1375 * 2 : 0 --> Desktop, 1 --> Laptop
1376 * 3~5 : External Amplifier control
1377 * 7~6 : Reserved
1378 */
1379 tmp = (ass & 0x38) >> 3; /* external Amp control */
1380 switch (tmp) {
1381 case 1:
1382 spec->init_amp = ALC_INIT_GPIO1;
1383 break;
1384 case 3:
1385 spec->init_amp = ALC_INIT_GPIO2;
1386 break;
1387 case 7:
1388 spec->init_amp = ALC_INIT_GPIO3;
1389 break;
1390 case 5:
1391 spec->init_amp = ALC_INIT_DEFAULT;
1392 break;
1393 }
1394
1395 /* is laptop or Desktop and enable the function "Mute internal speaker
1396 * when the external headphone out jack is plugged"
1397 */
1398 if (!(ass & 0x8000))
1399 return 1;
1400 /*
1401 * 10~8 : Jack location
1402 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1403 * 14~13: Resvered
1404 * 15 : 1 --> enable the function "Mute internal speaker
1405 * when the external headphone out jack is plugged"
1406 */
1407 if (!spec->autocfg.hp_pins[0]) {
1408 hda_nid_t nid;
1409 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1410 if (tmp == 0)
1411 nid = porta;
1412 else if (tmp == 1)
1413 nid = porte;
1414 else if (tmp == 2)
1415 nid = portd;
1416 else if (tmp == 3)
1417 nid = porti;
1418 else
1419 return 1;
1420 for (i = 0; i < spec->autocfg.line_outs; i++)
1421 if (spec->autocfg.line_out_pins[i] == nid)
1422 return 1;
1423 spec->autocfg.hp_pins[0] = nid;
1424 }
1425
1426 alc_init_auto_hp(codec);
1427 alc_init_auto_mic(codec);
1428 return 1;
1429 }
1430
1431 static void alc_ssid_check(struct hda_codec *codec,
1432 hda_nid_t porta, hda_nid_t porte,
1433 hda_nid_t portd, hda_nid_t porti)
1434 {
1435 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1436 struct alc_spec *spec = codec->spec;
1437 snd_printd("realtek: "
1438 "Enable default setup for auto mode as fallback\n");
1439 spec->init_amp = ALC_INIT_DEFAULT;
1440 alc_init_auto_hp(codec);
1441 alc_init_auto_mic(codec);
1442 }
1443 }
1444
1445 /*
1446 * Fix-up pin default configurations and add default verbs
1447 */
1448
1449 struct alc_pincfg {
1450 hda_nid_t nid;
1451 u32 val;
1452 };
1453
1454 struct alc_fixup {
1455 const struct alc_pincfg *pins;
1456 const struct hda_verb *verbs;
1457 };
1458
1459 static void alc_pick_fixup(struct hda_codec *codec,
1460 const struct snd_pci_quirk *quirk,
1461 const struct alc_fixup *fix)
1462 {
1463 const struct alc_pincfg *cfg;
1464
1465 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1466 if (!quirk)
1467 return;
1468
1469 fix += quirk->value;
1470 cfg = fix->pins;
1471 if (cfg) {
1472 for (; cfg->nid; cfg++)
1473 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1474 }
1475 if (fix->verbs)
1476 add_verb(codec->spec, fix->verbs);
1477 }
1478
1479 static int alc_read_coef_idx(struct hda_codec *codec,
1480 unsigned int coef_idx)
1481 {
1482 unsigned int val;
1483 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1484 coef_idx);
1485 val = snd_hda_codec_read(codec, 0x20, 0,
1486 AC_VERB_GET_PROC_COEF, 0);
1487 return val;
1488 }
1489
1490 /*
1491 * ALC888
1492 */
1493
1494 /*
1495 * 2ch mode
1496 */
1497 static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1498 /* Mic-in jack as mic in */
1499 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1500 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1501 /* Line-in jack as Line in */
1502 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1503 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1504 /* Line-Out as Front */
1505 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1506 { } /* end */
1507 };
1508
1509 /*
1510 * 4ch mode
1511 */
1512 static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1513 /* Mic-in jack as mic in */
1514 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1515 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1516 /* Line-in jack as Surround */
1517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1518 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1519 /* Line-Out as Front */
1520 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1521 { } /* end */
1522 };
1523
1524 /*
1525 * 6ch mode
1526 */
1527 static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1528 /* Mic-in jack as CLFE */
1529 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1530 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1531 /* Line-in jack as Surround */
1532 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1533 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1534 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1535 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1536 { } /* end */
1537 };
1538
1539 /*
1540 * 8ch mode
1541 */
1542 static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1543 /* Mic-in jack as CLFE */
1544 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1545 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1546 /* Line-in jack as Surround */
1547 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1548 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1549 /* Line-Out as Side */
1550 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1551 { } /* end */
1552 };
1553
1554 static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1555 { 2, alc888_4ST_ch2_intel_init },
1556 { 4, alc888_4ST_ch4_intel_init },
1557 { 6, alc888_4ST_ch6_intel_init },
1558 { 8, alc888_4ST_ch8_intel_init },
1559 };
1560
1561 /*
1562 * ALC888 Fujitsu Siemens Amillo xa3530
1563 */
1564
1565 static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1566 /* Front Mic: set to PIN_IN (empty by default) */
1567 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1568 /* Connect Internal HP to Front */
1569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1570 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1571 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1572 /* Connect Bass HP to Front */
1573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1575 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1576 /* Connect Line-Out side jack (SPDIF) to Side */
1577 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1578 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1579 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1580 /* Connect Mic jack to CLFE */
1581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1583 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1584 /* Connect Line-in jack to Surround */
1585 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1586 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1587 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1588 /* Connect HP out jack to Front */
1589 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1590 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1591 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1592 /* Enable unsolicited event for HP jack and Line-out jack */
1593 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1594 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1595 {}
1596 };
1597
1598 static void alc_automute_amp(struct hda_codec *codec)
1599 {
1600 struct alc_spec *spec = codec->spec;
1601 unsigned int mute;
1602 hda_nid_t nid;
1603 int i;
1604
1605 spec->jack_present = 0;
1606 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
1607 nid = spec->autocfg.hp_pins[i];
1608 if (!nid)
1609 break;
1610 if (snd_hda_jack_detect(codec, nid)) {
1611 spec->jack_present = 1;
1612 break;
1613 }
1614 }
1615
1616 mute = spec->jack_present ? HDA_AMP_MUTE : 0;
1617 /* Toggle internal speakers muting */
1618 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
1619 nid = spec->autocfg.speaker_pins[i];
1620 if (!nid)
1621 break;
1622 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1623 HDA_AMP_MUTE, mute);
1624 }
1625 }
1626
1627 static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1628 unsigned int res)
1629 {
1630 if (codec->vendor_id == 0x10ec0880)
1631 res >>= 28;
1632 else
1633 res >>= 26;
1634 if (res == ALC880_HP_EVENT)
1635 alc_automute_amp(codec);
1636 }
1637
1638 static void alc889_automute_setup(struct hda_codec *codec)
1639 {
1640 struct alc_spec *spec = codec->spec;
1641
1642 spec->autocfg.hp_pins[0] = 0x15;
1643 spec->autocfg.speaker_pins[0] = 0x14;
1644 spec->autocfg.speaker_pins[1] = 0x16;
1645 spec->autocfg.speaker_pins[2] = 0x17;
1646 spec->autocfg.speaker_pins[3] = 0x19;
1647 spec->autocfg.speaker_pins[4] = 0x1a;
1648 }
1649
1650 static void alc889_intel_init_hook(struct hda_codec *codec)
1651 {
1652 alc889_coef_init(codec);
1653 alc_automute_amp(codec);
1654 }
1655
1656 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1657 {
1658 struct alc_spec *spec = codec->spec;
1659
1660 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
1661 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1662 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1663 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1664 }
1665
1666 /*
1667 * ALC888 Acer Aspire 4930G model
1668 */
1669
1670 static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1671 /* Front Mic: set to PIN_IN (empty by default) */
1672 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1673 /* Unselect Front Mic by default in input mixer 3 */
1674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1675 /* Enable unsolicited event for HP jack */
1676 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1677 /* Connect Internal HP to front */
1678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1680 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1681 /* Connect HP out to front */
1682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1683 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1684 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1685 { }
1686 };
1687
1688 /*
1689 * ALC888 Acer Aspire 6530G model
1690 */
1691
1692 static struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
1693 /* Route to built-in subwoofer as well as speakers */
1694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1695 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1698 /* Bias voltage on for external mic port */
1699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
1700 /* Front Mic: set to PIN_IN (empty by default) */
1701 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1702 /* Unselect Front Mic by default in input mixer 3 */
1703 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1704 /* Enable unsolicited event for HP jack */
1705 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1706 /* Enable speaker output */
1707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1709 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1710 /* Enable headphone output */
1711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1713 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1714 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1715 { }
1716 };
1717
1718 /*
1719 * ALC889 Acer Aspire 8930G model
1720 */
1721
1722 static struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
1723 /* Front Mic: set to PIN_IN (empty by default) */
1724 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1725 /* Unselect Front Mic by default in input mixer 3 */
1726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1727 /* Enable unsolicited event for HP jack */
1728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1729 /* Connect Internal Front to Front */
1730 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1731 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1732 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1733 /* Connect Internal Rear to Rear */
1734 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1735 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1736 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
1737 /* Connect Internal CLFE to CLFE */
1738 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1739 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1740 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1741 /* Connect HP out to Front */
1742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
1743 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1744 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1745 /* Enable all DACs */
1746 /* DAC DISABLE/MUTE 1? */
1747 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
1748 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
1749 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1750 /* DAC DISABLE/MUTE 2? */
1751 /* some bit here disables the other DACs. Init=0x4900 */
1752 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
1753 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
1754 /* DMIC fix
1755 * This laptop has a stereo digital microphone. The mics are only 1cm apart
1756 * which makes the stereo useless. However, either the mic or the ALC889
1757 * makes the signal become a difference/sum signal instead of standard
1758 * stereo, which is annoying. So instead we flip this bit which makes the
1759 * codec replicate the sum signal to both channels, turning it into a
1760 * normal mono mic.
1761 */
1762 /* DMIC_CONTROL? Init value = 0x0001 */
1763 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
1764 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
1765 { }
1766 };
1767
1768 static struct hda_input_mux alc888_2_capture_sources[2] = {
1769 /* Front mic only available on one ADC */
1770 {
1771 .num_items = 4,
1772 .items = {
1773 { "Mic", 0x0 },
1774 { "Line", 0x2 },
1775 { "CD", 0x4 },
1776 { "Front Mic", 0xb },
1777 },
1778 },
1779 {
1780 .num_items = 3,
1781 .items = {
1782 { "Mic", 0x0 },
1783 { "Line", 0x2 },
1784 { "CD", 0x4 },
1785 },
1786 }
1787 };
1788
1789 static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
1790 /* Interal mic only available on one ADC */
1791 {
1792 .num_items = 5,
1793 .items = {
1794 { "Ext Mic", 0x0 },
1795 { "Line In", 0x2 },
1796 { "CD", 0x4 },
1797 { "Input Mix", 0xa },
1798 { "Int Mic", 0xb },
1799 },
1800 },
1801 {
1802 .num_items = 4,
1803 .items = {
1804 { "Ext Mic", 0x0 },
1805 { "Line In", 0x2 },
1806 { "CD", 0x4 },
1807 { "Input Mix", 0xa },
1808 },
1809 }
1810 };
1811
1812 static struct hda_input_mux alc889_capture_sources[3] = {
1813 /* Digital mic only available on first "ADC" */
1814 {
1815 .num_items = 5,
1816 .items = {
1817 { "Mic", 0x0 },
1818 { "Line", 0x2 },
1819 { "CD", 0x4 },
1820 { "Front Mic", 0xb },
1821 { "Input Mix", 0xa },
1822 },
1823 },
1824 {
1825 .num_items = 4,
1826 .items = {
1827 { "Mic", 0x0 },
1828 { "Line", 0x2 },
1829 { "CD", 0x4 },
1830 { "Input Mix", 0xa },
1831 },
1832 },
1833 {
1834 .num_items = 4,
1835 .items = {
1836 { "Mic", 0x0 },
1837 { "Line", 0x2 },
1838 { "CD", 0x4 },
1839 { "Input Mix", 0xa },
1840 },
1841 }
1842 };
1843
1844 static struct snd_kcontrol_new alc888_base_mixer[] = {
1845 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1846 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1847 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1848 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1849 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1850 HDA_OUTPUT),
1851 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1852 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1853 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1854 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1855 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1856 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1857 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1858 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1859 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1861 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1863 { } /* end */
1864 };
1865
1866 static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
1867 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1868 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1869 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1870 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1871 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1872 HDA_OUTPUT),
1873 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1874 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1875 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1876 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1877 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1879 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1881 { } /* end */
1882 };
1883
1884
1885 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1886 {
1887 struct alc_spec *spec = codec->spec;
1888
1889 spec->autocfg.hp_pins[0] = 0x15;
1890 spec->autocfg.speaker_pins[0] = 0x14;
1891 spec->autocfg.speaker_pins[1] = 0x16;
1892 spec->autocfg.speaker_pins[2] = 0x17;
1893 }
1894
1895 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1896 {
1897 struct alc_spec *spec = codec->spec;
1898
1899 spec->autocfg.hp_pins[0] = 0x15;
1900 spec->autocfg.speaker_pins[0] = 0x14;
1901 spec->autocfg.speaker_pins[1] = 0x16;
1902 spec->autocfg.speaker_pins[2] = 0x17;
1903 }
1904
1905 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1906 {
1907 struct alc_spec *spec = codec->spec;
1908
1909 spec->autocfg.hp_pins[0] = 0x15;
1910 spec->autocfg.speaker_pins[0] = 0x14;
1911 spec->autocfg.speaker_pins[1] = 0x16;
1912 spec->autocfg.speaker_pins[2] = 0x1b;
1913 }
1914
1915 /*
1916 * ALC880 3-stack model
1917 *
1918 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1919 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1920 * F-Mic = 0x1b, HP = 0x19
1921 */
1922
1923 static hda_nid_t alc880_dac_nids[4] = {
1924 /* front, rear, clfe, rear_surr */
1925 0x02, 0x05, 0x04, 0x03
1926 };
1927
1928 static hda_nid_t alc880_adc_nids[3] = {
1929 /* ADC0-2 */
1930 0x07, 0x08, 0x09,
1931 };
1932
1933 /* The datasheet says the node 0x07 is connected from inputs,
1934 * but it shows zero connection in the real implementation on some devices.
1935 * Note: this is a 915GAV bug, fixed on 915GLV
1936 */
1937 static hda_nid_t alc880_adc_nids_alt[2] = {
1938 /* ADC1-2 */
1939 0x08, 0x09,
1940 };
1941
1942 #define ALC880_DIGOUT_NID 0x06
1943 #define ALC880_DIGIN_NID 0x0a
1944
1945 static struct hda_input_mux alc880_capture_source = {
1946 .num_items = 4,
1947 .items = {
1948 { "Mic", 0x0 },
1949 { "Front Mic", 0x3 },
1950 { "Line", 0x2 },
1951 { "CD", 0x4 },
1952 },
1953 };
1954
1955 /* channel source setting (2/6 channel selection for 3-stack) */
1956 /* 2ch mode */
1957 static struct hda_verb alc880_threestack_ch2_init[] = {
1958 /* set line-in to input, mute it */
1959 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1960 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1961 /* set mic-in to input vref 80%, mute it */
1962 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1963 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1964 { } /* end */
1965 };
1966
1967 /* 6ch mode */
1968 static struct hda_verb alc880_threestack_ch6_init[] = {
1969 /* set line-in to output, unmute it */
1970 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1971 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1972 /* set mic-in to output, unmute it */
1973 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1974 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1975 { } /* end */
1976 };
1977
1978 static struct hda_channel_mode alc880_threestack_modes[2] = {
1979 { 2, alc880_threestack_ch2_init },
1980 { 6, alc880_threestack_ch6_init },
1981 };
1982
1983 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1984 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1985 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1986 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1987 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1988 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1989 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1990 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1991 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1996 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2001 {
2002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2003 .name = "Channel Mode",
2004 .info = alc_ch_mode_info,
2005 .get = alc_ch_mode_get,
2006 .put = alc_ch_mode_put,
2007 },
2008 { } /* end */
2009 };
2010
2011 /* capture mixer elements */
2012 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2013 struct snd_ctl_elem_info *uinfo)
2014 {
2015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2016 struct alc_spec *spec = codec->spec;
2017 int err;
2018
2019 mutex_lock(&codec->control_mutex);
2020 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2021 HDA_INPUT);
2022 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2023 mutex_unlock(&codec->control_mutex);
2024 return err;
2025 }
2026
2027 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2028 unsigned int size, unsigned int __user *tlv)
2029 {
2030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2031 struct alc_spec *spec = codec->spec;
2032 int err;
2033
2034 mutex_lock(&codec->control_mutex);
2035 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2036 HDA_INPUT);
2037 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2038 mutex_unlock(&codec->control_mutex);
2039 return err;
2040 }
2041
2042 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2043 struct snd_ctl_elem_value *ucontrol);
2044
2045 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2046 struct snd_ctl_elem_value *ucontrol,
2047 getput_call_t func)
2048 {
2049 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2050 struct alc_spec *spec = codec->spec;
2051 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2052 int err;
2053
2054 mutex_lock(&codec->control_mutex);
2055 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2056 3, 0, HDA_INPUT);
2057 err = func(kcontrol, ucontrol);
2058 mutex_unlock(&codec->control_mutex);
2059 return err;
2060 }
2061
2062 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2063 struct snd_ctl_elem_value *ucontrol)
2064 {
2065 return alc_cap_getput_caller(kcontrol, ucontrol,
2066 snd_hda_mixer_amp_volume_get);
2067 }
2068
2069 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2070 struct snd_ctl_elem_value *ucontrol)
2071 {
2072 return alc_cap_getput_caller(kcontrol, ucontrol,
2073 snd_hda_mixer_amp_volume_put);
2074 }
2075
2076 /* capture mixer elements */
2077 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2078
2079 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2080 struct snd_ctl_elem_value *ucontrol)
2081 {
2082 return alc_cap_getput_caller(kcontrol, ucontrol,
2083 snd_hda_mixer_amp_switch_get);
2084 }
2085
2086 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2087 struct snd_ctl_elem_value *ucontrol)
2088 {
2089 return alc_cap_getput_caller(kcontrol, ucontrol,
2090 snd_hda_mixer_amp_switch_put);
2091 }
2092
2093 #define _DEFINE_CAPMIX(num) \
2094 { \
2095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2096 .name = "Capture Switch", \
2097 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2098 .count = num, \
2099 .info = alc_cap_sw_info, \
2100 .get = alc_cap_sw_get, \
2101 .put = alc_cap_sw_put, \
2102 }, \
2103 { \
2104 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2105 .name = "Capture Volume", \
2106 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2107 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2108 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2109 .count = num, \
2110 .info = alc_cap_vol_info, \
2111 .get = alc_cap_vol_get, \
2112 .put = alc_cap_vol_put, \
2113 .tlv = { .c = alc_cap_vol_tlv }, \
2114 }
2115
2116 #define _DEFINE_CAPSRC(num) \
2117 { \
2118 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2119 /* .name = "Capture Source", */ \
2120 .name = "Input Source", \
2121 .count = num, \
2122 .info = alc_mux_enum_info, \
2123 .get = alc_mux_enum_get, \
2124 .put = alc_mux_enum_put, \
2125 }
2126
2127 #define DEFINE_CAPMIX(num) \
2128 static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2129 _DEFINE_CAPMIX(num), \
2130 _DEFINE_CAPSRC(num), \
2131 { } /* end */ \
2132 }
2133
2134 #define DEFINE_CAPMIX_NOSRC(num) \
2135 static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2136 _DEFINE_CAPMIX(num), \
2137 { } /* end */ \
2138 }
2139
2140 /* up to three ADCs */
2141 DEFINE_CAPMIX(1);
2142 DEFINE_CAPMIX(2);
2143 DEFINE_CAPMIX(3);
2144 DEFINE_CAPMIX_NOSRC(1);
2145 DEFINE_CAPMIX_NOSRC(2);
2146 DEFINE_CAPMIX_NOSRC(3);
2147
2148 /*
2149 * ALC880 5-stack model
2150 *
2151 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2152 * Side = 0x02 (0xd)
2153 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2154 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2155 */
2156
2157 /* additional mixers to alc880_three_stack_mixer */
2158 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2159 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2160 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2161 { } /* end */
2162 };
2163
2164 /* channel source setting (6/8 channel selection for 5-stack) */
2165 /* 6ch mode */
2166 static struct hda_verb alc880_fivestack_ch6_init[] = {
2167 /* set line-in to input, mute it */
2168 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2169 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2170 { } /* end */
2171 };
2172
2173 /* 8ch mode */
2174 static struct hda_verb alc880_fivestack_ch8_init[] = {
2175 /* set line-in to output, unmute it */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178 { } /* end */
2179 };
2180
2181 static struct hda_channel_mode alc880_fivestack_modes[2] = {
2182 { 6, alc880_fivestack_ch6_init },
2183 { 8, alc880_fivestack_ch8_init },
2184 };
2185
2186
2187 /*
2188 * ALC880 6-stack model
2189 *
2190 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2191 * Side = 0x05 (0x0f)
2192 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2193 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2194 */
2195
2196 static hda_nid_t alc880_6st_dac_nids[4] = {
2197 /* front, rear, clfe, rear_surr */
2198 0x02, 0x03, 0x04, 0x05
2199 };
2200
2201 static struct hda_input_mux alc880_6stack_capture_source = {
2202 .num_items = 4,
2203 .items = {
2204 { "Mic", 0x0 },
2205 { "Front Mic", 0x1 },
2206 { "Line", 0x2 },
2207 { "CD", 0x4 },
2208 },
2209 };
2210
2211 /* fixed 8-channels */
2212 static struct hda_channel_mode alc880_sixstack_modes[1] = {
2213 { 8, NULL },
2214 };
2215
2216 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2217 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2218 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2219 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2220 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2221 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2222 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2224 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2225 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2226 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2227 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2228 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2230 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2231 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2232 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2234 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2235 {
2236 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2237 .name = "Channel Mode",
2238 .info = alc_ch_mode_info,
2239 .get = alc_ch_mode_get,
2240 .put = alc_ch_mode_put,
2241 },
2242 { } /* end */
2243 };
2244
2245
2246 /*
2247 * ALC880 W810 model
2248 *
2249 * W810 has rear IO for:
2250 * Front (DAC 02)
2251 * Surround (DAC 03)
2252 * Center/LFE (DAC 04)
2253 * Digital out (06)
2254 *
2255 * The system also has a pair of internal speakers, and a headphone jack.
2256 * These are both connected to Line2 on the codec, hence to DAC 02.
2257 *
2258 * There is a variable resistor to control the speaker or headphone
2259 * volume. This is a hardware-only device without a software API.
2260 *
2261 * Plugging headphones in will disable the internal speakers. This is
2262 * implemented in hardware, not via the driver using jack sense. In
2263 * a similar fashion, plugging into the rear socket marked "front" will
2264 * disable both the speakers and headphones.
2265 *
2266 * For input, there's a microphone jack, and an "audio in" jack.
2267 * These may not do anything useful with this driver yet, because I
2268 * haven't setup any initialization verbs for these yet...
2269 */
2270
2271 static hda_nid_t alc880_w810_dac_nids[3] = {
2272 /* front, rear/surround, clfe */
2273 0x02, 0x03, 0x04
2274 };
2275
2276 /* fixed 6 channels */
2277 static struct hda_channel_mode alc880_w810_modes[1] = {
2278 { 6, NULL }
2279 };
2280
2281 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2282 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2283 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2284 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2285 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2286 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2287 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2288 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2289 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2290 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2292 { } /* end */
2293 };
2294
2295
2296 /*
2297 * Z710V model
2298 *
2299 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2300 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2301 * Line = 0x1a
2302 */
2303
2304 static hda_nid_t alc880_z71v_dac_nids[1] = {
2305 0x02
2306 };
2307 #define ALC880_Z71V_HP_DAC 0x03
2308
2309 /* fixed 2 channels */
2310 static struct hda_channel_mode alc880_2_jack_modes[1] = {
2311 { 2, NULL }
2312 };
2313
2314 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
2315 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2316 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2317 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2318 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2319 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2320 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2321 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2322 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2323 { } /* end */
2324 };
2325
2326
2327 /*
2328 * ALC880 F1734 model
2329 *
2330 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2331 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2332 */
2333
2334 static hda_nid_t alc880_f1734_dac_nids[1] = {
2335 0x03
2336 };
2337 #define ALC880_F1734_HP_DAC 0x02
2338
2339 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
2340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2341 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2342 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2343 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2344 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2345 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2348 { } /* end */
2349 };
2350
2351 static struct hda_input_mux alc880_f1734_capture_source = {
2352 .num_items = 2,
2353 .items = {
2354 { "Mic", 0x1 },
2355 { "CD", 0x4 },
2356 },
2357 };
2358
2359
2360 /*
2361 * ALC880 ASUS model
2362 *
2363 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2364 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2365 * Mic = 0x18, Line = 0x1a
2366 */
2367
2368 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2369 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2370
2371 static struct snd_kcontrol_new alc880_asus_mixer[] = {
2372 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2373 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2374 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2375 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2376 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2377 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2378 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2379 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2380 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2381 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2382 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2383 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2385 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Channel Mode",
2389 .info = alc_ch_mode_info,
2390 .get = alc_ch_mode_get,
2391 .put = alc_ch_mode_put,
2392 },
2393 { } /* end */
2394 };
2395
2396 /*
2397 * ALC880 ASUS W1V model
2398 *
2399 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2400 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2401 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
2402 */
2403
2404 /* additional mixers to alc880_asus_mixer */
2405 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
2406 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
2407 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
2408 { } /* end */
2409 };
2410
2411 /* TCL S700 */
2412 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
2413 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2414 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
2417 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
2418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
2419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
2420 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
2421 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
2422 { } /* end */
2423 };
2424
2425 /* Uniwill */
2426 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2427 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2428 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2429 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2430 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2433 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2434 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2440 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2443 {
2444 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2445 .name = "Channel Mode",
2446 .info = alc_ch_mode_info,
2447 .get = alc_ch_mode_get,
2448 .put = alc_ch_mode_put,
2449 },
2450 { } /* end */
2451 };
2452
2453 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2458 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2459 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2460 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2461 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2462 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2463 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2464 { } /* end */
2465 };
2466
2467 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2468 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2469 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2471 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2473 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2474 { } /* end */
2475 };
2476
2477 /*
2478 * virtual master controls
2479 */
2480
2481 /*
2482 * slave controls for virtual master
2483 */
2484 static const char *alc_slave_vols[] = {
2485 "Front Playback Volume",
2486 "Surround Playback Volume",
2487 "Center Playback Volume",
2488 "LFE Playback Volume",
2489 "Side Playback Volume",
2490 "Headphone Playback Volume",
2491 "Speaker Playback Volume",
2492 "Mono Playback Volume",
2493 "Line-Out Playback Volume",
2494 "PCM Playback Volume",
2495 NULL,
2496 };
2497
2498 static const char *alc_slave_sws[] = {
2499 "Front Playback Switch",
2500 "Surround Playback Switch",
2501 "Center Playback Switch",
2502 "LFE Playback Switch",
2503 "Side Playback Switch",
2504 "Headphone Playback Switch",
2505 "Speaker Playback Switch",
2506 "Mono Playback Switch",
2507 "IEC958 Playback Switch",
2508 "Line-Out Playback Switch",
2509 "PCM Playback Switch",
2510 NULL,
2511 };
2512
2513 /*
2514 * build control elements
2515 */
2516
2517 #define NID_MAPPING (-1)
2518
2519 #define SUBDEV_SPEAKER_ (0 << 6)
2520 #define SUBDEV_HP_ (1 << 6)
2521 #define SUBDEV_LINE_ (2 << 6)
2522 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
2523 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
2524 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
2525
2526 static void alc_free_kctls(struct hda_codec *codec);
2527
2528 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2529 /* additional beep mixers; the actual parameters are overwritten at build */
2530 static struct snd_kcontrol_new alc_beep_mixer[] = {
2531 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
2532 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
2533 { } /* end */
2534 };
2535 #endif
2536
2537 static int alc_build_controls(struct hda_codec *codec)
2538 {
2539 struct alc_spec *spec = codec->spec;
2540 struct snd_kcontrol *kctl;
2541 struct snd_kcontrol_new *knew;
2542 int i, j, err;
2543 unsigned int u;
2544 hda_nid_t nid;
2545
2546 for (i = 0; i < spec->num_mixers; i++) {
2547 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
2548 if (err < 0)
2549 return err;
2550 }
2551 if (spec->cap_mixer) {
2552 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2553 if (err < 0)
2554 return err;
2555 }
2556 if (spec->multiout.dig_out_nid) {
2557 err = snd_hda_create_spdif_out_ctls(codec,
2558 spec->multiout.dig_out_nid);
2559 if (err < 0)
2560 return err;
2561 if (!spec->no_analog) {
2562 err = snd_hda_create_spdif_share_sw(codec,
2563 &spec->multiout);
2564 if (err < 0)
2565 return err;
2566 spec->multiout.share_spdif = 1;
2567 }
2568 }
2569 if (spec->dig_in_nid) {
2570 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
2571 if (err < 0)
2572 return err;
2573 }
2574
2575 #ifdef CONFIG_SND_HDA_INPUT_BEEP
2576 /* create beep controls if needed */
2577 if (spec->beep_amp) {
2578 struct snd_kcontrol_new *knew;
2579 for (knew = alc_beep_mixer; knew->name; knew++) {
2580 struct snd_kcontrol *kctl;
2581 kctl = snd_ctl_new1(knew, codec);
2582 if (!kctl)
2583 return -ENOMEM;
2584 kctl->private_value = spec->beep_amp;
2585 err = snd_hda_ctl_add(codec, 0, kctl);
2586 if (err < 0)
2587 return err;
2588 }
2589 }
2590 #endif
2591
2592 /* if we have no master control, let's create it */
2593 if (!spec->no_analog &&
2594 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2595 unsigned int vmaster_tlv[4];
2596 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2597 HDA_OUTPUT, vmaster_tlv);
2598 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
2599 vmaster_tlv, alc_slave_vols);
2600 if (err < 0)
2601 return err;
2602 }
2603 if (!spec->no_analog &&
2604 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2605 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2606 NULL, alc_slave_sws);
2607 if (err < 0)
2608 return err;
2609 }
2610
2611 /* assign Capture Source enums to NID */
2612 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
2613 if (!kctl)
2614 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
2615 for (i = 0; kctl && i < kctl->count; i++) {
2616 hda_nid_t *nids = spec->capsrc_nids;
2617 if (!nids)
2618 nids = spec->adc_nids;
2619 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
2620 if (err < 0)
2621 return err;
2622 }
2623 if (spec->cap_mixer) {
2624 const char *kname = kctl ? kctl->id.name : NULL;
2625 for (knew = spec->cap_mixer; knew->name; knew++) {
2626 if (kname && strcmp(knew->name, kname) == 0)
2627 continue;
2628 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2629 for (i = 0; kctl && i < kctl->count; i++) {
2630 err = snd_hda_add_nid(codec, kctl, i,
2631 spec->adc_nids[i]);
2632 if (err < 0)
2633 return err;
2634 }
2635 }
2636 }
2637
2638 /* other nid->control mapping */
2639 for (i = 0; i < spec->num_mixers; i++) {
2640 for (knew = spec->mixers[i]; knew->name; knew++) {
2641 if (knew->iface != NID_MAPPING)
2642 continue;
2643 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
2644 if (kctl == NULL)
2645 continue;
2646 u = knew->subdevice;
2647 for (j = 0; j < 4; j++, u >>= 8) {
2648 nid = u & 0x3f;
2649 if (nid == 0)
2650 continue;
2651 switch (u & 0xc0) {
2652 case SUBDEV_SPEAKER_:
2653 nid = spec->autocfg.speaker_pins[nid];
2654 break;
2655 case SUBDEV_LINE_:
2656 nid = spec->autocfg.line_out_pins[nid];
2657 break;
2658 case SUBDEV_HP_:
2659 nid = spec->autocfg.hp_pins[nid];
2660 break;
2661 default:
2662 continue;
2663 }
2664 err = snd_hda_add_nid(codec, kctl, 0, nid);
2665 if (err < 0)
2666 return err;
2667 }
2668 u = knew->private_value;
2669 for (j = 0; j < 4; j++, u >>= 8) {
2670 nid = u & 0xff;
2671 if (nid == 0)
2672 continue;
2673 err = snd_hda_add_nid(codec, kctl, 0, nid);
2674 if (err < 0)
2675 return err;
2676 }
2677 }
2678 }
2679
2680 alc_free_kctls(codec); /* no longer needed */
2681
2682 return 0;
2683 }
2684
2685
2686 /*
2687 * initialize the codec volumes, etc
2688 */
2689
2690 /*
2691 * generic initialization of ADC, input mixers and output mixers
2692 */
2693 static struct hda_verb alc880_volume_init_verbs[] = {
2694 /*
2695 * Unmute ADC0-2 and set the default input to mic-in
2696 */
2697 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2699 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2701 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2703
2704 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2705 * mixer widget
2706 * Note: PASD motherboards uses the Line In 2 as the input for front
2707 * panel mic (mic 2)
2708 */
2709 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
2710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2714 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2715 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2716 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2717
2718 /*
2719 * Set up output mixers (0x0c - 0x0f)
2720 */
2721 /* set vol=0 to output mixers */
2722 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2725 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2726 /* set up input amps for analog loopback */
2727 /* Amp Indices: DAC = 0, mixer = 1 */
2728 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2729 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2734 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2735 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2736
2737 { }
2738 };
2739
2740 /*
2741 * 3-stack pin configuration:
2742 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
2743 */
2744 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
2745 /*
2746 * preset connection lists of input pins
2747 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2748 */
2749 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2750 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2751 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2752
2753 /*
2754 * Set pin mode and muting
2755 */
2756 /* set front pin widgets 0x14 for output */
2757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2759 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2762 /* Mic2 (as headphone out) for HP output */
2763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2765 /* Line In pin widget for input */
2766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2767 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2768 /* Line2 (as front mic) pin widget for input and vref at 80% */
2769 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2770 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2771 /* CD pin widget for input */
2772 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2773
2774 { }
2775 };
2776
2777 /*
2778 * 5-stack pin configuration:
2779 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
2780 * line-in/side = 0x1a, f-mic = 0x1b
2781 */
2782 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
2783 /*
2784 * preset connection lists of input pins
2785 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
2786 */
2787 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2788 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
2789
2790 /*
2791 * Set pin mode and muting
2792 */
2793 /* set pin widgets 0x14-0x17 for output */
2794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2795 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2796 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2797 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2798 /* unmute pins for output (no gain on this amp) */
2799 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2802 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2803
2804 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2805 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2807 /* Mic2 (as headphone out) for HP output */
2808 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2809 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2810 /* Line In pin widget for input */
2811 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2812 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2813 /* Line2 (as front mic) pin widget for input and vref at 80% */
2814 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2815 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2816 /* CD pin widget for input */
2817 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2818
2819 { }
2820 };
2821
2822 /*
2823 * W810 pin configuration:
2824 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
2825 */
2826 static struct hda_verb alc880_pin_w810_init_verbs[] = {
2827 /* hphone/speaker input selector: front DAC */
2828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
2829
2830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2833 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2835 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2836
2837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2838 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2839
2840 { }
2841 };
2842
2843 /*
2844 * Z71V pin configuration:
2845 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
2846 */
2847 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
2848 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2849 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2850 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2852
2853 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2855 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2856 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2857
2858 { }
2859 };
2860
2861 /*
2862 * 6-stack pin configuration:
2863 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
2864 * f-mic = 0x19, line = 0x1a, HP = 0x1b
2865 */
2866 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
2867 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2868
2869 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2870 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2873 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2874 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2875 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2876 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2877
2878 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2880 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2881 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2882 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2883 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2884 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2885 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2886 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2887
2888 { }
2889 };
2890
2891 /*
2892 * Uniwill pin configuration:
2893 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
2894 * line = 0x1a
2895 */
2896 static struct hda_verb alc880_uniwill_init_verbs[] = {
2897 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2898
2899 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2900 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2902 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2903 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2904 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2905 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2906 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2907 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2908 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2909 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2910 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2913
2914 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2915 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2916 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2917 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2918 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2919 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2920 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
2921 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
2922 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2923
2924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2925 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
2926
2927 { }
2928 };
2929
2930 /*
2931 * Uniwill P53
2932 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
2933 */
2934 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
2935 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2936
2937 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2938 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2939 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2940 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2941 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2942 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2943 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2944 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2945 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2946 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2947 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
2948 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
2949
2950 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2951 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2953 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2954 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2955 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2956
2957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2958 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
2959
2960 { }
2961 };
2962
2963 static struct hda_verb alc880_beep_init_verbs[] = {
2964 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
2965 { }
2966 };
2967
2968 /* auto-toggle front mic */
2969 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2970 {
2971 unsigned int present;
2972 unsigned char bits;
2973
2974 present = snd_hda_jack_detect(codec, 0x18);
2975 bits = present ? HDA_AMP_MUTE : 0;
2976 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2977 }
2978
2979 static void alc880_uniwill_setup(struct hda_codec *codec)
2980 {
2981 struct alc_spec *spec = codec->spec;
2982
2983 spec->autocfg.hp_pins[0] = 0x14;
2984 spec->autocfg.speaker_pins[0] = 0x15;
2985 spec->autocfg.speaker_pins[0] = 0x16;
2986 }
2987
2988 static void alc880_uniwill_init_hook(struct hda_codec *codec)
2989 {
2990 alc_automute_amp(codec);
2991 alc880_uniwill_mic_automute(codec);
2992 }
2993
2994 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2995 unsigned int res)
2996 {
2997 /* Looks like the unsol event is incompatible with the standard
2998 * definition. 4bit tag is placed at 28 bit!
2999 */
3000 switch (res >> 28) {
3001 case ALC880_MIC_EVENT:
3002 alc880_uniwill_mic_automute(codec);
3003 break;
3004 default:
3005 alc_automute_amp_unsol_event(codec, res);
3006 break;
3007 }
3008 }
3009
3010 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3011 {
3012 struct alc_spec *spec = codec->spec;
3013
3014 spec->autocfg.hp_pins[0] = 0x14;
3015 spec->autocfg.speaker_pins[0] = 0x15;
3016 }
3017
3018 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3019 {
3020 unsigned int present;
3021
3022 present = snd_hda_codec_read(codec, 0x21, 0,
3023 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3024 present &= HDA_AMP_VOLMASK;
3025 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3026 HDA_AMP_VOLMASK, present);
3027 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3028 HDA_AMP_VOLMASK, present);
3029 }
3030
3031 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3032 unsigned int res)
3033 {
3034 /* Looks like the unsol event is incompatible with the standard
3035 * definition. 4bit tag is placed at 28 bit!
3036 */
3037 if ((res >> 28) == ALC880_DCVOL_EVENT)
3038 alc880_uniwill_p53_dcvol_automute(codec);
3039 else
3040 alc_automute_amp_unsol_event(codec, res);
3041 }
3042
3043 /*
3044 * F1734 pin configuration:
3045 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3046 */
3047 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
3048 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3049 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3050 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3051 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3052 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3053
3054 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3055 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3056 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3058
3059 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3060 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3061 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3062 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3063 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3064 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3065 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3066 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3067 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3068
3069 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3070 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3071
3072 { }
3073 };
3074
3075 /*
3076 * ASUS pin configuration:
3077 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3078 */
3079 static struct hda_verb alc880_pin_asus_init_verbs[] = {
3080 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3081 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3082 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3083 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3084
3085 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3086 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3088 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3090 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3091 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3093
3094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3095 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3096 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3097 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3098 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3102 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3103
3104 { }
3105 };
3106
3107 /* Enable GPIO mask and set output */
3108 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3109 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3110 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3111
3112 /* Clevo m520g init */
3113 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
3114 /* headphone output */
3115 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3116 /* line-out */
3117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3119 /* Line-in */
3120 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3121 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3122 /* CD */
3123 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3124 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3125 /* Mic1 (rear panel) */
3126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3127 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3128 /* Mic2 (front panel) */
3129 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3130 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3131 /* headphone */
3132 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3133 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3134 /* change to EAPD mode */
3135 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3136 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3137
3138 { }
3139 };
3140
3141 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3142 /* change to EAPD mode */
3143 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3144 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3145
3146 /* Headphone output */
3147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3148 /* Front output*/
3149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3151
3152 /* Line In pin widget for input */
3153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3154 /* CD pin widget for input */
3155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3156 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3158
3159 /* change to EAPD mode */
3160 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3161 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3162
3163 { }
3164 };
3165
3166 /*
3167 * LG m1 express dual
3168 *
3169 * Pin assignment:
3170 * Rear Line-In/Out (blue): 0x14
3171 * Build-in Mic-In: 0x15
3172 * Speaker-out: 0x17
3173 * HP-Out (green): 0x1b
3174 * Mic-In/Out (red): 0x19
3175 * SPDIF-Out: 0x1e
3176 */
3177
3178 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3179 static hda_nid_t alc880_lg_dac_nids[3] = {
3180 0x05, 0x02, 0x03
3181 };
3182
3183 /* seems analog CD is not working */
3184 static struct hda_input_mux alc880_lg_capture_source = {
3185 .num_items = 3,
3186 .items = {
3187 { "Mic", 0x1 },
3188 { "Line", 0x5 },
3189 { "Internal Mic", 0x6 },
3190 },
3191 };
3192
3193 /* 2,4,6 channel modes */
3194 static struct hda_verb alc880_lg_ch2_init[] = {
3195 /* set line-in and mic-in to input */
3196 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3197 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3198 { }
3199 };
3200
3201 static struct hda_verb alc880_lg_ch4_init[] = {
3202 /* set line-in to out and mic-in to input */
3203 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3204 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3205 { }
3206 };
3207
3208 static struct hda_verb alc880_lg_ch6_init[] = {
3209 /* set line-in and mic-in to output */
3210 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3211 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3212 { }
3213 };
3214
3215 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
3216 { 2, alc880_lg_ch2_init },
3217 { 4, alc880_lg_ch4_init },
3218 { 6, alc880_lg_ch6_init },
3219 };
3220
3221 static struct snd_kcontrol_new alc880_lg_mixer[] = {
3222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3223 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3225 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3230 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3231 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3234 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3235 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3236 {
3237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3238 .name = "Channel Mode",
3239 .info = alc_ch_mode_info,
3240 .get = alc_ch_mode_get,
3241 .put = alc_ch_mode_put,
3242 },
3243 { } /* end */
3244 };
3245
3246 static struct hda_verb alc880_lg_init_verbs[] = {
3247 /* set capture source to mic-in */
3248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3249 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3250 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3251 /* mute all amp mixer inputs */
3252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3255 /* line-in to input */
3256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3257 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3258 /* built-in mic */
3259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3261 /* speaker-out */
3262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3264 /* mic-in to input */
3265 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3266 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3267 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3268 /* HP-out */
3269 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3270 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3271 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3272 /* jack sense */
3273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3274 { }
3275 };
3276
3277 /* toggle speaker-output according to the hp-jack state */
3278 static void alc880_lg_setup(struct hda_codec *codec)
3279 {
3280 struct alc_spec *spec = codec->spec;
3281
3282 spec->autocfg.hp_pins[0] = 0x1b;
3283 spec->autocfg.speaker_pins[0] = 0x17;
3284 }
3285
3286 /*
3287 * LG LW20
3288 *
3289 * Pin assignment:
3290 * Speaker-out: 0x14
3291 * Mic-In: 0x18
3292 * Built-in Mic-In: 0x19
3293 * Line-In: 0x1b
3294 * HP-Out: 0x1a
3295 * SPDIF-Out: 0x1e
3296 */
3297
3298 static struct hda_input_mux alc880_lg_lw_capture_source = {
3299 .num_items = 3,
3300 .items = {
3301 { "Mic", 0x0 },
3302 { "Internal Mic", 0x1 },
3303 { "Line In", 0x2 },
3304 },
3305 };
3306
3307 #define alc880_lg_lw_modes alc880_threestack_modes
3308
3309 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3312 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3313 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3314 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3315 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3316 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3317 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3318 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3319 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3320 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3321 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3322 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3323 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
3324 {
3325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3326 .name = "Channel Mode",
3327 .info = alc_ch_mode_info,
3328 .get = alc_ch_mode_get,
3329 .put = alc_ch_mode_put,
3330 },
3331 { } /* end */
3332 };
3333
3334 static struct hda_verb alc880_lg_lw_init_verbs[] = {
3335 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3336 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3337 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3338
3339 /* set capture source to mic-in */
3340 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3341 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3342 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3344 /* speaker-out */
3345 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3347 /* HP-out */
3348 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3349 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3350 /* mic-in to input */
3351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3353 /* built-in mic */
3354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3355 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3356 /* jack sense */
3357 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3358 { }
3359 };
3360
3361 /* toggle speaker-output according to the hp-jack state */
3362 static void alc880_lg_lw_setup(struct hda_codec *codec)
3363 {
3364 struct alc_spec *spec = codec->spec;
3365
3366 spec->autocfg.hp_pins[0] = 0x1b;
3367 spec->autocfg.speaker_pins[0] = 0x14;
3368 }
3369
3370 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
3371 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3372 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
3373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3375 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3376 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
3377 { } /* end */
3378 };
3379
3380 static struct hda_input_mux alc880_medion_rim_capture_source = {
3381 .num_items = 2,
3382 .items = {
3383 { "Mic", 0x0 },
3384 { "Internal Mic", 0x1 },
3385 },
3386 };
3387
3388 static struct hda_verb alc880_medion_rim_init_verbs[] = {
3389 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3390
3391 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3393
3394 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3397 /* Mic2 (as headphone out) for HP output */
3398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3400 /* Internal Speaker */
3401 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3402 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3403
3404 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3405 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3406
3407 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3408 { }
3409 };
3410
3411 /* toggle speaker-output according to the hp-jack state */
3412 static void alc880_medion_rim_automute(struct hda_codec *codec)
3413 {
3414 struct alc_spec *spec = codec->spec;
3415 alc_automute_amp(codec);
3416 /* toggle EAPD */
3417 if (spec->jack_present)
3418 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
3419 else
3420 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
3421 }
3422
3423 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3424 unsigned int res)
3425 {
3426 /* Looks like the unsol event is incompatible with the standard
3427 * definition. 4bit tag is placed at 28 bit!
3428 */
3429 if ((res >> 28) == ALC880_HP_EVENT)
3430 alc880_medion_rim_automute(codec);
3431 }
3432
3433 static void alc880_medion_rim_setup(struct hda_codec *codec)
3434 {
3435 struct alc_spec *spec = codec->spec;
3436
3437 spec->autocfg.hp_pins[0] = 0x14;
3438 spec->autocfg.speaker_pins[0] = 0x1b;
3439 }
3440
3441 #ifdef CONFIG_SND_HDA_POWER_SAVE
3442 static struct hda_amp_list alc880_loopbacks[] = {
3443 { 0x0b, HDA_INPUT, 0 },
3444 { 0x0b, HDA_INPUT, 1 },
3445 { 0x0b, HDA_INPUT, 2 },
3446 { 0x0b, HDA_INPUT, 3 },
3447 { 0x0b, HDA_INPUT, 4 },
3448 { } /* end */
3449 };
3450
3451 static struct hda_amp_list alc880_lg_loopbacks[] = {
3452 { 0x0b, HDA_INPUT, 1 },
3453 { 0x0b, HDA_INPUT, 6 },
3454 { 0x0b, HDA_INPUT, 7 },
3455 { } /* end */
3456 };
3457 #endif
3458
3459 /*
3460 * Common callbacks
3461 */
3462
3463 static int alc_init(struct hda_codec *codec)
3464 {
3465 struct alc_spec *spec = codec->spec;
3466 unsigned int i;
3467
3468 alc_fix_pll(codec);
3469 alc_auto_init_amp(codec, spec->init_amp);
3470
3471 for (i = 0; i < spec->num_init_verbs; i++)
3472 snd_hda_sequence_write(codec, spec->init_verbs[i]);
3473
3474 if (spec->init_hook)
3475 spec->init_hook(codec);
3476
3477 #ifdef CONFIG_SND_HDA_POWER_SAVE
3478 if (codec->patch_ops.check_power_status)
3479 codec->patch_ops.check_power_status(codec, 0x01);
3480 #endif
3481 return 0;
3482 }
3483
3484 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
3485 {
3486 struct alc_spec *spec = codec->spec;
3487
3488 if (spec->unsol_event)
3489 spec->unsol_event(codec, res);
3490 }
3491
3492 #ifdef CONFIG_SND_HDA_POWER_SAVE
3493 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
3494 {
3495 struct alc_spec *spec = codec->spec;
3496 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
3497 }
3498 #endif
3499
3500 /*
3501 * Analog playback callbacks
3502 */
3503 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
3504 struct hda_codec *codec,
3505 struct snd_pcm_substream *substream)
3506 {
3507 struct alc_spec *spec = codec->spec;
3508 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
3509 hinfo);
3510 }
3511
3512 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3513 struct hda_codec *codec,
3514 unsigned int stream_tag,
3515 unsigned int format,
3516 struct snd_pcm_substream *substream)
3517 {
3518 struct alc_spec *spec = codec->spec;
3519 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
3520 stream_tag, format, substream);
3521 }
3522
3523 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3524 struct hda_codec *codec,
3525 struct snd_pcm_substream *substream)
3526 {
3527 struct alc_spec *spec = codec->spec;
3528 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
3529 }
3530
3531 /*
3532 * Digital out
3533 */
3534 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
3535 struct hda_codec *codec,
3536 struct snd_pcm_substream *substream)
3537 {
3538 struct alc_spec *spec = codec->spec;
3539 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
3540 }
3541
3542 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
3543 struct hda_codec *codec,
3544 unsigned int stream_tag,
3545 unsigned int format,
3546 struct snd_pcm_substream *substream)
3547 {
3548 struct alc_spec *spec = codec->spec;
3549 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
3550 stream_tag, format, substream);
3551 }
3552
3553 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
3554 struct hda_codec *codec,
3555 struct snd_pcm_substream *substream)
3556 {
3557 struct alc_spec *spec = codec->spec;
3558 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
3559 }
3560
3561 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
3562 struct hda_codec *codec,
3563 struct snd_pcm_substream *substream)
3564 {
3565 struct alc_spec *spec = codec->spec;
3566 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
3567 }
3568
3569 /*
3570 * Analog capture
3571 */
3572 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3573 struct hda_codec *codec,
3574 unsigned int stream_tag,
3575 unsigned int format,
3576 struct snd_pcm_substream *substream)
3577 {
3578 struct alc_spec *spec = codec->spec;
3579
3580 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
3581 stream_tag, 0, format);
3582 return 0;
3583 }
3584
3585 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3586 struct hda_codec *codec,
3587 struct snd_pcm_substream *substream)
3588 {
3589 struct alc_spec *spec = codec->spec;
3590
3591 snd_hda_codec_cleanup_stream(codec,
3592 spec->adc_nids[substream->number + 1]);
3593 return 0;
3594 }
3595
3596
3597 /*
3598 */
3599 static struct hda_pcm_stream alc880_pcm_analog_playback = {
3600 .substreams = 1,
3601 .channels_min = 2,
3602 .channels_max = 8,
3603 /* NID is set in alc_build_pcms */
3604 .ops = {
3605 .open = alc880_playback_pcm_open,
3606 .prepare = alc880_playback_pcm_prepare,
3607 .cleanup = alc880_playback_pcm_cleanup
3608 },
3609 };
3610
3611 static struct hda_pcm_stream alc880_pcm_analog_capture = {
3612 .substreams = 1,
3613 .channels_min = 2,
3614 .channels_max = 2,
3615 /* NID is set in alc_build_pcms */
3616 };
3617
3618 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
3619 .substreams = 1,
3620 .channels_min = 2,
3621 .channels_max = 2,
3622 /* NID is set in alc_build_pcms */
3623 };
3624
3625 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
3626 .substreams = 2, /* can be overridden */
3627 .channels_min = 2,
3628 .channels_max = 2,
3629 /* NID is set in alc_build_pcms */
3630 .ops = {
3631 .prepare = alc880_alt_capture_pcm_prepare,
3632 .cleanup = alc880_alt_capture_pcm_cleanup
3633 },
3634 };
3635
3636 static struct hda_pcm_stream alc880_pcm_digital_playback = {
3637 .substreams = 1,
3638 .channels_min = 2,
3639 .channels_max = 2,
3640 /* NID is set in alc_build_pcms */
3641 .ops = {
3642 .open = alc880_dig_playback_pcm_open,
3643 .close = alc880_dig_playback_pcm_close,
3644 .prepare = alc880_dig_playback_pcm_prepare,
3645 .cleanup = alc880_dig_playback_pcm_cleanup
3646 },
3647 };
3648
3649 static struct hda_pcm_stream alc880_pcm_digital_capture = {
3650 .substreams = 1,
3651 .channels_min = 2,
3652 .channels_max = 2,
3653 /* NID is set in alc_build_pcms */
3654 };
3655
3656 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
3657 static struct hda_pcm_stream alc_pcm_null_stream = {
3658 .substreams = 0,
3659 .channels_min = 0,
3660 .channels_max = 0,
3661 };
3662
3663 static int alc_build_pcms(struct hda_codec *codec)
3664 {
3665 struct alc_spec *spec = codec->spec;
3666 struct hda_pcm *info = spec->pcm_rec;
3667 int i;
3668
3669 codec->num_pcms = 1;
3670 codec->pcm_info = info;
3671
3672 if (spec->no_analog)
3673 goto skip_analog;
3674
3675 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
3676 "%s Analog", codec->chip_name);
3677 info->name = spec->stream_name_analog;
3678
3679 if (spec->stream_analog_playback) {
3680 if (snd_BUG_ON(!spec->multiout.dac_nids))
3681 return -EINVAL;
3682 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
3683 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
3684 }
3685 if (spec->stream_analog_capture) {
3686 if (snd_BUG_ON(!spec->adc_nids))
3687 return -EINVAL;
3688 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
3689 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
3690 }
3691
3692 if (spec->channel_mode) {
3693 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
3694 for (i = 0; i < spec->num_channel_mode; i++) {
3695 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
3696 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
3697 }
3698 }
3699 }
3700
3701 skip_analog:
3702 /* SPDIF for stream index #1 */
3703 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3704 snprintf(spec->stream_name_digital,
3705 sizeof(spec->stream_name_digital),
3706 "%s Digital", codec->chip_name);
3707 codec->num_pcms = 2;
3708 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
3709 info = spec->pcm_rec + 1;
3710 info->name = spec->stream_name_digital;
3711 if (spec->dig_out_type)
3712 info->pcm_type = spec->dig_out_type;
3713 else
3714 info->pcm_type = HDA_PCM_TYPE_SPDIF;
3715 if (spec->multiout.dig_out_nid &&
3716 spec->stream_digital_playback) {
3717 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
3718 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
3719 }
3720 if (spec->dig_in_nid &&
3721 spec->stream_digital_capture) {
3722 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
3723 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
3724 }
3725 /* FIXME: do we need this for all Realtek codec models? */
3726 codec->spdif_status_reset = 1;
3727 }
3728
3729 if (spec->no_analog)
3730 return 0;
3731
3732 /* If the use of more than one ADC is requested for the current
3733 * model, configure a second analog capture-only PCM.
3734 */
3735 /* Additional Analaog capture for index #2 */
3736 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
3737 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
3738 codec->num_pcms = 3;
3739 info = spec->pcm_rec + 2;
3740 info->name = spec->stream_name_analog;
3741 if (spec->alt_dac_nid) {
3742 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3743 *spec->stream_analog_alt_playback;
3744 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
3745 spec->alt_dac_nid;
3746 } else {
3747 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
3748 alc_pcm_null_stream;
3749 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
3750 }
3751 if (spec->num_adc_nids > 1) {
3752 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3753 *spec->stream_analog_alt_capture;
3754 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
3755 spec->adc_nids[1];
3756 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
3757 spec->num_adc_nids - 1;
3758 } else {
3759 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
3760 alc_pcm_null_stream;
3761 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
3762 }
3763 }
3764
3765 return 0;
3766 }
3767
3768 static inline void alc_shutup(struct hda_codec *codec)
3769 {
3770 snd_hda_shutup_pins(codec);
3771 }
3772
3773 static void alc_free_kctls(struct hda_codec *codec)
3774 {
3775 struct alc_spec *spec = codec->spec;
3776
3777 if (spec->kctls.list) {
3778 struct snd_kcontrol_new *kctl = spec->kctls.list;
3779 int i;
3780 for (i = 0; i < spec->kctls.used; i++)
3781 kfree(kctl[i].name);
3782 }
3783 snd_array_free(&spec->kctls);
3784 }
3785
3786 static void alc_free(struct hda_codec *codec)
3787 {
3788 struct alc_spec *spec = codec->spec;
3789
3790 if (!spec)
3791 return;
3792
3793 alc_shutup(codec);
3794 alc_free_kctls(codec);
3795 kfree(spec);
3796 snd_hda_detach_beep_device(codec);
3797 }
3798
3799 #ifdef CONFIG_SND_HDA_POWER_SAVE
3800 static void alc_power_eapd(struct hda_codec *codec)
3801 {
3802 /* We currently only handle front, HP */
3803 switch (codec->vendor_id) {
3804 case 0x10ec0260:
3805 set_eapd(codec, 0x0f, 0);
3806 set_eapd(codec, 0x10, 0);
3807 break;
3808 case 0x10ec0262:
3809 case 0x10ec0267:
3810 case 0x10ec0268:
3811 case 0x10ec0269:
3812 case 0x10ec0270:
3813 case 0x10ec0272:
3814 case 0x10ec0660:
3815 case 0x10ec0662:
3816 case 0x10ec0663:
3817 case 0x10ec0862:
3818 case 0x10ec0889:
3819 set_eapd(codec, 0x14, 0);
3820 set_eapd(codec, 0x15, 0);
3821 break;
3822 }
3823 }
3824
3825 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
3826 {
3827 struct alc_spec *spec = codec->spec;
3828 alc_shutup(codec);
3829 if (spec && spec->power_hook)
3830 spec->power_hook(codec);
3831 return 0;
3832 }
3833 #endif
3834
3835 #ifdef SND_HDA_NEEDS_RESUME
3836 static int alc_resume(struct hda_codec *codec)
3837 {
3838 codec->patch_ops.init(codec);
3839 snd_hda_codec_resume_amp(codec);
3840 snd_hda_codec_resume_cache(codec);
3841 #ifdef CONFIG_SND_HDA_POWER_SAVE
3842 if (codec->patch_ops.check_power_status)
3843 codec->patch_ops.check_power_status(codec, 0x01);
3844 #endif
3845 return 0;
3846 }
3847 #endif
3848
3849 /*
3850 */
3851 static struct hda_codec_ops alc_patch_ops = {
3852 .build_controls = alc_build_controls,
3853 .build_pcms = alc_build_pcms,
3854 .init = alc_init,
3855 .free = alc_free,
3856 .unsol_event = alc_unsol_event,
3857 #ifdef SND_HDA_NEEDS_RESUME
3858 .resume = alc_resume,
3859 #endif
3860 #ifdef CONFIG_SND_HDA_POWER_SAVE
3861 .suspend = alc_suspend,
3862 .check_power_status = alc_check_power_status,
3863 #endif
3864 .reboot_notify = alc_shutup,
3865 };
3866
3867 /* replace the codec chip_name with the given string */
3868 static int alc_codec_rename(struct hda_codec *codec, const char *name)
3869 {
3870 kfree(codec->chip_name);
3871 codec->chip_name = kstrdup(name, GFP_KERNEL);
3872 if (!codec->chip_name) {
3873 alc_free(codec);
3874 return -ENOMEM;
3875 }
3876 return 0;
3877 }
3878
3879 /*
3880 * Test configuration for debugging
3881 *
3882 * Almost all inputs/outputs are enabled. I/O pins can be configured via
3883 * enum controls.
3884 */
3885 #ifdef CONFIG_SND_DEBUG
3886 static hda_nid_t alc880_test_dac_nids[4] = {
3887 0x02, 0x03, 0x04, 0x05
3888 };
3889
3890 static struct hda_input_mux alc880_test_capture_source = {
3891 .num_items = 7,
3892 .items = {
3893 { "In-1", 0x0 },
3894 { "In-2", 0x1 },
3895 { "In-3", 0x2 },
3896 { "In-4", 0x3 },
3897 { "CD", 0x4 },
3898 { "Front", 0x5 },
3899 { "Surround", 0x6 },
3900 },
3901 };
3902
3903 static struct hda_channel_mode alc880_test_modes[4] = {
3904 { 2, NULL },
3905 { 4, NULL },
3906 { 6, NULL },
3907 { 8, NULL },
3908 };
3909
3910 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
3911 struct snd_ctl_elem_info *uinfo)
3912 {
3913 static char *texts[] = {
3914 "N/A", "Line Out", "HP Out",
3915 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
3916 };
3917 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3918 uinfo->count = 1;
3919 uinfo->value.enumerated.items = 8;
3920 if (uinfo->value.enumerated.item >= 8)
3921 uinfo->value.enumerated.item = 7;
3922 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3923 return 0;
3924 }
3925
3926 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
3927 struct snd_ctl_elem_value *ucontrol)
3928 {
3929 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3930 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3931 unsigned int pin_ctl, item = 0;
3932
3933 pin_ctl = snd_hda_codec_read(codec, nid, 0,
3934 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3935 if (pin_ctl & AC_PINCTL_OUT_EN) {
3936 if (pin_ctl & AC_PINCTL_HP_EN)
3937 item = 2;
3938 else
3939 item = 1;
3940 } else if (pin_ctl & AC_PINCTL_IN_EN) {
3941 switch (pin_ctl & AC_PINCTL_VREFEN) {
3942 case AC_PINCTL_VREF_HIZ: item = 3; break;
3943 case AC_PINCTL_VREF_50: item = 4; break;
3944 case AC_PINCTL_VREF_GRD: item = 5; break;
3945 case AC_PINCTL_VREF_80: item = 6; break;
3946 case AC_PINCTL_VREF_100: item = 7; break;
3947 }
3948 }
3949 ucontrol->value.enumerated.item[0] = item;
3950 return 0;
3951 }
3952
3953 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
3954 struct snd_ctl_elem_value *ucontrol)
3955 {
3956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3957 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3958 static unsigned int ctls[] = {
3959 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
3960 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
3961 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
3962 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
3963 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
3964 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
3965 };
3966 unsigned int old_ctl, new_ctl;
3967
3968 old_ctl = snd_hda_codec_read(codec, nid, 0,
3969 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3970 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
3971 if (old_ctl != new_ctl) {
3972 int val;
3973 snd_hda_codec_write_cache(codec, nid, 0,
3974 AC_VERB_SET_PIN_WIDGET_CONTROL,
3975 new_ctl);
3976 val = ucontrol->value.enumerated.item[0] >= 3 ?
3977 HDA_AMP_MUTE : 0;
3978 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3979 HDA_AMP_MUTE, val);
3980 return 1;
3981 }
3982 return 0;
3983 }
3984
3985 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3986 struct snd_ctl_elem_info *uinfo)
3987 {
3988 static char *texts[] = {
3989 "Front", "Surround", "CLFE", "Side"
3990 };
3991 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3992 uinfo->count = 1;
3993 uinfo->value.enumerated.items = 4;
3994 if (uinfo->value.enumerated.item >= 4)
3995 uinfo->value.enumerated.item = 3;
3996 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3997 return 0;
3998 }
3999
4000 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4001 struct snd_ctl_elem_value *ucontrol)
4002 {
4003 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4004 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4005 unsigned int sel;
4006
4007 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4008 ucontrol->value.enumerated.item[0] = sel & 3;
4009 return 0;
4010 }
4011
4012 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4013 struct snd_ctl_elem_value *ucontrol)
4014 {
4015 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4016 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4017 unsigned int sel;
4018
4019 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4020 if (ucontrol->value.enumerated.item[0] != sel) {
4021 sel = ucontrol->value.enumerated.item[0] & 3;
4022 snd_hda_codec_write_cache(codec, nid, 0,
4023 AC_VERB_SET_CONNECT_SEL, sel);
4024 return 1;
4025 }
4026 return 0;
4027 }
4028
4029 #define PIN_CTL_TEST(xname,nid) { \
4030 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4031 .name = xname, \
4032 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4033 .info = alc_test_pin_ctl_info, \
4034 .get = alc_test_pin_ctl_get, \
4035 .put = alc_test_pin_ctl_put, \
4036 .private_value = nid \
4037 }
4038
4039 #define PIN_SRC_TEST(xname,nid) { \
4040 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4041 .name = xname, \
4042 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4043 .info = alc_test_pin_src_info, \
4044 .get = alc_test_pin_src_get, \
4045 .put = alc_test_pin_src_put, \
4046 .private_value = nid \
4047 }
4048
4049 static struct snd_kcontrol_new alc880_test_mixer[] = {
4050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4051 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4052 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4053 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4055 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4056 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4057 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4058 PIN_CTL_TEST("Front Pin Mode", 0x14),
4059 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4060 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4061 PIN_CTL_TEST("Side Pin Mode", 0x17),
4062 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4063 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4064 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4065 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4066 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4067 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4068 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4069 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4070 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4071 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4072 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4073 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4074 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4075 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4076 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4077 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4078 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4079 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4080 {
4081 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4082 .name = "Channel Mode",
4083 .info = alc_ch_mode_info,
4084 .get = alc_ch_mode_get,
4085 .put = alc_ch_mode_put,
4086 },
4087 { } /* end */
4088 };
4089
4090 static struct hda_verb alc880_test_init_verbs[] = {
4091 /* Unmute inputs of 0x0c - 0x0f */
4092 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4094 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4095 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4096 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4097 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4098 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4099 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4100 /* Vol output for 0x0c-0x0f */
4101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4102 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4103 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4104 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4105 /* Set output pins 0x14-0x17 */
4106 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4107 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4108 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4109 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4110 /* Unmute output pins 0x14-0x17 */
4111 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4113 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4114 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4115 /* Set input pins 0x18-0x1c */
4116 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4117 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4118 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4119 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4120 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4121 /* Mute input pins 0x18-0x1b */
4122 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4123 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4124 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4125 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4126 /* ADC set up */
4127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4128 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4129 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4130 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4131 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4132 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4133 /* Analog input/passthru */
4134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4136 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4137 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4138 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4139 { }
4140 };
4141 #endif
4142
4143 /*
4144 */
4145
4146 static const char *alc880_models[ALC880_MODEL_LAST] = {
4147 [ALC880_3ST] = "3stack",
4148 [ALC880_TCL_S700] = "tcl",
4149 [ALC880_3ST_DIG] = "3stack-digout",
4150 [ALC880_CLEVO] = "clevo",
4151 [ALC880_5ST] = "5stack",
4152 [ALC880_5ST_DIG] = "5stack-digout",
4153 [ALC880_W810] = "w810",
4154 [ALC880_Z71V] = "z71v",
4155 [ALC880_6ST] = "6stack",
4156 [ALC880_6ST_DIG] = "6stack-digout",
4157 [ALC880_ASUS] = "asus",
4158 [ALC880_ASUS_W1V] = "asus-w1v",
4159 [ALC880_ASUS_DIG] = "asus-dig",
4160 [ALC880_ASUS_DIG2] = "asus-dig2",
4161 [ALC880_UNIWILL_DIG] = "uniwill",
4162 [ALC880_UNIWILL_P53] = "uniwill-p53",
4163 [ALC880_FUJITSU] = "fujitsu",
4164 [ALC880_F1734] = "F1734",
4165 [ALC880_LG] = "lg",
4166 [ALC880_LG_LW] = "lg-lw",
4167 [ALC880_MEDION_RIM] = "medion",
4168 #ifdef CONFIG_SND_DEBUG
4169 [ALC880_TEST] = "test",
4170 #endif
4171 [ALC880_AUTO] = "auto",
4172 };
4173
4174 static struct snd_pci_quirk alc880_cfg_tbl[] = {
4175 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4176 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4177 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4178 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4179 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4180 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4181 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4182 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4183 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4184 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4185 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
4186 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4187 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4188 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4189 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4190 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4191 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4192 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4193 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4194 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4195 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4196 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4197 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4198 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4199 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4200 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4201 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4202 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4203 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4204 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4205 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4206 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4207 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4208 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4209 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4210 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4211 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4212 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4213 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4214 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4215 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
4216 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4217 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4218 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4219 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4220 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4221 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4222 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4223 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4224 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
4225 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4226 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4227 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4228 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4229 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4230 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4231 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4232 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4233 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4234 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4235 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4236 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4237 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4238 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4239 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4240 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4241 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4242 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4243 /* default Intel */
4244 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4245 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4246 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4247 {}
4248 };
4249
4250 /*
4251 * ALC880 codec presets
4252 */
4253 static struct alc_config_preset alc880_presets[] = {
4254 [ALC880_3ST] = {
4255 .mixers = { alc880_three_stack_mixer },
4256 .init_verbs = { alc880_volume_init_verbs,
4257 alc880_pin_3stack_init_verbs },
4258 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4259 .dac_nids = alc880_dac_nids,
4260 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4261 .channel_mode = alc880_threestack_modes,
4262 .need_dac_fix = 1,
4263 .input_mux = &alc880_capture_source,
4264 },
4265 [ALC880_3ST_DIG] = {
4266 .mixers = { alc880_three_stack_mixer },
4267 .init_verbs = { alc880_volume_init_verbs,
4268 alc880_pin_3stack_init_verbs },
4269 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4270 .dac_nids = alc880_dac_nids,
4271 .dig_out_nid = ALC880_DIGOUT_NID,
4272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4273 .channel_mode = alc880_threestack_modes,
4274 .need_dac_fix = 1,
4275 .input_mux = &alc880_capture_source,
4276 },
4277 [ALC880_TCL_S700] = {
4278 .mixers = { alc880_tcl_s700_mixer },
4279 .init_verbs = { alc880_volume_init_verbs,
4280 alc880_pin_tcl_S700_init_verbs,
4281 alc880_gpio2_init_verbs },
4282 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4283 .dac_nids = alc880_dac_nids,
4284 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4285 .num_adc_nids = 1, /* single ADC */
4286 .hp_nid = 0x03,
4287 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4288 .channel_mode = alc880_2_jack_modes,
4289 .input_mux = &alc880_capture_source,
4290 },
4291 [ALC880_5ST] = {
4292 .mixers = { alc880_three_stack_mixer,
4293 alc880_five_stack_mixer},
4294 .init_verbs = { alc880_volume_init_verbs,
4295 alc880_pin_5stack_init_verbs },
4296 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4297 .dac_nids = alc880_dac_nids,
4298 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4299 .channel_mode = alc880_fivestack_modes,
4300 .input_mux = &alc880_capture_source,
4301 },
4302 [ALC880_5ST_DIG] = {
4303 .mixers = { alc880_three_stack_mixer,
4304 alc880_five_stack_mixer },
4305 .init_verbs = { alc880_volume_init_verbs,
4306 alc880_pin_5stack_init_verbs },
4307 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4308 .dac_nids = alc880_dac_nids,
4309 .dig_out_nid = ALC880_DIGOUT_NID,
4310 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4311 .channel_mode = alc880_fivestack_modes,
4312 .input_mux = &alc880_capture_source,
4313 },
4314 [ALC880_6ST] = {
4315 .mixers = { alc880_six_stack_mixer },
4316 .init_verbs = { alc880_volume_init_verbs,
4317 alc880_pin_6stack_init_verbs },
4318 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4319 .dac_nids = alc880_6st_dac_nids,
4320 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4321 .channel_mode = alc880_sixstack_modes,
4322 .input_mux = &alc880_6stack_capture_source,
4323 },
4324 [ALC880_6ST_DIG] = {
4325 .mixers = { alc880_six_stack_mixer },
4326 .init_verbs = { alc880_volume_init_verbs,
4327 alc880_pin_6stack_init_verbs },
4328 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4329 .dac_nids = alc880_6st_dac_nids,
4330 .dig_out_nid = ALC880_DIGOUT_NID,
4331 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4332 .channel_mode = alc880_sixstack_modes,
4333 .input_mux = &alc880_6stack_capture_source,
4334 },
4335 [ALC880_W810] = {
4336 .mixers = { alc880_w810_base_mixer },
4337 .init_verbs = { alc880_volume_init_verbs,
4338 alc880_pin_w810_init_verbs,
4339 alc880_gpio2_init_verbs },
4340 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4341 .dac_nids = alc880_w810_dac_nids,
4342 .dig_out_nid = ALC880_DIGOUT_NID,
4343 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4344 .channel_mode = alc880_w810_modes,
4345 .input_mux = &alc880_capture_source,
4346 },
4347 [ALC880_Z71V] = {
4348 .mixers = { alc880_z71v_mixer },
4349 .init_verbs = { alc880_volume_init_verbs,
4350 alc880_pin_z71v_init_verbs },
4351 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
4352 .dac_nids = alc880_z71v_dac_nids,
4353 .dig_out_nid = ALC880_DIGOUT_NID,
4354 .hp_nid = 0x03,
4355 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4356 .channel_mode = alc880_2_jack_modes,
4357 .input_mux = &alc880_capture_source,
4358 },
4359 [ALC880_F1734] = {
4360 .mixers = { alc880_f1734_mixer },
4361 .init_verbs = { alc880_volume_init_verbs,
4362 alc880_pin_f1734_init_verbs },
4363 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
4364 .dac_nids = alc880_f1734_dac_nids,
4365 .hp_nid = 0x02,
4366 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4367 .channel_mode = alc880_2_jack_modes,
4368 .input_mux = &alc880_f1734_capture_source,
4369 .unsol_event = alc880_uniwill_p53_unsol_event,
4370 .setup = alc880_uniwill_p53_setup,
4371 .init_hook = alc_automute_amp,
4372 },
4373 [ALC880_ASUS] = {
4374 .mixers = { alc880_asus_mixer },
4375 .init_verbs = { alc880_volume_init_verbs,
4376 alc880_pin_asus_init_verbs,
4377 alc880_gpio1_init_verbs },
4378 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4379 .dac_nids = alc880_asus_dac_nids,
4380 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4381 .channel_mode = alc880_asus_modes,
4382 .need_dac_fix = 1,
4383 .input_mux = &alc880_capture_source,
4384 },
4385 [ALC880_ASUS_DIG] = {
4386 .mixers = { alc880_asus_mixer },
4387 .init_verbs = { alc880_volume_init_verbs,
4388 alc880_pin_asus_init_verbs,
4389 alc880_gpio1_init_verbs },
4390 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4391 .dac_nids = alc880_asus_dac_nids,
4392 .dig_out_nid = ALC880_DIGOUT_NID,
4393 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4394 .channel_mode = alc880_asus_modes,
4395 .need_dac_fix = 1,
4396 .input_mux = &alc880_capture_source,
4397 },
4398 [ALC880_ASUS_DIG2] = {
4399 .mixers = { alc880_asus_mixer },
4400 .init_verbs = { alc880_volume_init_verbs,
4401 alc880_pin_asus_init_verbs,
4402 alc880_gpio2_init_verbs }, /* use GPIO2 */
4403 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4404 .dac_nids = alc880_asus_dac_nids,
4405 .dig_out_nid = ALC880_DIGOUT_NID,
4406 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4407 .channel_mode = alc880_asus_modes,
4408 .need_dac_fix = 1,
4409 .input_mux = &alc880_capture_source,
4410 },
4411 [ALC880_ASUS_W1V] = {
4412 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
4413 .init_verbs = { alc880_volume_init_verbs,
4414 alc880_pin_asus_init_verbs,
4415 alc880_gpio1_init_verbs },
4416 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4417 .dac_nids = alc880_asus_dac_nids,
4418 .dig_out_nid = ALC880_DIGOUT_NID,
4419 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4420 .channel_mode = alc880_asus_modes,
4421 .need_dac_fix = 1,
4422 .input_mux = &alc880_capture_source,
4423 },
4424 [ALC880_UNIWILL_DIG] = {
4425 .mixers = { alc880_asus_mixer },
4426 .init_verbs = { alc880_volume_init_verbs,
4427 alc880_pin_asus_init_verbs },
4428 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4429 .dac_nids = alc880_asus_dac_nids,
4430 .dig_out_nid = ALC880_DIGOUT_NID,
4431 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
4432 .channel_mode = alc880_asus_modes,
4433 .need_dac_fix = 1,
4434 .input_mux = &alc880_capture_source,
4435 },
4436 [ALC880_UNIWILL] = {
4437 .mixers = { alc880_uniwill_mixer },
4438 .init_verbs = { alc880_volume_init_verbs,
4439 alc880_uniwill_init_verbs },
4440 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4441 .dac_nids = alc880_asus_dac_nids,
4442 .dig_out_nid = ALC880_DIGOUT_NID,
4443 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4444 .channel_mode = alc880_threestack_modes,
4445 .need_dac_fix = 1,
4446 .input_mux = &alc880_capture_source,
4447 .unsol_event = alc880_uniwill_unsol_event,
4448 .setup = alc880_uniwill_setup,
4449 .init_hook = alc880_uniwill_init_hook,
4450 },
4451 [ALC880_UNIWILL_P53] = {
4452 .mixers = { alc880_uniwill_p53_mixer },
4453 .init_verbs = { alc880_volume_init_verbs,
4454 alc880_uniwill_p53_init_verbs },
4455 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
4456 .dac_nids = alc880_asus_dac_nids,
4457 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
4458 .channel_mode = alc880_threestack_modes,
4459 .input_mux = &alc880_capture_source,
4460 .unsol_event = alc880_uniwill_p53_unsol_event,
4461 .setup = alc880_uniwill_p53_setup,
4462 .init_hook = alc_automute_amp,
4463 },
4464 [ALC880_FUJITSU] = {
4465 .mixers = { alc880_fujitsu_mixer },
4466 .init_verbs = { alc880_volume_init_verbs,
4467 alc880_uniwill_p53_init_verbs,
4468 alc880_beep_init_verbs },
4469 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4470 .dac_nids = alc880_dac_nids,
4471 .dig_out_nid = ALC880_DIGOUT_NID,
4472 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4473 .channel_mode = alc880_2_jack_modes,
4474 .input_mux = &alc880_capture_source,
4475 .unsol_event = alc880_uniwill_p53_unsol_event,
4476 .setup = alc880_uniwill_p53_setup,
4477 .init_hook = alc_automute_amp,
4478 },
4479 [ALC880_CLEVO] = {
4480 .mixers = { alc880_three_stack_mixer },
4481 .init_verbs = { alc880_volume_init_verbs,
4482 alc880_pin_clevo_init_verbs },
4483 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4484 .dac_nids = alc880_dac_nids,
4485 .hp_nid = 0x03,
4486 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4487 .channel_mode = alc880_threestack_modes,
4488 .need_dac_fix = 1,
4489 .input_mux = &alc880_capture_source,
4490 },
4491 [ALC880_LG] = {
4492 .mixers = { alc880_lg_mixer },
4493 .init_verbs = { alc880_volume_init_verbs,
4494 alc880_lg_init_verbs },
4495 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
4496 .dac_nids = alc880_lg_dac_nids,
4497 .dig_out_nid = ALC880_DIGOUT_NID,
4498 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
4499 .channel_mode = alc880_lg_ch_modes,
4500 .need_dac_fix = 1,
4501 .input_mux = &alc880_lg_capture_source,
4502 .unsol_event = alc_automute_amp_unsol_event,
4503 .setup = alc880_lg_setup,
4504 .init_hook = alc_automute_amp,
4505 #ifdef CONFIG_SND_HDA_POWER_SAVE
4506 .loopbacks = alc880_lg_loopbacks,
4507 #endif
4508 },
4509 [ALC880_LG_LW] = {
4510 .mixers = { alc880_lg_lw_mixer },
4511 .init_verbs = { alc880_volume_init_verbs,
4512 alc880_lg_lw_init_verbs },
4513 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4514 .dac_nids = alc880_dac_nids,
4515 .dig_out_nid = ALC880_DIGOUT_NID,
4516 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
4517 .channel_mode = alc880_lg_lw_modes,
4518 .input_mux = &alc880_lg_lw_capture_source,
4519 .unsol_event = alc_automute_amp_unsol_event,
4520 .setup = alc880_lg_lw_setup,
4521 .init_hook = alc_automute_amp,
4522 },
4523 [ALC880_MEDION_RIM] = {
4524 .mixers = { alc880_medion_rim_mixer },
4525 .init_verbs = { alc880_volume_init_verbs,
4526 alc880_medion_rim_init_verbs,
4527 alc_gpio2_init_verbs },
4528 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4529 .dac_nids = alc880_dac_nids,
4530 .dig_out_nid = ALC880_DIGOUT_NID,
4531 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4532 .channel_mode = alc880_2_jack_modes,
4533 .input_mux = &alc880_medion_rim_capture_source,
4534 .unsol_event = alc880_medion_rim_unsol_event,
4535 .setup = alc880_medion_rim_setup,
4536 .init_hook = alc880_medion_rim_automute,
4537 },
4538 #ifdef CONFIG_SND_DEBUG
4539 [ALC880_TEST] = {
4540 .mixers = { alc880_test_mixer },
4541 .init_verbs = { alc880_test_init_verbs },
4542 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
4543 .dac_nids = alc880_test_dac_nids,
4544 .dig_out_nid = ALC880_DIGOUT_NID,
4545 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
4546 .channel_mode = alc880_test_modes,
4547 .input_mux = &alc880_test_capture_source,
4548 },
4549 #endif
4550 };
4551
4552 /*
4553 * Automatic parse of I/O pins from the BIOS configuration
4554 */
4555
4556 enum {
4557 ALC_CTL_WIDGET_VOL,
4558 ALC_CTL_WIDGET_MUTE,
4559 ALC_CTL_BIND_MUTE,
4560 };
4561 static struct snd_kcontrol_new alc880_control_templates[] = {
4562 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
4563 HDA_CODEC_MUTE(NULL, 0, 0, 0),
4564 HDA_BIND_MUTE(NULL, 0, 0, 0),
4565 };
4566
4567 /* add dynamic controls */
4568 static int add_control(struct alc_spec *spec, int type, const char *name,
4569 unsigned long val)
4570 {
4571 struct snd_kcontrol_new *knew;
4572
4573 snd_array_init(&spec->kctls, sizeof(*knew), 32);
4574 knew = snd_array_new(&spec->kctls);
4575 if (!knew)
4576 return -ENOMEM;
4577 *knew = alc880_control_templates[type];
4578 knew->name = kstrdup(name, GFP_KERNEL);
4579 if (!knew->name)
4580 return -ENOMEM;
4581 if (get_amp_nid_(val))
4582 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
4583 knew->private_value = val;
4584 return 0;
4585 }
4586
4587 static int add_control_with_pfx(struct alc_spec *spec, int type,
4588 const char *pfx, const char *dir,
4589 const char *sfx, unsigned long val)
4590 {
4591 char name[32];
4592 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
4593 return add_control(spec, type, name, val);
4594 }
4595
4596 #define add_pb_vol_ctrl(spec, type, pfx, val) \
4597 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", val)
4598 #define add_pb_sw_ctrl(spec, type, pfx, val) \
4599 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", val)
4600
4601 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
4602 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4603 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4604 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4605 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
4606 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
4607 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
4608 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
4609 #define ALC880_PIN_CD_NID 0x1c
4610
4611 /* fill in the dac_nids table from the parsed pin configuration */
4612 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
4613 const struct auto_pin_cfg *cfg)
4614 {
4615 hda_nid_t nid;
4616 int assigned[4];
4617 int i, j;
4618
4619 memset(assigned, 0, sizeof(assigned));
4620 spec->multiout.dac_nids = spec->private_dac_nids;
4621
4622 /* check the pins hardwired to audio widget */
4623 for (i = 0; i < cfg->line_outs; i++) {
4624 nid = cfg->line_out_pins[i];
4625 if (alc880_is_fixed_pin(nid)) {
4626 int idx = alc880_fixed_pin_idx(nid);
4627 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
4628 assigned[idx] = 1;
4629 }
4630 }
4631 /* left pins can be connect to any audio widget */
4632 for (i = 0; i < cfg->line_outs; i++) {
4633 nid = cfg->line_out_pins[i];
4634 if (alc880_is_fixed_pin(nid))
4635 continue;
4636 /* search for an empty channel */
4637 for (j = 0; j < cfg->line_outs; j++) {
4638 if (!assigned[j]) {
4639 spec->multiout.dac_nids[i] =
4640 alc880_idx_to_dac(j);
4641 assigned[j] = 1;
4642 break;
4643 }
4644 }
4645 }
4646 spec->multiout.num_dacs = cfg->line_outs;
4647 return 0;
4648 }
4649
4650 /* add playback controls from the parsed DAC table */
4651 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4652 const struct auto_pin_cfg *cfg)
4653 {
4654 static const char *chname[4] = {
4655 "Front", "Surround", NULL /*CLFE*/, "Side"
4656 };
4657 hda_nid_t nid;
4658 int i, err;
4659
4660 for (i = 0; i < cfg->line_outs; i++) {
4661 if (!spec->multiout.dac_nids[i])
4662 continue;
4663 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
4664 if (i == 2) {
4665 /* Center/LFE */
4666 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4667 "Center",
4668 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
4669 HDA_OUTPUT));
4670 if (err < 0)
4671 return err;
4672 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
4673 "LFE",
4674 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
4675 HDA_OUTPUT));
4676 if (err < 0)
4677 return err;
4678 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4679 "Center",
4680 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
4681 HDA_INPUT));
4682 if (err < 0)
4683 return err;
4684 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
4685 "LFE",
4686 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
4687 HDA_INPUT));
4688 if (err < 0)
4689 return err;
4690 } else {
4691 const char *pfx;
4692 if (cfg->line_outs == 1 &&
4693 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4694 pfx = "Speaker";
4695 else
4696 pfx = chname[i];
4697 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4698 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4699 HDA_OUTPUT));
4700 if (err < 0)
4701 return err;
4702 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4703 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4704 HDA_INPUT));
4705 if (err < 0)
4706 return err;
4707 }
4708 }
4709 return 0;
4710 }
4711
4712 /* add playback controls for speaker and HP outputs */
4713 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
4714 const char *pfx)
4715 {
4716 hda_nid_t nid;
4717 int err;
4718
4719 if (!pin)
4720 return 0;
4721
4722 if (alc880_is_fixed_pin(pin)) {
4723 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
4724 /* specify the DAC as the extra output */
4725 if (!spec->multiout.hp_nid)
4726 spec->multiout.hp_nid = nid;
4727 else
4728 spec->multiout.extra_out_nid[0] = nid;
4729 /* control HP volume/switch on the output mixer amp */
4730 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
4731 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
4732 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
4733 if (err < 0)
4734 return err;
4735 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
4736 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
4737 if (err < 0)
4738 return err;
4739 } else if (alc880_is_multi_pin(pin)) {
4740 /* set manual connection */
4741 /* we have only a switch on HP-out PIN */
4742 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
4743 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4744 if (err < 0)
4745 return err;
4746 }
4747 return 0;
4748 }
4749
4750 /* create input playback/capture controls for the given pin */
4751 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4752 const char *ctlname,
4753 int idx, hda_nid_t mix_nid)
4754 {
4755 int err;
4756
4757 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
4758 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4759 if (err < 0)
4760 return err;
4761 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
4762 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
4763 if (err < 0)
4764 return err;
4765 return 0;
4766 }
4767
4768 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4769 {
4770 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4771 return (pincap & AC_PINCAP_IN) != 0;
4772 }
4773
4774 /* create playback/capture controls for input pins */
4775 static int alc_auto_create_input_ctls(struct hda_codec *codec,
4776 const struct auto_pin_cfg *cfg,
4777 hda_nid_t mixer,
4778 hda_nid_t cap1, hda_nid_t cap2)
4779 {
4780 struct alc_spec *spec = codec->spec;
4781 struct hda_input_mux *imux = &spec->private_imux[0];
4782 int i, err, idx;
4783
4784 for (i = 0; i < AUTO_PIN_LAST; i++) {
4785 hda_nid_t pin;
4786
4787 pin = cfg->input_pins[i];
4788 if (!alc_is_input_pin(codec, pin))
4789 continue;
4790
4791 if (mixer) {
4792 idx = get_connection_index(codec, mixer, pin);
4793 if (idx >= 0) {
4794 err = new_analog_input(spec, pin,
4795 auto_pin_cfg_labels[i],
4796 idx, mixer);
4797 if (err < 0)
4798 return err;
4799 }
4800 }
4801
4802 if (!cap1)
4803 continue;
4804 idx = get_connection_index(codec, cap1, pin);
4805 if (idx < 0 && cap2)
4806 idx = get_connection_index(codec, cap2, pin);
4807 if (idx >= 0) {
4808 imux->items[imux->num_items].label =
4809 auto_pin_cfg_labels[i];
4810 imux->items[imux->num_items].index = idx;
4811 imux->num_items++;
4812 }
4813 }
4814 return 0;
4815 }
4816
4817 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4818 const struct auto_pin_cfg *cfg)
4819 {
4820 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4821 }
4822
4823 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4824 unsigned int pin_type)
4825 {
4826 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4827 pin_type);
4828 /* unmute pin */
4829 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4830 AMP_OUT_UNMUTE);
4831 }
4832
4833 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
4834 hda_nid_t nid, int pin_type,
4835 int dac_idx)
4836 {
4837 alc_set_pin_output(codec, nid, pin_type);
4838 /* need the manual connection? */
4839 if (alc880_is_multi_pin(nid)) {
4840 struct alc_spec *spec = codec->spec;
4841 int idx = alc880_multi_pin_idx(nid);
4842 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
4843 AC_VERB_SET_CONNECT_SEL,
4844 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
4845 }
4846 }
4847
4848 static int get_pin_type(int line_out_type)
4849 {
4850 if (line_out_type == AUTO_PIN_HP_OUT)
4851 return PIN_HP;
4852 else
4853 return PIN_OUT;
4854 }
4855
4856 static void alc880_auto_init_multi_out(struct hda_codec *codec)
4857 {
4858 struct alc_spec *spec = codec->spec;
4859 int i;
4860
4861 for (i = 0; i < spec->autocfg.line_outs; i++) {
4862 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4863 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4864 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
4865 }
4866 }
4867
4868 static void alc880_auto_init_extra_out(struct hda_codec *codec)
4869 {
4870 struct alc_spec *spec = codec->spec;
4871 hda_nid_t pin;
4872
4873 pin = spec->autocfg.speaker_pins[0];
4874 if (pin) /* connect to front */
4875 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
4876 pin = spec->autocfg.hp_pins[0];
4877 if (pin) /* connect to front */
4878 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
4879 }
4880
4881 static void alc880_auto_init_analog_input(struct hda_codec *codec)
4882 {
4883 struct alc_spec *spec = codec->spec;
4884 int i;
4885
4886 for (i = 0; i < AUTO_PIN_LAST; i++) {
4887 hda_nid_t nid = spec->autocfg.input_pins[i];
4888 if (alc_is_input_pin(codec, nid)) {
4889 alc_set_input_pin(codec, nid, i);
4890 if (nid != ALC880_PIN_CD_NID &&
4891 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
4892 snd_hda_codec_write(codec, nid, 0,
4893 AC_VERB_SET_AMP_GAIN_MUTE,
4894 AMP_OUT_MUTE);
4895 }
4896 }
4897 }
4898
4899 /* parse the BIOS configuration and set up the alc_spec */
4900 /* return 1 if successful, 0 if the proper config is not found,
4901 * or a negative error code
4902 */
4903 static int alc880_parse_auto_config(struct hda_codec *codec)
4904 {
4905 struct alc_spec *spec = codec->spec;
4906 int i, err;
4907 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
4908
4909 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4910 alc880_ignore);
4911 if (err < 0)
4912 return err;
4913 if (!spec->autocfg.line_outs)
4914 return 0; /* can't find valid BIOS pin config */
4915
4916 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
4917 if (err < 0)
4918 return err;
4919 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
4920 if (err < 0)
4921 return err;
4922 err = alc880_auto_create_extra_out(spec,
4923 spec->autocfg.speaker_pins[0],
4924 "Speaker");
4925 if (err < 0)
4926 return err;
4927 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
4928 "Headphone");
4929 if (err < 0)
4930 return err;
4931 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4932 if (err < 0)
4933 return err;
4934
4935 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4936
4937 /* check multiple SPDIF-out (for recent codecs) */
4938 for (i = 0; i < spec->autocfg.dig_outs; i++) {
4939 hda_nid_t dig_nid;
4940 err = snd_hda_get_connections(codec,
4941 spec->autocfg.dig_out_pins[i],
4942 &dig_nid, 1);
4943 if (err < 0)
4944 continue;
4945 if (!i)
4946 spec->multiout.dig_out_nid = dig_nid;
4947 else {
4948 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
4949 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
4950 break;
4951 spec->slave_dig_outs[i - 1] = dig_nid;
4952 }
4953 }
4954 if (spec->autocfg.dig_in_pin)
4955 spec->dig_in_nid = ALC880_DIGIN_NID;
4956
4957 if (spec->kctls.list)
4958 add_mixer(spec, spec->kctls.list);
4959
4960 add_verb(spec, alc880_volume_init_verbs);
4961
4962 spec->num_mux_defs = 1;
4963 spec->input_mux = &spec->private_imux[0];
4964
4965 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4966
4967 return 1;
4968 }
4969
4970 /* additional initialization for auto-configuration model */
4971 static void alc880_auto_init(struct hda_codec *codec)
4972 {
4973 struct alc_spec *spec = codec->spec;
4974 alc880_auto_init_multi_out(codec);
4975 alc880_auto_init_extra_out(codec);
4976 alc880_auto_init_analog_input(codec);
4977 if (spec->unsol_event)
4978 alc_inithook(codec);
4979 }
4980
4981 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4982 * one of two digital mic pins, e.g. on ALC272
4983 */
4984 static void fixup_automic_adc(struct hda_codec *codec)
4985 {
4986 struct alc_spec *spec = codec->spec;
4987 int i;
4988
4989 for (i = 0; i < spec->num_adc_nids; i++) {
4990 hda_nid_t cap = spec->capsrc_nids ?
4991 spec->capsrc_nids[i] : spec->adc_nids[i];
4992 int iidx, eidx;
4993
4994 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4995 if (iidx < 0)
4996 continue;
4997 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4998 if (eidx < 0)
4999 continue;
5000 spec->int_mic.mux_idx = iidx;
5001 spec->ext_mic.mux_idx = eidx;
5002 if (spec->capsrc_nids)
5003 spec->capsrc_nids += i;
5004 spec->adc_nids += i;
5005 spec->num_adc_nids = 1;
5006 return;
5007 }
5008 snd_printd(KERN_INFO "hda_codec: %s: "
5009 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5010 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5011 spec->auto_mic = 0; /* disable auto-mic to be sure */
5012 }
5013
5014 /* choose the ADC/MUX containing the input pin and initialize the setup */
5015 static void fixup_single_adc(struct hda_codec *codec)
5016 {
5017 struct alc_spec *spec = codec->spec;
5018 hda_nid_t pin = 0;
5019 int i;
5020
5021 /* search for the input pin; there must be only one */
5022 for (i = 0; i < AUTO_PIN_LAST; i++) {
5023 if (spec->autocfg.input_pins[i]) {
5024 pin = spec->autocfg.input_pins[i];
5025 break;
5026 }
5027 }
5028 if (!pin)
5029 return;
5030
5031 /* set the default connection to that pin */
5032 for (i = 0; i < spec->num_adc_nids; i++) {
5033 hda_nid_t cap = spec->capsrc_nids ?
5034 spec->capsrc_nids[i] : spec->adc_nids[i];
5035 int idx;
5036
5037 idx = get_connection_index(codec, cap, pin);
5038 if (idx < 0)
5039 continue;
5040 /* use only this ADC */
5041 if (spec->capsrc_nids)
5042 spec->capsrc_nids += i;
5043 spec->adc_nids += i;
5044 spec->num_adc_nids = 1;
5045 /* select or unmute this route */
5046 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5047 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5048 HDA_AMP_MUTE, 0);
5049 } else {
5050 snd_hda_codec_write_cache(codec, cap, 0,
5051 AC_VERB_SET_CONNECT_SEL, idx);
5052 }
5053 return;
5054 }
5055 }
5056
5057 static void set_capture_mixer(struct hda_codec *codec)
5058 {
5059 struct alc_spec *spec = codec->spec;
5060 static struct snd_kcontrol_new *caps[2][3] = {
5061 { alc_capture_mixer_nosrc1,
5062 alc_capture_mixer_nosrc2,
5063 alc_capture_mixer_nosrc3 },
5064 { alc_capture_mixer1,
5065 alc_capture_mixer2,
5066 alc_capture_mixer3 },
5067 };
5068 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5069 int mux = 0;
5070 if (spec->auto_mic)
5071 fixup_automic_adc(codec);
5072 else if (spec->input_mux) {
5073 if (spec->input_mux->num_items > 1)
5074 mux = 1;
5075 else if (spec->input_mux->num_items == 1)
5076 fixup_single_adc(codec);
5077 }
5078 spec->cap_mixer = caps[mux][spec->num_adc_nids - 1];
5079 }
5080 }
5081
5082 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5083 static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids,
5084 int num_nids)
5085 {
5086 struct alc_spec *spec = codec->spec;
5087 int n;
5088 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5089
5090 for (n = 0; n < num_nids; n++) {
5091 hda_nid_t adc, cap;
5092 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5093 int nconns, i, j;
5094
5095 adc = nids[n];
5096 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5097 continue;
5098 cap = adc;
5099 nconns = snd_hda_get_connections(codec, cap, conn,
5100 ARRAY_SIZE(conn));
5101 if (nconns == 1) {
5102 cap = conn[0];
5103 nconns = snd_hda_get_connections(codec, cap, conn,
5104 ARRAY_SIZE(conn));
5105 }
5106 if (nconns <= 0)
5107 continue;
5108 if (!fallback_adc) {
5109 fallback_adc = adc;
5110 fallback_cap = cap;
5111 }
5112 for (i = 0; i < AUTO_PIN_LAST; i++) {
5113 hda_nid_t nid = spec->autocfg.input_pins[i];
5114 if (!nid)
5115 continue;
5116 for (j = 0; j < nconns; j++) {
5117 if (conn[j] == nid)
5118 break;
5119 }
5120 if (j >= nconns)
5121 break;
5122 }
5123 if (i >= AUTO_PIN_LAST) {
5124 int num_adcs = spec->num_adc_nids;
5125 spec->private_adc_nids[num_adcs] = adc;
5126 spec->private_capsrc_nids[num_adcs] = cap;
5127 spec->num_adc_nids++;
5128 spec->adc_nids = spec->private_adc_nids;
5129 if (adc != cap)
5130 spec->capsrc_nids = spec->private_capsrc_nids;
5131 }
5132 }
5133 if (!spec->num_adc_nids) {
5134 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5135 " using fallback 0x%x\n",
5136 codec->chip_name, fallback_adc);
5137 spec->private_adc_nids[0] = fallback_adc;
5138 spec->adc_nids = spec->private_adc_nids;
5139 if (fallback_adc != fallback_cap) {
5140 spec->private_capsrc_nids[0] = fallback_cap;
5141 spec->capsrc_nids = spec->private_adc_nids;
5142 }
5143 }
5144 }
5145
5146 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5147 #define set_beep_amp(spec, nid, idx, dir) \
5148 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5149 #else
5150 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5151 #endif
5152
5153 /*
5154 * OK, here we have finally the patch for ALC880
5155 */
5156
5157 static int patch_alc880(struct hda_codec *codec)
5158 {
5159 struct alc_spec *spec;
5160 int board_config;
5161 int err;
5162
5163 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5164 if (spec == NULL)
5165 return -ENOMEM;
5166
5167 codec->spec = spec;
5168
5169 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5170 alc880_models,
5171 alc880_cfg_tbl);
5172 if (board_config < 0) {
5173 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5174 codec->chip_name);
5175 board_config = ALC880_AUTO;
5176 }
5177
5178 if (board_config == ALC880_AUTO) {
5179 /* automatic parse from the BIOS config */
5180 err = alc880_parse_auto_config(codec);
5181 if (err < 0) {
5182 alc_free(codec);
5183 return err;
5184 } else if (!err) {
5185 printk(KERN_INFO
5186 "hda_codec: Cannot set up configuration "
5187 "from BIOS. Using 3-stack mode...\n");
5188 board_config = ALC880_3ST;
5189 }
5190 }
5191
5192 err = snd_hda_attach_beep_device(codec, 0x1);
5193 if (err < 0) {
5194 alc_free(codec);
5195 return err;
5196 }
5197
5198 if (board_config != ALC880_AUTO)
5199 setup_preset(codec, &alc880_presets[board_config]);
5200
5201 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5202 spec->stream_analog_capture = &alc880_pcm_analog_capture;
5203 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
5204
5205 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5206 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5207
5208 if (!spec->adc_nids && spec->input_mux) {
5209 /* check whether NID 0x07 is valid */
5210 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
5211 /* get type */
5212 wcap = get_wcaps_type(wcap);
5213 if (wcap != AC_WID_AUD_IN) {
5214 spec->adc_nids = alc880_adc_nids_alt;
5215 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
5216 } else {
5217 spec->adc_nids = alc880_adc_nids;
5218 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
5219 }
5220 }
5221 set_capture_mixer(codec);
5222 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
5223
5224 spec->vmaster_nid = 0x0c;
5225
5226 codec->patch_ops = alc_patch_ops;
5227 if (board_config == ALC880_AUTO)
5228 spec->init_hook = alc880_auto_init;
5229 #ifdef CONFIG_SND_HDA_POWER_SAVE
5230 if (!spec->loopback.amplist)
5231 spec->loopback.amplist = alc880_loopbacks;
5232 #endif
5233
5234 return 0;
5235 }
5236
5237
5238 /*
5239 * ALC260 support
5240 */
5241
5242 static hda_nid_t alc260_dac_nids[1] = {
5243 /* front */
5244 0x02,
5245 };
5246
5247 static hda_nid_t alc260_adc_nids[1] = {
5248 /* ADC0 */
5249 0x04,
5250 };
5251
5252 static hda_nid_t alc260_adc_nids_alt[1] = {
5253 /* ADC1 */
5254 0x05,
5255 };
5256
5257 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
5258 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5259 */
5260 static hda_nid_t alc260_dual_adc_nids[2] = {
5261 /* ADC0, ADC1 */
5262 0x04, 0x05
5263 };
5264
5265 #define ALC260_DIGOUT_NID 0x03
5266 #define ALC260_DIGIN_NID 0x06
5267
5268 static struct hda_input_mux alc260_capture_source = {
5269 .num_items = 4,
5270 .items = {
5271 { "Mic", 0x0 },
5272 { "Front Mic", 0x1 },
5273 { "Line", 0x2 },
5274 { "CD", 0x4 },
5275 },
5276 };
5277
5278 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
5279 * headphone jack and the internal CD lines since these are the only pins at
5280 * which audio can appear. For flexibility, also allow the option of
5281 * recording the mixer output on the second ADC (ADC0 doesn't have a
5282 * connection to the mixer output).
5283 */
5284 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
5285 {
5286 .num_items = 3,
5287 .items = {
5288 { "Mic/Line", 0x0 },
5289 { "CD", 0x4 },
5290 { "Headphone", 0x2 },
5291 },
5292 },
5293 {
5294 .num_items = 4,
5295 .items = {
5296 { "Mic/Line", 0x0 },
5297 { "CD", 0x4 },
5298 { "Headphone", 0x2 },
5299 { "Mixer", 0x5 },
5300 },
5301 },
5302
5303 };
5304
5305 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
5306 * the Fujitsu S702x, but jacks are marked differently.
5307 */
5308 static struct hda_input_mux alc260_acer_capture_sources[2] = {
5309 {
5310 .num_items = 4,
5311 .items = {
5312 { "Mic", 0x0 },
5313 { "Line", 0x2 },
5314 { "CD", 0x4 },
5315 { "Headphone", 0x5 },
5316 },
5317 },
5318 {
5319 .num_items = 5,
5320 .items = {
5321 { "Mic", 0x0 },
5322 { "Line", 0x2 },
5323 { "CD", 0x4 },
5324 { "Headphone", 0x6 },
5325 { "Mixer", 0x5 },
5326 },
5327 },
5328 };
5329
5330 /* Maxdata Favorit 100XS */
5331 static struct hda_input_mux alc260_favorit100_capture_sources[2] = {
5332 {
5333 .num_items = 2,
5334 .items = {
5335 { "Line/Mic", 0x0 },
5336 { "CD", 0x4 },
5337 },
5338 },
5339 {
5340 .num_items = 3,
5341 .items = {
5342 { "Line/Mic", 0x0 },
5343 { "CD", 0x4 },
5344 { "Mixer", 0x5 },
5345 },
5346 },
5347 };
5348
5349 /*
5350 * This is just place-holder, so there's something for alc_build_pcms to look
5351 * at when it calculates the maximum number of channels. ALC260 has no mixer
5352 * element which allows changing the channel mode, so the verb list is
5353 * never used.
5354 */
5355 static struct hda_channel_mode alc260_modes[1] = {
5356 { 2, NULL },
5357 };
5358
5359
5360 /* Mixer combinations
5361 *
5362 * basic: base_output + input + pc_beep + capture
5363 * HP: base_output + input + capture_alt
5364 * HP_3013: hp_3013 + input + capture
5365 * fujitsu: fujitsu + capture
5366 * acer: acer + capture
5367 */
5368
5369 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
5370 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5371 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5372 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5373 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5374 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5375 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5376 { } /* end */
5377 };
5378
5379 static struct snd_kcontrol_new alc260_input_mixer[] = {
5380 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5381 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5382 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5383 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5384 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5385 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5386 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
5387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
5388 { } /* end */
5389 };
5390
5391 /* update HP, line and mono out pins according to the master switch */
5392 static void alc260_hp_master_update(struct hda_codec *codec,
5393 hda_nid_t hp, hda_nid_t line,
5394 hda_nid_t mono)
5395 {
5396 struct alc_spec *spec = codec->spec;
5397 unsigned int val = spec->master_sw ? PIN_HP : 0;
5398 /* change HP and line-out pins */
5399 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5400 val);
5401 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5402 val);
5403 /* mono (speaker) depending on the HP jack sense */
5404 val = (val && !spec->jack_present) ? PIN_OUT : 0;
5405 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5406 val);
5407 }
5408
5409 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
5410 struct snd_ctl_elem_value *ucontrol)
5411 {
5412 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5413 struct alc_spec *spec = codec->spec;
5414 *ucontrol->value.integer.value = spec->master_sw;
5415 return 0;
5416 }
5417
5418 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
5419 struct snd_ctl_elem_value *ucontrol)
5420 {
5421 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5422 struct alc_spec *spec = codec->spec;
5423 int val = !!*ucontrol->value.integer.value;
5424 hda_nid_t hp, line, mono;
5425
5426 if (val == spec->master_sw)
5427 return 0;
5428 spec->master_sw = val;
5429 hp = (kcontrol->private_value >> 16) & 0xff;
5430 line = (kcontrol->private_value >> 8) & 0xff;
5431 mono = kcontrol->private_value & 0xff;
5432 alc260_hp_master_update(codec, hp, line, mono);
5433 return 1;
5434 }
5435
5436 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
5437 {
5438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5439 .name = "Master Playback Switch",
5440 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5441 .info = snd_ctl_boolean_mono_info,
5442 .get = alc260_hp_master_sw_get,
5443 .put = alc260_hp_master_sw_put,
5444 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
5445 },
5446 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5447 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
5448 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5449 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
5450 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5451 HDA_OUTPUT),
5452 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
5453 { } /* end */
5454 };
5455
5456 static struct hda_verb alc260_hp_unsol_verbs[] = {
5457 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5458 {},
5459 };
5460
5461 static void alc260_hp_automute(struct hda_codec *codec)
5462 {
5463 struct alc_spec *spec = codec->spec;
5464
5465 spec->jack_present = snd_hda_jack_detect(codec, 0x10);
5466 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
5467 }
5468
5469 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
5470 {
5471 if ((res >> 26) == ALC880_HP_EVENT)
5472 alc260_hp_automute(codec);
5473 }
5474
5475 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
5476 {
5477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5478 .name = "Master Playback Switch",
5479 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
5480 .info = snd_ctl_boolean_mono_info,
5481 .get = alc260_hp_master_sw_get,
5482 .put = alc260_hp_master_sw_put,
5483 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
5484 },
5485 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5486 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5487 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
5488 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
5489 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5490 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5491 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
5492 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
5493 { } /* end */
5494 };
5495
5496 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
5497 .ops = &snd_hda_bind_vol,
5498 .values = {
5499 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
5500 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
5501 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
5502 0
5503 },
5504 };
5505
5506 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
5507 .ops = &snd_hda_bind_sw,
5508 .values = {
5509 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
5510 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
5511 0
5512 },
5513 };
5514
5515 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
5516 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
5517 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
5518 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
5519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
5520 { } /* end */
5521 };
5522
5523 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
5524 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
5525 {},
5526 };
5527
5528 static void alc260_hp_3013_automute(struct hda_codec *codec)
5529 {
5530 struct alc_spec *spec = codec->spec;
5531
5532 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
5533 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
5534 }
5535
5536 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
5537 unsigned int res)
5538 {
5539 if ((res >> 26) == ALC880_HP_EVENT)
5540 alc260_hp_3013_automute(codec);
5541 }
5542
5543 static void alc260_hp_3012_automute(struct hda_codec *codec)
5544 {
5545 unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
5546
5547 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5548 bits);
5549 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5550 bits);
5551 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5552 bits);
5553 }
5554
5555 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
5556 unsigned int res)
5557 {
5558 if ((res >> 26) == ALC880_HP_EVENT)
5559 alc260_hp_3012_automute(codec);
5560 }
5561
5562 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
5563 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
5564 */
5565 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
5566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5567 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
5568 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5569 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5570 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5571 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
5572 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
5573 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
5574 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
5575 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
5576 { } /* end */
5577 };
5578
5579 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
5580 * versions of the ALC260 don't act on requests to enable mic bias from NID
5581 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
5582 * datasheet doesn't mention this restriction. At this stage it's not clear
5583 * whether this behaviour is intentional or is a hardware bug in chip
5584 * revisions available in early 2006. Therefore for now allow the
5585 * "Headphone Jack Mode" control to span all choices, but if it turns out
5586 * that the lack of mic bias for this NID is intentional we could change the
5587 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
5588 *
5589 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
5590 * don't appear to make the mic bias available from the "line" jack, even
5591 * though the NID used for this jack (0x14) can supply it. The theory is
5592 * that perhaps Acer have included blocking capacitors between the ALC260
5593 * and the output jack. If this turns out to be the case for all such
5594 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
5595 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
5596 *
5597 * The C20x Tablet series have a mono internal speaker which is controlled
5598 * via the chip's Mono sum widget and pin complex, so include the necessary
5599 * controls for such models. On models without a "mono speaker" the control
5600 * won't do anything.
5601 */
5602 static struct snd_kcontrol_new alc260_acer_mixer[] = {
5603 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5604 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5605 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5606 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
5607 HDA_OUTPUT),
5608 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
5609 HDA_INPUT),
5610 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5611 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5612 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5613 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5614 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5615 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5616 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5617 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5618 { } /* end */
5619 };
5620
5621 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
5622 */
5623 static struct snd_kcontrol_new alc260_favorit100_mixer[] = {
5624 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5625 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
5626 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
5627 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5628 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5629 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5630 { } /* end */
5631 };
5632
5633 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
5634 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
5635 */
5636 static struct snd_kcontrol_new alc260_will_mixer[] = {
5637 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5638 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5640 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5641 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5642 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5643 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5644 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5645 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
5646 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
5647 { } /* end */
5648 };
5649
5650 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
5651 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
5652 */
5653 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
5654 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
5655 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
5656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
5657 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
5658 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
5659 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
5660 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
5661 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
5662 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
5663 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
5664 { } /* end */
5665 };
5666
5667 /*
5668 * initialization verbs
5669 */
5670 static struct hda_verb alc260_init_verbs[] = {
5671 /* Line In pin widget for input */
5672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5673 /* CD pin widget for input */
5674 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5675 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5676 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5677 /* Mic2 (front panel) pin widget for input and vref at 80% */
5678 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5679 /* LINE-2 is used for line-out in rear */
5680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5681 /* select line-out */
5682 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
5683 /* LINE-OUT pin */
5684 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5685 /* enable HP */
5686 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5687 /* enable Mono */
5688 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5689 /* mute capture amp left and right */
5690 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5691 /* set connection select to line in (default select for this ADC) */
5692 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5693 /* mute capture amp left and right */
5694 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5695 /* set connection select to line in (default select for this ADC) */
5696 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
5697 /* set vol=0 Line-Out mixer amp left and right */
5698 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5699 /* unmute pin widget amp left and right (no gain on this amp) */
5700 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5701 /* set vol=0 HP mixer amp left and right */
5702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5703 /* unmute pin widget amp left and right (no gain on this amp) */
5704 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5705 /* set vol=0 Mono mixer amp left and right */
5706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5707 /* unmute pin widget amp left and right (no gain on this amp) */
5708 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5709 /* unmute LINE-2 out pin */
5710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5711 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5712 * Line In 2 = 0x03
5713 */
5714 /* mute analog inputs */
5715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5719 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5720 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5721 /* mute Front out path */
5722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5723 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5724 /* mute Headphone out path */
5725 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5726 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5727 /* mute Mono out path */
5728 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5729 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5730 { }
5731 };
5732
5733 #if 0 /* should be identical with alc260_init_verbs? */
5734 static struct hda_verb alc260_hp_init_verbs[] = {
5735 /* Headphone and output */
5736 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5737 /* mono output */
5738 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5739 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5740 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5741 /* Mic2 (front panel) pin widget for input and vref at 80% */
5742 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5743 /* Line In pin widget for input */
5744 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5745 /* Line-2 pin widget for output */
5746 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5747 /* CD pin widget for input */
5748 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5749 /* unmute amp left and right */
5750 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5751 /* set connection select to line in (default select for this ADC) */
5752 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5753 /* unmute Line-Out mixer amp left and right (volume = 0) */
5754 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5755 /* mute pin widget amp left and right (no gain on this amp) */
5756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5757 /* unmute HP mixer amp left and right (volume = 0) */
5758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5759 /* mute pin widget amp left and right (no gain on this amp) */
5760 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5761 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5762 * Line In 2 = 0x03
5763 */
5764 /* mute analog inputs */
5765 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5766 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5768 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5769 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5770 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5771 /* Unmute Front out path */
5772 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5773 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5774 /* Unmute Headphone out path */
5775 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5776 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5777 /* Unmute Mono out path */
5778 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5779 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5780 { }
5781 };
5782 #endif
5783
5784 static struct hda_verb alc260_hp_3013_init_verbs[] = {
5785 /* Line out and output */
5786 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5787 /* mono output */
5788 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
5789 /* Mic1 (rear panel) pin widget for input and vref at 80% */
5790 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5791 /* Mic2 (front panel) pin widget for input and vref at 80% */
5792 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
5793 /* Line In pin widget for input */
5794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5795 /* Headphone pin widget for output */
5796 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
5797 /* CD pin widget for input */
5798 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
5799 /* unmute amp left and right */
5800 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
5801 /* set connection select to line in (default select for this ADC) */
5802 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
5803 /* unmute Line-Out mixer amp left and right (volume = 0) */
5804 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5805 /* mute pin widget amp left and right (no gain on this amp) */
5806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5807 /* unmute HP mixer amp left and right (volume = 0) */
5808 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
5809 /* mute pin widget amp left and right (no gain on this amp) */
5810 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
5811 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
5812 * Line In 2 = 0x03
5813 */
5814 /* mute analog inputs */
5815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5820 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
5821 /* Unmute Front out path */
5822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5824 /* Unmute Headphone out path */
5825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5827 /* Unmute Mono out path */
5828 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
5830 { }
5831 };
5832
5833 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
5834 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
5835 * audio = 0x16, internal speaker = 0x10.
5836 */
5837 static struct hda_verb alc260_fujitsu_init_verbs[] = {
5838 /* Disable all GPIOs */
5839 {0x01, AC_VERB_SET_GPIO_MASK, 0},
5840 /* Internal speaker is connected to headphone pin */
5841 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5842 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
5843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5844 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
5845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5846 /* Ensure all other unused pins are disabled and muted. */
5847 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5848 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5849 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5850 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5851 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5852 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5853 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5854 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5855
5856 /* Disable digital (SPDIF) pins */
5857 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5858 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5859
5860 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
5861 * when acting as an output.
5862 */
5863 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5864
5865 /* Start with output sum widgets muted and their output gains at min */
5866 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5867 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5868 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5869 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5870 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5871 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5872 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5873 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5874 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5875
5876 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
5877 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5878 /* Unmute Line1 pin widget output buffer since it starts as an output.
5879 * If the pin mode is changed by the user the pin mode control will
5880 * take care of enabling the pin's input/output buffers as needed.
5881 * Therefore there's no need to enable the input buffer at this
5882 * stage.
5883 */
5884 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5885 /* Unmute input buffer of pin widget used for Line-in (no equiv
5886 * mixer ctrl)
5887 */
5888 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5889
5890 /* Mute capture amp left and right */
5891 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5892 /* Set ADC connection select to match default mixer setting - line
5893 * in (on mic1 pin)
5894 */
5895 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5896
5897 /* Do the same for the second ADC: mute capture input amp and
5898 * set ADC connection to line in (on mic1 pin)
5899 */
5900 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5901 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5902
5903 /* Mute all inputs to mixer widget (even unconnected ones) */
5904 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5905 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5906 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5912
5913 { }
5914 };
5915
5916 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
5917 * similar laptops (adapted from Fujitsu init verbs).
5918 */
5919 static struct hda_verb alc260_acer_init_verbs[] = {
5920 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
5921 * the headphone jack. Turn this on and rely on the standard mute
5922 * methods whenever the user wants to turn these outputs off.
5923 */
5924 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
5925 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
5926 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
5927 /* Internal speaker/Headphone jack is connected to Line-out pin */
5928 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5929 /* Internal microphone/Mic jack is connected to Mic1 pin */
5930 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
5931 /* Line In jack is connected to Line1 pin */
5932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5933 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
5934 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5935 /* Ensure all other unused pins are disabled and muted. */
5936 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5937 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5938 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5939 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
5941 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5942 /* Disable digital (SPDIF) pins */
5943 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5944 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5945
5946 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
5947 * bus when acting as outputs.
5948 */
5949 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5950 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5951
5952 /* Start with output sum widgets muted and their output gains at min */
5953 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5955 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5956 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5959 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5961 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5962
5963 /* Unmute Line-out pin widget amp left and right
5964 * (no equiv mixer ctrl)
5965 */
5966 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5967 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
5968 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5969 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
5970 * inputs. If the pin mode is changed by the user the pin mode control
5971 * will take care of enabling the pin's input/output buffers as needed.
5972 * Therefore there's no need to enable the input buffer at this
5973 * stage.
5974 */
5975 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5976 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5977
5978 /* Mute capture amp left and right */
5979 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5980 /* Set ADC connection select to match default mixer setting - mic
5981 * (on mic1 pin)
5982 */
5983 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5984
5985 /* Do similar with the second ADC: mute capture input amp and
5986 * set ADC connection to mic to match ALSA's default state.
5987 */
5988 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5989 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5990
5991 /* Mute all inputs to mixer widget (even unconnected ones) */
5992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5998 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5999 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6000
6001 { }
6002 };
6003
6004 /* Initialisation sequence for Maxdata Favorit 100XS
6005 * (adapted from Acer init verbs).
6006 */
6007 static struct hda_verb alc260_favorit100_init_verbs[] = {
6008 /* GPIO 0 enables the output jack.
6009 * Turn this on and rely on the standard mute
6010 * methods whenever the user wants to turn these outputs off.
6011 */
6012 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6013 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6014 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6015 /* Line/Mic input jack is connected to Mic1 pin */
6016 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6017 /* Ensure all other unused pins are disabled and muted. */
6018 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6019 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6020 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6021 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6022 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6023 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6024 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6025 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6028 /* Disable digital (SPDIF) pins */
6029 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6030 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6031
6032 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6033 * bus when acting as outputs.
6034 */
6035 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6036 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6037
6038 /* Start with output sum widgets muted and their output gains at min */
6039 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6042 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6045 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6046 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6047 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6048
6049 /* Unmute Line-out pin widget amp left and right
6050 * (no equiv mixer ctrl)
6051 */
6052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6053 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6054 * inputs. If the pin mode is changed by the user the pin mode control
6055 * will take care of enabling the pin's input/output buffers as needed.
6056 * Therefore there's no need to enable the input buffer at this
6057 * stage.
6058 */
6059 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6060
6061 /* Mute capture amp left and right */
6062 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6063 /* Set ADC connection select to match default mixer setting - mic
6064 * (on mic1 pin)
6065 */
6066 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6067
6068 /* Do similar with the second ADC: mute capture input amp and
6069 * set ADC connection to mic to match ALSA's default state.
6070 */
6071 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6072 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6073
6074 /* Mute all inputs to mixer widget (even unconnected ones) */
6075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6076 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6077 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6083
6084 { }
6085 };
6086
6087 static struct hda_verb alc260_will_verbs[] = {
6088 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6089 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6090 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6091 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6092 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6093 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6094 {}
6095 };
6096
6097 static struct hda_verb alc260_replacer_672v_verbs[] = {
6098 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6099 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6100 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6101
6102 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6103 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6104 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6105
6106 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6107 {}
6108 };
6109
6110 /* toggle speaker-output according to the hp-jack state */
6111 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6112 {
6113 unsigned int present;
6114
6115 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6116 present = snd_hda_jack_detect(codec, 0x0f);
6117 if (present) {
6118 snd_hda_codec_write_cache(codec, 0x01, 0,
6119 AC_VERB_SET_GPIO_DATA, 1);
6120 snd_hda_codec_write_cache(codec, 0x0f, 0,
6121 AC_VERB_SET_PIN_WIDGET_CONTROL,
6122 PIN_HP);
6123 } else {
6124 snd_hda_codec_write_cache(codec, 0x01, 0,
6125 AC_VERB_SET_GPIO_DATA, 0);
6126 snd_hda_codec_write_cache(codec, 0x0f, 0,
6127 AC_VERB_SET_PIN_WIDGET_CONTROL,
6128 PIN_OUT);
6129 }
6130 }
6131
6132 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6133 unsigned int res)
6134 {
6135 if ((res >> 26) == ALC880_HP_EVENT)
6136 alc260_replacer_672v_automute(codec);
6137 }
6138
6139 static struct hda_verb alc260_hp_dc7600_verbs[] = {
6140 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6141 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6142 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6143 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6144 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6146 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6147 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6148 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6149 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6150 {}
6151 };
6152
6153 /* Test configuration for debugging, modelled after the ALC880 test
6154 * configuration.
6155 */
6156 #ifdef CONFIG_SND_DEBUG
6157 static hda_nid_t alc260_test_dac_nids[1] = {
6158 0x02,
6159 };
6160 static hda_nid_t alc260_test_adc_nids[2] = {
6161 0x04, 0x05,
6162 };
6163 /* For testing the ALC260, each input MUX needs its own definition since
6164 * the signal assignments are different. This assumes that the first ADC
6165 * is NID 0x04.
6166 */
6167 static struct hda_input_mux alc260_test_capture_sources[2] = {
6168 {
6169 .num_items = 7,
6170 .items = {
6171 { "MIC1 pin", 0x0 },
6172 { "MIC2 pin", 0x1 },
6173 { "LINE1 pin", 0x2 },
6174 { "LINE2 pin", 0x3 },
6175 { "CD pin", 0x4 },
6176 { "LINE-OUT pin", 0x5 },
6177 { "HP-OUT pin", 0x6 },
6178 },
6179 },
6180 {
6181 .num_items = 8,
6182 .items = {
6183 { "MIC1 pin", 0x0 },
6184 { "MIC2 pin", 0x1 },
6185 { "LINE1 pin", 0x2 },
6186 { "LINE2 pin", 0x3 },
6187 { "CD pin", 0x4 },
6188 { "Mixer", 0x5 },
6189 { "LINE-OUT pin", 0x6 },
6190 { "HP-OUT pin", 0x7 },
6191 },
6192 },
6193 };
6194 static struct snd_kcontrol_new alc260_test_mixer[] = {
6195 /* Output driver widgets */
6196 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6197 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6198 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6199 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6200 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6201 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6202
6203 /* Modes for retasking pin widgets
6204 * Note: the ALC260 doesn't seem to act on requests to enable mic
6205 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6206 * mention this restriction. At this stage it's not clear whether
6207 * this behaviour is intentional or is a hardware bug in chip
6208 * revisions available at least up until early 2006. Therefore for
6209 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6210 * choices, but if it turns out that the lack of mic bias for these
6211 * NIDs is intentional we could change their modes from
6212 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6213 */
6214 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6215 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6216 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6217 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6218 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6219 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6220
6221 /* Loopback mixer controls */
6222 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6223 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6224 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6225 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6226 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6227 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6228 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6229 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6230 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6231 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6232 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6233 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6234 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6235 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6236
6237 /* Controls for GPIO pins, assuming they are configured as outputs */
6238 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6239 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6240 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6241 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6242
6243 /* Switches to allow the digital IO pins to be enabled. The datasheet
6244 * is ambigious as to which NID is which; testing on laptops which
6245 * make this output available should provide clarification.
6246 */
6247 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6248 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6249
6250 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6251 * this output to turn on an external amplifier.
6252 */
6253 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6254 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6255
6256 { } /* end */
6257 };
6258 static struct hda_verb alc260_test_init_verbs[] = {
6259 /* Enable all GPIOs as outputs with an initial value of 0 */
6260 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6261 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6262 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6263
6264 /* Enable retasking pins as output, initially without power amp */
6265 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6266 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6267 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6269 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6270 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6271
6272 /* Disable digital (SPDIF) pins initially, but users can enable
6273 * them via a mixer switch. In the case of SPDIF-out, this initverb
6274 * payload also sets the generation to 0, output to be in "consumer"
6275 * PCM format, copyright asserted, no pre-emphasis and no validity
6276 * control.
6277 */
6278 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6279 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6280
6281 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6282 * OUT1 sum bus when acting as an output.
6283 */
6284 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6285 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6286 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6287 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6288
6289 /* Start with output sum widgets muted and their output gains at min */
6290 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6292 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6293 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6294 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6295 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6296 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6297 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6298 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6299
6300 /* Unmute retasking pin widget output buffers since the default
6301 * state appears to be output. As the pin mode is changed by the
6302 * user the pin mode control will take care of enabling the pin's
6303 * input/output buffers as needed.
6304 */
6305 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6306 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6307 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6308 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6309 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6310 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6311 /* Also unmute the mono-out pin widget */
6312 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6313
6314 /* Mute capture amp left and right */
6315 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6316 /* Set ADC connection select to match default mixer setting (mic1
6317 * pin)
6318 */
6319 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6320
6321 /* Do the same for the second ADC: mute capture input amp and
6322 * set ADC connection to mic1 pin
6323 */
6324 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6325 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6326
6327 /* Mute all inputs to mixer widget (even unconnected ones) */
6328 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6329 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6330 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6331 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6332 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6333 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6334 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6335 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6336
6337 { }
6338 };
6339 #endif
6340
6341 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
6342 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
6343
6344 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
6345 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
6346
6347 /*
6348 * for BIOS auto-configuration
6349 */
6350
6351 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
6352 const char *pfx, int *vol_bits)
6353 {
6354 hda_nid_t nid_vol;
6355 unsigned long vol_val, sw_val;
6356 int err;
6357
6358 if (nid >= 0x0f && nid < 0x11) {
6359 nid_vol = nid - 0x7;
6360 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6361 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6362 } else if (nid == 0x11) {
6363 nid_vol = nid - 0x7;
6364 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
6365 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
6366 } else if (nid >= 0x12 && nid <= 0x15) {
6367 nid_vol = 0x08;
6368 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
6369 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
6370 } else
6371 return 0; /* N/A */
6372
6373 if (!(*vol_bits & (1 << nid_vol))) {
6374 /* first control for the volume widget */
6375 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
6376 if (err < 0)
6377 return err;
6378 *vol_bits |= (1 << nid_vol);
6379 }
6380 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
6381 if (err < 0)
6382 return err;
6383 return 1;
6384 }
6385
6386 /* add playback controls from the parsed DAC table */
6387 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
6388 const struct auto_pin_cfg *cfg)
6389 {
6390 hda_nid_t nid;
6391 int err;
6392 int vols = 0;
6393
6394 spec->multiout.num_dacs = 1;
6395 spec->multiout.dac_nids = spec->private_dac_nids;
6396 spec->multiout.dac_nids[0] = 0x02;
6397
6398 nid = cfg->line_out_pins[0];
6399 if (nid) {
6400 const char *pfx;
6401 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6402 pfx = "Master";
6403 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6404 pfx = "Speaker";
6405 else
6406 pfx = "Front";
6407 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
6408 if (err < 0)
6409 return err;
6410 }
6411
6412 nid = cfg->speaker_pins[0];
6413 if (nid) {
6414 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
6415 if (err < 0)
6416 return err;
6417 }
6418
6419 nid = cfg->hp_pins[0];
6420 if (nid) {
6421 err = alc260_add_playback_controls(spec, nid, "Headphone",
6422 &vols);
6423 if (err < 0)
6424 return err;
6425 }
6426 return 0;
6427 }
6428
6429 /* create playback/capture controls for input pins */
6430 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
6431 const struct auto_pin_cfg *cfg)
6432 {
6433 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
6434 }
6435
6436 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
6437 hda_nid_t nid, int pin_type,
6438 int sel_idx)
6439 {
6440 alc_set_pin_output(codec, nid, pin_type);
6441 /* need the manual connection? */
6442 if (nid >= 0x12) {
6443 int idx = nid - 0x12;
6444 snd_hda_codec_write(codec, idx + 0x0b, 0,
6445 AC_VERB_SET_CONNECT_SEL, sel_idx);
6446 }
6447 }
6448
6449 static void alc260_auto_init_multi_out(struct hda_codec *codec)
6450 {
6451 struct alc_spec *spec = codec->spec;
6452 hda_nid_t nid;
6453
6454 nid = spec->autocfg.line_out_pins[0];
6455 if (nid) {
6456 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6457 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
6458 }
6459
6460 nid = spec->autocfg.speaker_pins[0];
6461 if (nid)
6462 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
6463
6464 nid = spec->autocfg.hp_pins[0];
6465 if (nid)
6466 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
6467 }
6468
6469 #define ALC260_PIN_CD_NID 0x16
6470 static void alc260_auto_init_analog_input(struct hda_codec *codec)
6471 {
6472 struct alc_spec *spec = codec->spec;
6473 int i;
6474
6475 for (i = 0; i < AUTO_PIN_LAST; i++) {
6476 hda_nid_t nid = spec->autocfg.input_pins[i];
6477 if (nid >= 0x12) {
6478 alc_set_input_pin(codec, nid, i);
6479 if (nid != ALC260_PIN_CD_NID &&
6480 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
6481 snd_hda_codec_write(codec, nid, 0,
6482 AC_VERB_SET_AMP_GAIN_MUTE,
6483 AMP_OUT_MUTE);
6484 }
6485 }
6486 }
6487
6488 /*
6489 * generic initialization of ADC, input mixers and output mixers
6490 */
6491 static struct hda_verb alc260_volume_init_verbs[] = {
6492 /*
6493 * Unmute ADC0-1 and set the default input to mic-in
6494 */
6495 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6496 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6497 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6498 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6499
6500 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6501 * mixer widget
6502 * Note: PASD motherboards uses the Line In 2 as the input for
6503 * front panel mic (mic 2)
6504 */
6505 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6506 /* mute analog inputs */
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6508 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6509 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6510 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6511 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6512
6513 /*
6514 * Set up output mixers (0x08 - 0x0a)
6515 */
6516 /* set vol=0 to output mixers */
6517 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6518 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6519 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6520 /* set up input amps for analog loopback */
6521 /* Amp Indices: DAC = 0, mixer = 1 */
6522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6524 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6526 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6527 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6528
6529 { }
6530 };
6531
6532 static int alc260_parse_auto_config(struct hda_codec *codec)
6533 {
6534 struct alc_spec *spec = codec->spec;
6535 int err;
6536 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
6537
6538 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
6539 alc260_ignore);
6540 if (err < 0)
6541 return err;
6542 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
6543 if (err < 0)
6544 return err;
6545 if (!spec->kctls.list)
6546 return 0; /* can't find valid BIOS pin config */
6547 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6548 if (err < 0)
6549 return err;
6550
6551 spec->multiout.max_channels = 2;
6552
6553 if (spec->autocfg.dig_outs)
6554 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
6555 if (spec->kctls.list)
6556 add_mixer(spec, spec->kctls.list);
6557
6558 add_verb(spec, alc260_volume_init_verbs);
6559
6560 spec->num_mux_defs = 1;
6561 spec->input_mux = &spec->private_imux[0];
6562
6563 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6564
6565 return 1;
6566 }
6567
6568 /* additional initialization for auto-configuration model */
6569 static void alc260_auto_init(struct hda_codec *codec)
6570 {
6571 struct alc_spec *spec = codec->spec;
6572 alc260_auto_init_multi_out(codec);
6573 alc260_auto_init_analog_input(codec);
6574 if (spec->unsol_event)
6575 alc_inithook(codec);
6576 }
6577
6578 #ifdef CONFIG_SND_HDA_POWER_SAVE
6579 static struct hda_amp_list alc260_loopbacks[] = {
6580 { 0x07, HDA_INPUT, 0 },
6581 { 0x07, HDA_INPUT, 1 },
6582 { 0x07, HDA_INPUT, 2 },
6583 { 0x07, HDA_INPUT, 3 },
6584 { 0x07, HDA_INPUT, 4 },
6585 { } /* end */
6586 };
6587 #endif
6588
6589 /*
6590 * ALC260 configurations
6591 */
6592 static const char *alc260_models[ALC260_MODEL_LAST] = {
6593 [ALC260_BASIC] = "basic",
6594 [ALC260_HP] = "hp",
6595 [ALC260_HP_3013] = "hp-3013",
6596 [ALC260_HP_DC7600] = "hp-dc7600",
6597 [ALC260_FUJITSU_S702X] = "fujitsu",
6598 [ALC260_ACER] = "acer",
6599 [ALC260_WILL] = "will",
6600 [ALC260_REPLACER_672V] = "replacer",
6601 [ALC260_FAVORIT100] = "favorit100",
6602 #ifdef CONFIG_SND_DEBUG
6603 [ALC260_TEST] = "test",
6604 #endif
6605 [ALC260_AUTO] = "auto",
6606 };
6607
6608 static struct snd_pci_quirk alc260_cfg_tbl[] = {
6609 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
6610 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
6611 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
6612 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
6613 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
6614 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
6615 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
6616 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
6617 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
6618 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
6619 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
6620 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
6621 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
6622 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
6623 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
6624 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
6625 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
6626 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
6627 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
6628 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
6629 {}
6630 };
6631
6632 static struct alc_config_preset alc260_presets[] = {
6633 [ALC260_BASIC] = {
6634 .mixers = { alc260_base_output_mixer,
6635 alc260_input_mixer },
6636 .init_verbs = { alc260_init_verbs },
6637 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6638 .dac_nids = alc260_dac_nids,
6639 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6640 .adc_nids = alc260_dual_adc_nids,
6641 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6642 .channel_mode = alc260_modes,
6643 .input_mux = &alc260_capture_source,
6644 },
6645 [ALC260_HP] = {
6646 .mixers = { alc260_hp_output_mixer,
6647 alc260_input_mixer },
6648 .init_verbs = { alc260_init_verbs,
6649 alc260_hp_unsol_verbs },
6650 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6651 .dac_nids = alc260_dac_nids,
6652 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6653 .adc_nids = alc260_adc_nids_alt,
6654 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6655 .channel_mode = alc260_modes,
6656 .input_mux = &alc260_capture_source,
6657 .unsol_event = alc260_hp_unsol_event,
6658 .init_hook = alc260_hp_automute,
6659 },
6660 [ALC260_HP_DC7600] = {
6661 .mixers = { alc260_hp_dc7600_mixer,
6662 alc260_input_mixer },
6663 .init_verbs = { alc260_init_verbs,
6664 alc260_hp_dc7600_verbs },
6665 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6666 .dac_nids = alc260_dac_nids,
6667 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6668 .adc_nids = alc260_adc_nids_alt,
6669 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6670 .channel_mode = alc260_modes,
6671 .input_mux = &alc260_capture_source,
6672 .unsol_event = alc260_hp_3012_unsol_event,
6673 .init_hook = alc260_hp_3012_automute,
6674 },
6675 [ALC260_HP_3013] = {
6676 .mixers = { alc260_hp_3013_mixer,
6677 alc260_input_mixer },
6678 .init_verbs = { alc260_hp_3013_init_verbs,
6679 alc260_hp_3013_unsol_verbs },
6680 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6681 .dac_nids = alc260_dac_nids,
6682 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
6683 .adc_nids = alc260_adc_nids_alt,
6684 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6685 .channel_mode = alc260_modes,
6686 .input_mux = &alc260_capture_source,
6687 .unsol_event = alc260_hp_3013_unsol_event,
6688 .init_hook = alc260_hp_3013_automute,
6689 },
6690 [ALC260_FUJITSU_S702X] = {
6691 .mixers = { alc260_fujitsu_mixer },
6692 .init_verbs = { alc260_fujitsu_init_verbs },
6693 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6694 .dac_nids = alc260_dac_nids,
6695 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6696 .adc_nids = alc260_dual_adc_nids,
6697 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6698 .channel_mode = alc260_modes,
6699 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
6700 .input_mux = alc260_fujitsu_capture_sources,
6701 },
6702 [ALC260_ACER] = {
6703 .mixers = { alc260_acer_mixer },
6704 .init_verbs = { alc260_acer_init_verbs },
6705 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6706 .dac_nids = alc260_dac_nids,
6707 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6708 .adc_nids = alc260_dual_adc_nids,
6709 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6710 .channel_mode = alc260_modes,
6711 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
6712 .input_mux = alc260_acer_capture_sources,
6713 },
6714 [ALC260_FAVORIT100] = {
6715 .mixers = { alc260_favorit100_mixer },
6716 .init_verbs = { alc260_favorit100_init_verbs },
6717 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6718 .dac_nids = alc260_dac_nids,
6719 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
6720 .adc_nids = alc260_dual_adc_nids,
6721 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6722 .channel_mode = alc260_modes,
6723 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
6724 .input_mux = alc260_favorit100_capture_sources,
6725 },
6726 [ALC260_WILL] = {
6727 .mixers = { alc260_will_mixer },
6728 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
6729 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6730 .dac_nids = alc260_dac_nids,
6731 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6732 .adc_nids = alc260_adc_nids,
6733 .dig_out_nid = ALC260_DIGOUT_NID,
6734 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6735 .channel_mode = alc260_modes,
6736 .input_mux = &alc260_capture_source,
6737 },
6738 [ALC260_REPLACER_672V] = {
6739 .mixers = { alc260_replacer_672v_mixer },
6740 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
6741 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
6742 .dac_nids = alc260_dac_nids,
6743 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
6744 .adc_nids = alc260_adc_nids,
6745 .dig_out_nid = ALC260_DIGOUT_NID,
6746 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6747 .channel_mode = alc260_modes,
6748 .input_mux = &alc260_capture_source,
6749 .unsol_event = alc260_replacer_672v_unsol_event,
6750 .init_hook = alc260_replacer_672v_automute,
6751 },
6752 #ifdef CONFIG_SND_DEBUG
6753 [ALC260_TEST] = {
6754 .mixers = { alc260_test_mixer },
6755 .init_verbs = { alc260_test_init_verbs },
6756 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
6757 .dac_nids = alc260_test_dac_nids,
6758 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
6759 .adc_nids = alc260_test_adc_nids,
6760 .num_channel_mode = ARRAY_SIZE(alc260_modes),
6761 .channel_mode = alc260_modes,
6762 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
6763 .input_mux = alc260_test_capture_sources,
6764 },
6765 #endif
6766 };
6767
6768 static int patch_alc260(struct hda_codec *codec)
6769 {
6770 struct alc_spec *spec;
6771 int err, board_config;
6772
6773 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6774 if (spec == NULL)
6775 return -ENOMEM;
6776
6777 codec->spec = spec;
6778
6779 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
6780 alc260_models,
6781 alc260_cfg_tbl);
6782 if (board_config < 0) {
6783 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6784 codec->chip_name);
6785 board_config = ALC260_AUTO;
6786 }
6787
6788 if (board_config == ALC260_AUTO) {
6789 /* automatic parse from the BIOS config */
6790 err = alc260_parse_auto_config(codec);
6791 if (err < 0) {
6792 alc_free(codec);
6793 return err;
6794 } else if (!err) {
6795 printk(KERN_INFO
6796 "hda_codec: Cannot set up configuration "
6797 "from BIOS. Using base mode...\n");
6798 board_config = ALC260_BASIC;
6799 }
6800 }
6801
6802 err = snd_hda_attach_beep_device(codec, 0x1);
6803 if (err < 0) {
6804 alc_free(codec);
6805 return err;
6806 }
6807
6808 if (board_config != ALC260_AUTO)
6809 setup_preset(codec, &alc260_presets[board_config]);
6810
6811 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6812 spec->stream_analog_capture = &alc260_pcm_analog_capture;
6813
6814 spec->stream_digital_playback = &alc260_pcm_digital_playback;
6815 spec->stream_digital_capture = &alc260_pcm_digital_capture;
6816
6817 if (!spec->adc_nids && spec->input_mux) {
6818 /* check whether NID 0x04 is valid */
6819 unsigned int wcap = get_wcaps(codec, 0x04);
6820 wcap = get_wcaps_type(wcap);
6821 /* get type */
6822 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6823 spec->adc_nids = alc260_adc_nids_alt;
6824 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
6825 } else {
6826 spec->adc_nids = alc260_adc_nids;
6827 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6828 }
6829 }
6830 set_capture_mixer(codec);
6831 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6832
6833 spec->vmaster_nid = 0x08;
6834
6835 codec->patch_ops = alc_patch_ops;
6836 if (board_config == ALC260_AUTO)
6837 spec->init_hook = alc260_auto_init;
6838 #ifdef CONFIG_SND_HDA_POWER_SAVE
6839 if (!spec->loopback.amplist)
6840 spec->loopback.amplist = alc260_loopbacks;
6841 #endif
6842
6843 return 0;
6844 }
6845
6846
6847 /*
6848 * ALC882/883/885/888/889 support
6849 *
6850 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6851 * configuration. Each pin widget can choose any input DACs and a mixer.
6852 * Each ADC is connected from a mixer of all inputs. This makes possible
6853 * 6-channel independent captures.
6854 *
6855 * In addition, an independent DAC for the multi-playback (not used in this
6856 * driver yet).
6857 */
6858 #define ALC882_DIGOUT_NID 0x06
6859 #define ALC882_DIGIN_NID 0x0a
6860 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6861 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
6862 #define ALC1200_DIGOUT_NID 0x10
6863
6864
6865 static struct hda_channel_mode alc882_ch_modes[1] = {
6866 { 8, NULL }
6867 };
6868
6869 /* DACs */
6870 static hda_nid_t alc882_dac_nids[4] = {
6871 /* front, rear, clfe, rear_surr */
6872 0x02, 0x03, 0x04, 0x05
6873 };
6874 #define alc883_dac_nids alc882_dac_nids
6875
6876 /* ADCs */
6877 #define alc882_adc_nids alc880_adc_nids
6878 #define alc882_adc_nids_alt alc880_adc_nids_alt
6879 #define alc883_adc_nids alc882_adc_nids_alt
6880 static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6881 static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6882 #define alc889_adc_nids alc880_adc_nids
6883
6884 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6885 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6886 #define alc883_capsrc_nids alc882_capsrc_nids_alt
6887 static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6888 #define alc889_capsrc_nids alc882_capsrc_nids
6889
6890 /* input MUX */
6891 /* FIXME: should be a matrix-type input source selection */
6892
6893 static struct hda_input_mux alc882_capture_source = {
6894 .num_items = 4,
6895 .items = {
6896 { "Mic", 0x0 },
6897 { "Front Mic", 0x1 },
6898 { "Line", 0x2 },
6899 { "CD", 0x4 },
6900 },
6901 };
6902
6903 #define alc883_capture_source alc882_capture_source
6904
6905 static struct hda_input_mux alc889_capture_source = {
6906 .num_items = 3,
6907 .items = {
6908 { "Front Mic", 0x0 },
6909 { "Mic", 0x3 },
6910 { "Line", 0x2 },
6911 },
6912 };
6913
6914 static struct hda_input_mux mb5_capture_source = {
6915 .num_items = 3,
6916 .items = {
6917 { "Mic", 0x1 },
6918 { "Line", 0x2 },
6919 { "CD", 0x4 },
6920 },
6921 };
6922
6923 static struct hda_input_mux macmini3_capture_source = {
6924 .num_items = 2,
6925 .items = {
6926 { "Line", 0x2 },
6927 { "CD", 0x4 },
6928 },
6929 };
6930
6931 static struct hda_input_mux alc883_3stack_6ch_intel = {
6932 .num_items = 4,
6933 .items = {
6934 { "Mic", 0x1 },
6935 { "Front Mic", 0x0 },
6936 { "Line", 0x2 },
6937 { "CD", 0x4 },
6938 },
6939 };
6940
6941 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6942 .num_items = 2,
6943 .items = {
6944 { "Mic", 0x1 },
6945 { "Line", 0x2 },
6946 },
6947 };
6948
6949 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6950 .num_items = 4,
6951 .items = {
6952 { "Mic", 0x0 },
6953 { "iMic", 0x1 },
6954 { "Line", 0x2 },
6955 { "CD", 0x4 },
6956 },
6957 };
6958
6959 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6960 .num_items = 2,
6961 .items = {
6962 { "Mic", 0x0 },
6963 { "Int Mic", 0x1 },
6964 },
6965 };
6966
6967 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6968 .num_items = 3,
6969 .items = {
6970 { "Mic", 0x0 },
6971 { "Front Mic", 0x1 },
6972 { "Line", 0x4 },
6973 },
6974 };
6975
6976 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6977 .num_items = 2,
6978 .items = {
6979 { "Mic", 0x0 },
6980 { "Line", 0x2 },
6981 },
6982 };
6983
6984 static struct hda_input_mux alc889A_mb31_capture_source = {
6985 .num_items = 2,
6986 .items = {
6987 { "Mic", 0x0 },
6988 /* Front Mic (0x01) unused */
6989 { "Line", 0x2 },
6990 /* Line 2 (0x03) unused */
6991 /* CD (0x04) unused? */
6992 },
6993 };
6994
6995 /*
6996 * 2ch mode
6997 */
6998 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6999 { 2, NULL }
7000 };
7001
7002 /*
7003 * 2ch mode
7004 */
7005 static struct hda_verb alc882_3ST_ch2_init[] = {
7006 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7007 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7008 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7009 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7010 { } /* end */
7011 };
7012
7013 /*
7014 * 4ch mode
7015 */
7016 static struct hda_verb alc882_3ST_ch4_init[] = {
7017 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7018 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7019 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7020 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7021 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7022 { } /* end */
7023 };
7024
7025 /*
7026 * 6ch mode
7027 */
7028 static struct hda_verb alc882_3ST_ch6_init[] = {
7029 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7030 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7031 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7032 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7033 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7034 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7035 { } /* end */
7036 };
7037
7038 static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7039 { 2, alc882_3ST_ch2_init },
7040 { 4, alc882_3ST_ch4_init },
7041 { 6, alc882_3ST_ch6_init },
7042 };
7043
7044 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7045
7046 /*
7047 * 2ch mode
7048 */
7049 static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7050 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7053 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7054 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7055 { } /* end */
7056 };
7057
7058 /*
7059 * 4ch mode
7060 */
7061 static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7062 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7064 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7065 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7066 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7067 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7068 { } /* end */
7069 };
7070
7071 /*
7072 * 6ch mode
7073 */
7074 static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7075 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7076 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7077 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7078 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7079 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7080 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7081 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7082 { } /* end */
7083 };
7084
7085 static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7086 { 2, alc883_3ST_ch2_clevo_init },
7087 { 4, alc883_3ST_ch4_clevo_init },
7088 { 6, alc883_3ST_ch6_clevo_init },
7089 };
7090
7091
7092 /*
7093 * 6ch mode
7094 */
7095 static struct hda_verb alc882_sixstack_ch6_init[] = {
7096 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7097 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7098 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7099 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7100 { } /* end */
7101 };
7102
7103 /*
7104 * 8ch mode
7105 */
7106 static struct hda_verb alc882_sixstack_ch8_init[] = {
7107 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7108 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7109 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7110 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7111 { } /* end */
7112 };
7113
7114 static struct hda_channel_mode alc882_sixstack_modes[2] = {
7115 { 6, alc882_sixstack_ch6_init },
7116 { 8, alc882_sixstack_ch8_init },
7117 };
7118
7119
7120 /* Macbook Air 2,1 */
7121
7122 static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7123 { 2, NULL },
7124 };
7125
7126 /*
7127 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7128 */
7129
7130 /*
7131 * 2ch mode
7132 */
7133 static struct hda_verb alc885_mbp_ch2_init[] = {
7134 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7135 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7136 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7137 { } /* end */
7138 };
7139
7140 /*
7141 * 4ch mode
7142 */
7143 static struct hda_verb alc885_mbp_ch4_init[] = {
7144 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7145 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7146 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7147 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7148 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7149 { } /* end */
7150 };
7151
7152 static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7153 { 2, alc885_mbp_ch2_init },
7154 { 4, alc885_mbp_ch4_init },
7155 };
7156
7157 /*
7158 * 2ch
7159 * Speakers/Woofer/HP = Front
7160 * LineIn = Input
7161 */
7162 static struct hda_verb alc885_mb5_ch2_init[] = {
7163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7165 { } /* end */
7166 };
7167
7168 /*
7169 * 6ch mode
7170 * Speakers/HP = Front
7171 * Woofer = LFE
7172 * LineIn = Surround
7173 */
7174 static struct hda_verb alc885_mb5_ch6_init[] = {
7175 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7176 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7178 { } /* end */
7179 };
7180
7181 static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7182 { 2, alc885_mb5_ch2_init },
7183 { 6, alc885_mb5_ch6_init },
7184 };
7185
7186 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7187
7188 /*
7189 * 2ch mode
7190 */
7191 static struct hda_verb alc883_4ST_ch2_init[] = {
7192 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7193 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7194 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7195 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7198 { } /* end */
7199 };
7200
7201 /*
7202 * 4ch mode
7203 */
7204 static struct hda_verb alc883_4ST_ch4_init[] = {
7205 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7206 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7207 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7208 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7209 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7210 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7211 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7212 { } /* end */
7213 };
7214
7215 /*
7216 * 6ch mode
7217 */
7218 static struct hda_verb alc883_4ST_ch6_init[] = {
7219 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7220 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7221 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7222 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7223 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7224 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7225 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7226 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7227 { } /* end */
7228 };
7229
7230 /*
7231 * 8ch mode
7232 */
7233 static struct hda_verb alc883_4ST_ch8_init[] = {
7234 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7235 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7236 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7237 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7238 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7239 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7240 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7241 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7242 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7243 { } /* end */
7244 };
7245
7246 static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7247 { 2, alc883_4ST_ch2_init },
7248 { 4, alc883_4ST_ch4_init },
7249 { 6, alc883_4ST_ch6_init },
7250 { 8, alc883_4ST_ch8_init },
7251 };
7252
7253
7254 /*
7255 * 2ch mode
7256 */
7257 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7258 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7259 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7260 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7261 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7262 { } /* end */
7263 };
7264
7265 /*
7266 * 4ch mode
7267 */
7268 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7269 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7270 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7271 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7272 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7273 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7274 { } /* end */
7275 };
7276
7277 /*
7278 * 6ch mode
7279 */
7280 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7281 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7282 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7283 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7284 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7285 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7286 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7287 { } /* end */
7288 };
7289
7290 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7291 { 2, alc883_3ST_ch2_intel_init },
7292 { 4, alc883_3ST_ch4_intel_init },
7293 { 6, alc883_3ST_ch6_intel_init },
7294 };
7295
7296 /*
7297 * 2ch mode
7298 */
7299 static struct hda_verb alc889_ch2_intel_init[] = {
7300 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7301 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7302 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7303 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7304 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7305 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7306 { } /* end */
7307 };
7308
7309 /*
7310 * 6ch mode
7311 */
7312 static struct hda_verb alc889_ch6_intel_init[] = {
7313 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7314 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7315 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7316 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7317 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7318 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7319 { } /* end */
7320 };
7321
7322 /*
7323 * 8ch mode
7324 */
7325 static struct hda_verb alc889_ch8_intel_init[] = {
7326 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7327 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7328 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7329 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7330 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
7331 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7332 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7333 { } /* end */
7334 };
7335
7336 static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
7337 { 2, alc889_ch2_intel_init },
7338 { 6, alc889_ch6_intel_init },
7339 { 8, alc889_ch8_intel_init },
7340 };
7341
7342 /*
7343 * 6ch mode
7344 */
7345 static struct hda_verb alc883_sixstack_ch6_init[] = {
7346 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7347 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7348 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7349 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7350 { } /* end */
7351 };
7352
7353 /*
7354 * 8ch mode
7355 */
7356 static struct hda_verb alc883_sixstack_ch8_init[] = {
7357 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7358 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7359 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7360 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7361 { } /* end */
7362 };
7363
7364 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7365 { 6, alc883_sixstack_ch6_init },
7366 { 8, alc883_sixstack_ch8_init },
7367 };
7368
7369
7370 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7371 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7372 */
7373 static struct snd_kcontrol_new alc882_base_mixer[] = {
7374 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7375 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7376 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7377 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7378 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7379 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7380 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7381 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7382 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7383 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7384 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7385 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7386 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7387 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7388 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7390 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7392 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7393 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7395 { } /* end */
7396 };
7397
7398 /* Macbook Air 2,1 same control for HP and internal Speaker */
7399
7400 static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7401 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7402 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7403 { }
7404 };
7405
7406
7407 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7408 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7409 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
7410 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7411 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7412 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7414 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7415 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7416 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7417 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
7418 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7419 { } /* end */
7420 };
7421
7422 static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7423 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7424 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7425 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7426 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7427 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7428 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7429 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7430 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7431 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7432 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7434 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7435 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7436 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT),
7437 { } /* end */
7438 };
7439
7440 static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7441 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7442 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7443 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7444 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7445 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7446 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7447 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7448 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7450 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7451 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7452 { } /* end */
7453 };
7454
7455 static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7456 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7457 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
7458 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
7459 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7460 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7461 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7462 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7463 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7464 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
7465 { } /* end */
7466 };
7467
7468
7469 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7471 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7472 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7473 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7474 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7475 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7477 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7478 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7479 { } /* end */
7480 };
7481
7482 static struct snd_kcontrol_new alc882_targa_mixer[] = {
7483 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7484 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7486 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7487 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7491 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7492 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7493 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7494 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7495 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7496 { } /* end */
7497 };
7498
7499 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
7500 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
7501 */
7502 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7504 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7506 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7507 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7508 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7509 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7510 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7511 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
7512 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7516 { } /* end */
7517 };
7518
7519 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7523 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7524 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7525 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7526 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7527 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7528 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7529 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7530 { } /* end */
7531 };
7532
7533 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7534 {
7535 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7536 .name = "Channel Mode",
7537 .info = alc_ch_mode_info,
7538 .get = alc_ch_mode_get,
7539 .put = alc_ch_mode_put,
7540 },
7541 { } /* end */
7542 };
7543
7544 static struct hda_verb alc882_base_init_verbs[] = {
7545 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7547 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7548 /* Rear mixer */
7549 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7550 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7551 /* CLFE mixer */
7552 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7553 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7554 /* Side mixer */
7555 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7556 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7557
7558 /* Front Pin: output 0 (0x0c) */
7559 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7560 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7561 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7562 /* Rear Pin: output 1 (0x0d) */
7563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7564 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7565 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7566 /* CLFE Pin: output 2 (0x0e) */
7567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7569 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7570 /* Side Pin: output 3 (0x0f) */
7571 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7572 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7573 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7574 /* Mic (rear) pin: input vref at 80% */
7575 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7576 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7577 /* Front Mic pin: input vref at 80% */
7578 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7579 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7580 /* Line In pin: input */
7581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7583 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7584 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7585 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7586 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7587 /* CD pin widget for input */
7588 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7589
7590 /* FIXME: use matrix-type input source selection */
7591 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7592 /* Input mixer2 */
7593 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7594 /* Input mixer3 */
7595 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7596 /* ADC2: mute amp left and right */
7597 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7598 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7599 /* ADC3: mute amp left and right */
7600 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7601 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7602
7603 { }
7604 };
7605
7606 static struct hda_verb alc882_adc1_init_verbs[] = {
7607 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7611 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7612 /* ADC1: mute amp left and right */
7613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7614 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7615 { }
7616 };
7617
7618 static struct hda_verb alc882_eapd_verbs[] = {
7619 /* change to EAPD mode */
7620 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7621 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
7622 { }
7623 };
7624
7625 static struct hda_verb alc889_eapd_verbs[] = {
7626 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7627 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7628 { }
7629 };
7630
7631 static struct hda_verb alc_hp15_unsol_verbs[] = {
7632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7633 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7634 {}
7635 };
7636
7637 static struct hda_verb alc885_init_verbs[] = {
7638 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7640 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7641 /* Rear mixer */
7642 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7643 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7644 /* CLFE mixer */
7645 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7646 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7647 /* Side mixer */
7648 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7649 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7650
7651 /* Front HP Pin: output 0 (0x0c) */
7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7655 /* Front Pin: output 0 (0x0c) */
7656 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7657 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7658 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7659 /* Rear Pin: output 1 (0x0d) */
7660 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7662 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7663 /* CLFE Pin: output 2 (0x0e) */
7664 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7665 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7666 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7667 /* Side Pin: output 3 (0x0f) */
7668 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7669 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7671 /* Mic (rear) pin: input vref at 80% */
7672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7673 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7674 /* Front Mic pin: input vref at 80% */
7675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7677 /* Line In pin: input */
7678 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7679 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7680
7681 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7682 /* Input mixer1 */
7683 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7684 /* Input mixer2 */
7685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7686 /* Input mixer3 */
7687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7688 /* ADC2: mute amp left and right */
7689 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7690 /* ADC3: mute amp left and right */
7691 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7692
7693 { }
7694 };
7695
7696 static struct hda_verb alc885_init_input_verbs[] = {
7697 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7698 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7699 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7700 { }
7701 };
7702
7703
7704 /* Unmute Selector 24h and set the default input to front mic */
7705 static struct hda_verb alc889_init_input_verbs[] = {
7706 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7708 { }
7709 };
7710
7711
7712 #define alc883_init_verbs alc882_base_init_verbs
7713
7714 /* Mac Pro test */
7715 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
7716 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7717 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7718 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
7719 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7720 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7721 /* FIXME: this looks suspicious...
7722 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
7723 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
7724 */
7725 { } /* end */
7726 };
7727
7728 static struct hda_verb alc882_macpro_init_verbs[] = {
7729 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7731 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7733 /* Front Pin: output 0 (0x0c) */
7734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7736 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7737 /* Front Mic pin: input vref at 80% */
7738 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7739 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7740 /* Speaker: output */
7741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7743 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
7744 /* Headphone output (output 0 - 0x0c) */
7745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7747 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7748
7749 /* FIXME: use matrix-type input source selection */
7750 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7751 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7752 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7753 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7754 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7755 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7756 /* Input mixer2 */
7757 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7758 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7759 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7760 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7761 /* Input mixer3 */
7762 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7763 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7764 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7765 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7766 /* ADC1: mute amp left and right */
7767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7768 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7769 /* ADC2: mute amp left and right */
7770 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7771 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7772 /* ADC3: mute amp left and right */
7773 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7774 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7775
7776 { }
7777 };
7778
7779 /* Macbook 5,1 */
7780 static struct hda_verb alc885_mb5_init_verbs[] = {
7781 /* DACs */
7782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7783 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7784 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7786 /* Front mixer */
7787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7788 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7790 /* Surround mixer */
7791 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7792 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7793 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7794 /* LFE mixer */
7795 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7796 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7798 /* HP mixer */
7799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7801 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7802 /* Front Pin (0x0c) */
7803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7805 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7806 /* LFE Pin (0x0e) */
7807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7809 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7810 /* HP Pin (0x0f) */
7811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7815 /* Front Mic pin: input vref at 80% */
7816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7818 /* Line In pin */
7819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7821
7822 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7823 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7824 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7825 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7826 { }
7827 };
7828
7829 /* Macmini 3,1 */
7830 static struct hda_verb alc885_macmini3_init_verbs[] = {
7831 /* DACs */
7832 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7833 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7834 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7835 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7836 /* Front mixer */
7837 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7838 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7839 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7840 /* Surround mixer */
7841 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7842 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7844 /* LFE mixer */
7845 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7846 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7847 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7848 /* HP mixer */
7849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7850 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7851 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7852 /* Front Pin (0x0c) */
7853 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7854 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7856 /* LFE Pin (0x0e) */
7857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7859 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7860 /* HP Pin (0x0f) */
7861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7863 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7864 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7865 /* Line In pin */
7866 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7868
7869 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7870 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7871 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7872 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7873 { }
7874 };
7875
7876
7877 static struct hda_verb alc885_mba21_init_verbs[] = {
7878 /*Internal and HP Speaker Mixer*/
7879 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7880 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7881 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7882 /*Internal Speaker Pin (0x0c)*/
7883 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7884 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7885 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7886 /* HP Pin: output 0 (0x0e) */
7887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7889 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7890 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7891 /* Line in (is hp when jack connected)*/
7892 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7893 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7894
7895 { }
7896 };
7897
7898
7899 /* Macbook Pro rev3 */
7900 static struct hda_verb alc885_mbp3_init_verbs[] = {
7901 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7902 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7903 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7904 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7905 /* Rear mixer */
7906 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7907 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7908 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7909 /* HP mixer */
7910 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7911 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7912 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7913 /* Front Pin: output 0 (0x0c) */
7914 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7915 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7916 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7917 /* HP Pin: output 0 (0x0e) */
7918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7919 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7920 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
7921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7922 /* Mic (rear) pin: input vref at 80% */
7923 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7924 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7925 /* Front Mic pin: input vref at 80% */
7926 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7928 /* Line In pin: use output 1 when in LineOut mode */
7929 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7931 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7932
7933 /* FIXME: use matrix-type input source selection */
7934 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7935 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7936 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7937 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7938 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7939 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7940 /* Input mixer2 */
7941 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7942 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7943 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7944 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7945 /* Input mixer3 */
7946 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7947 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7948 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7949 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7950 /* ADC1: mute amp left and right */
7951 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7952 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7953 /* ADC2: mute amp left and right */
7954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7955 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7956 /* ADC3: mute amp left and right */
7957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7958 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7959
7960 { }
7961 };
7962
7963 /* iMac 9,1 */
7964 static struct hda_verb alc885_imac91_init_verbs[] = {
7965 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
7966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7967 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7968 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7969 /* Rear mixer */
7970 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7971 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7972 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7973 /* HP Pin: output 0 (0x0c) */
7974 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7975 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7976 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7977 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7978 /* Internal Speakers: output 0 (0x0d) */
7979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7980 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7981 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7982 /* Mic (rear) pin: input vref at 80% */
7983 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7984 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7985 /* Front Mic pin: input vref at 80% */
7986 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7987 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7988 /* Line In pin: use output 1 when in LineOut mode */
7989 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7990 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7991 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
7992
7993 /* FIXME: use matrix-type input source selection */
7994 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7995 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7999 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8000 /* Input mixer2 */
8001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8004 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8005 /* Input mixer3 */
8006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8010 /* ADC1: mute amp left and right */
8011 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8012 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8013 /* ADC2: mute amp left and right */
8014 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8015 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8016 /* ADC3: mute amp left and right */
8017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8018 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8019
8020 { }
8021 };
8022
8023 /* iMac 24 mixer. */
8024 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
8025 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8026 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8027 { } /* end */
8028 };
8029
8030 /* iMac 24 init verbs. */
8031 static struct hda_verb alc885_imac24_init_verbs[] = {
8032 /* Internal speakers: output 0 (0x0c) */
8033 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8034 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8035 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8036 /* Internal speakers: output 0 (0x0c) */
8037 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8038 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8039 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8040 /* Headphone: output 0 (0x0c) */
8041 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8042 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8043 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8045 /* Front Mic: input vref at 80% */
8046 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8047 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8048 { }
8049 };
8050
8051 /* Toggle speaker-output according to the hp-jack state */
8052 static void alc885_imac24_setup(struct hda_codec *codec)
8053 {
8054 struct alc_spec *spec = codec->spec;
8055
8056 spec->autocfg.hp_pins[0] = 0x14;
8057 spec->autocfg.speaker_pins[0] = 0x18;
8058 spec->autocfg.speaker_pins[1] = 0x1a;
8059 }
8060
8061 #define alc885_mb5_setup alc885_imac24_setup
8062 #define alc885_macmini3_setup alc885_imac24_setup
8063
8064 /* Macbook Air 2,1 */
8065 static void alc885_mba21_setup(struct hda_codec *codec)
8066 {
8067 struct alc_spec *spec = codec->spec;
8068
8069 spec->autocfg.hp_pins[0] = 0x14;
8070 spec->autocfg.speaker_pins[0] = 0x18;
8071 }
8072
8073
8074
8075 static void alc885_mbp3_setup(struct hda_codec *codec)
8076 {
8077 struct alc_spec *spec = codec->spec;
8078
8079 spec->autocfg.hp_pins[0] = 0x15;
8080 spec->autocfg.speaker_pins[0] = 0x14;
8081 }
8082
8083 static void alc885_imac91_setup(struct hda_codec *codec)
8084 {
8085 struct alc_spec *spec = codec->spec;
8086
8087 spec->autocfg.hp_pins[0] = 0x14;
8088 spec->autocfg.speaker_pins[0] = 0x15;
8089 spec->autocfg.speaker_pins[1] = 0x1a;
8090 }
8091
8092 static struct hda_verb alc882_targa_verbs[] = {
8093 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8094 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8095
8096 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8098
8099 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8100 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8101 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8102
8103 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8104 { } /* end */
8105 };
8106
8107 /* toggle speaker-output according to the hp-jack state */
8108 static void alc882_targa_automute(struct hda_codec *codec)
8109 {
8110 struct alc_spec *spec = codec->spec;
8111 alc_automute_amp(codec);
8112 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8113 spec->jack_present ? 1 : 3);
8114 }
8115
8116 static void alc882_targa_setup(struct hda_codec *codec)
8117 {
8118 struct alc_spec *spec = codec->spec;
8119
8120 spec->autocfg.hp_pins[0] = 0x14;
8121 spec->autocfg.speaker_pins[0] = 0x1b;
8122 }
8123
8124 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8125 {
8126 if ((res >> 26) == ALC880_HP_EVENT)
8127 alc882_targa_automute(codec);
8128 }
8129
8130 static struct hda_verb alc882_asus_a7j_verbs[] = {
8131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8132 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8133
8134 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8135 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8136 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8137
8138 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8139 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8140 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8141
8142 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8143 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8144 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8145 { } /* end */
8146 };
8147
8148 static struct hda_verb alc882_asus_a7m_verbs[] = {
8149 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8150 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8151
8152 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8153 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8154 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8155
8156 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8157 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8158 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8159
8160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8163 { } /* end */
8164 };
8165
8166 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8167 {
8168 unsigned int gpiostate, gpiomask, gpiodir;
8169
8170 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8171 AC_VERB_GET_GPIO_DATA, 0);
8172
8173 if (!muted)
8174 gpiostate |= (1 << pin);
8175 else
8176 gpiostate &= ~(1 << pin);
8177
8178 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8179 AC_VERB_GET_GPIO_MASK, 0);
8180 gpiomask |= (1 << pin);
8181
8182 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8183 AC_VERB_GET_GPIO_DIRECTION, 0);
8184 gpiodir |= (1 << pin);
8185
8186
8187 snd_hda_codec_write(codec, codec->afg, 0,
8188 AC_VERB_SET_GPIO_MASK, gpiomask);
8189 snd_hda_codec_write(codec, codec->afg, 0,
8190 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8191
8192 msleep(1);
8193
8194 snd_hda_codec_write(codec, codec->afg, 0,
8195 AC_VERB_SET_GPIO_DATA, gpiostate);
8196 }
8197
8198 /* set up GPIO at initialization */
8199 static void alc885_macpro_init_hook(struct hda_codec *codec)
8200 {
8201 alc882_gpio_mute(codec, 0, 0);
8202 alc882_gpio_mute(codec, 1, 0);
8203 }
8204
8205 /* set up GPIO and update auto-muting at initialization */
8206 static void alc885_imac24_init_hook(struct hda_codec *codec)
8207 {
8208 alc885_macpro_init_hook(codec);
8209 alc_automute_amp(codec);
8210 }
8211
8212 /*
8213 * generic initialization of ADC, input mixers and output mixers
8214 */
8215 static struct hda_verb alc883_auto_init_verbs[] = {
8216 /*
8217 * Unmute ADC0-2 and set the default input to mic-in
8218 */
8219 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8220 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8221 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8222 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8223
8224 /*
8225 * Set up output mixers (0x0c - 0x0f)
8226 */
8227 /* set vol=0 to output mixers */
8228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8231 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8232 /* set up input amps for analog loopback */
8233 /* Amp Indices: DAC = 0, mixer = 1 */
8234 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8236 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8237 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8238 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8239 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8240 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8243 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8244
8245 /* FIXME: use matrix-type input source selection */
8246 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8247 /* Input mixer2 */
8248 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8249 /* Input mixer3 */
8250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8251 { }
8252 };
8253
8254 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8255 static struct hda_verb alc889A_mb31_ch2_init[] = {
8256 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8257 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8258 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8259 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8260 { } /* end */
8261 };
8262
8263 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8264 static struct hda_verb alc889A_mb31_ch4_init[] = {
8265 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8266 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8267 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8268 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8269 { } /* end */
8270 };
8271
8272 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8273 static struct hda_verb alc889A_mb31_ch5_init[] = {
8274 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8275 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8276 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8277 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8278 { } /* end */
8279 };
8280
8281 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8282 static struct hda_verb alc889A_mb31_ch6_init[] = {
8283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8284 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8285 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8286 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8287 { } /* end */
8288 };
8289
8290 static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8291 { 2, alc889A_mb31_ch2_init },
8292 { 4, alc889A_mb31_ch4_init },
8293 { 5, alc889A_mb31_ch5_init },
8294 { 6, alc889A_mb31_ch6_init },
8295 };
8296
8297 static struct hda_verb alc883_medion_eapd_verbs[] = {
8298 /* eanable EAPD on medion laptop */
8299 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8300 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8301 { }
8302 };
8303
8304 #define alc883_base_mixer alc882_base_mixer
8305
8306 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8311 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8312 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8319 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8320 { } /* end */
8321 };
8322
8323 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8324 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8325 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8326 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8327 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8328 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8329 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8330 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8331 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8333 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8334 { } /* end */
8335 };
8336
8337 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8338 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8339 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8340 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8341 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8343 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8345 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8346 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8347 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8348 { } /* end */
8349 };
8350
8351 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8352 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8353 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8355 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8356 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8360 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8362 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8363 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8365 { } /* end */
8366 };
8367
8368 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8369 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8370 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8371 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8372 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8373 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8374 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8375 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8376 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8377 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8378 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8379 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8384 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8385 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8387 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8388 { } /* end */
8389 };
8390
8391 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8392 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8393 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8394 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8395 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8396 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8397 HDA_OUTPUT),
8398 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8399 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8400 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8403 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8404 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8405 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8407 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8408 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8409 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8410 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8411 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8412 { } /* end */
8413 };
8414
8415 static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8416 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8417 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8418 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8419 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8420 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8421 HDA_OUTPUT),
8422 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8423 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8424 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8425 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8426 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
8427 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8431 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
8432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8433 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8434 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
8435 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8436 { } /* end */
8437 };
8438
8439 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8440 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8441 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8442 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8443 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8444 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8445 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8446 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8447 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8448 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8454 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8457 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8459 { } /* end */
8460 };
8461
8462 static struct snd_kcontrol_new alc883_targa_mixer[] = {
8463 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8464 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8465 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8466 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8468 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8471 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8473 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8474 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8475 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8476 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8477 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8478 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8480 { } /* end */
8481 };
8482
8483 static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8484 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8485 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8486 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8487 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8488 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8489 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8490 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8491 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8492 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8493 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8494 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8495 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8496 { } /* end */
8497 };
8498
8499 static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8500 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8501 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8502 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8503 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8504 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8505 { } /* end */
8506 };
8507
8508 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8509 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8510 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8511 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8512 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8513 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8515 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8516 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8517 { } /* end */
8518 };
8519
8520 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8521 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8522 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
8523 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8524 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8525 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8526 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8527 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8528 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8529 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8530 { } /* end */
8531 };
8532
8533 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8534 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8535 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8536 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8537 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8538 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8541 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8542 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8543 { } /* end */
8544 };
8545
8546 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
8547 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8548 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8550 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8551 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8553 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8554 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8555 { } /* end */
8556 };
8557
8558 static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
8559 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8560 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8561 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8562 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8563 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8564 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8566 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8567 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8568 { } /* end */
8569 };
8570
8571 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
8572 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8573 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8574 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
8575 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
8576 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
8577 0x0d, 1, 0x0, HDA_OUTPUT),
8578 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
8579 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
8580 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
8581 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8582 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8583 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8584 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8585 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8586 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8588 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8591 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8592 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8593 { } /* end */
8594 };
8595
8596 static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
8597 /* Output mixers */
8598 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8599 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8600 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8601 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
8603 HDA_OUTPUT),
8604 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
8605 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
8606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
8607 /* Output switches */
8608 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
8609 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
8610 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
8611 /* Boost mixers */
8612 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
8613 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
8614 /* Input mixers */
8615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8617 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8618 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8619 { } /* end */
8620 };
8621
8622 static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
8623 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8624 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8626 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8627 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
8628 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8629 { } /* end */
8630 };
8631
8632 static struct hda_bind_ctls alc883_bind_cap_vol = {
8633 .ops = &snd_hda_bind_vol,
8634 .values = {
8635 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8636 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8637 0
8638 },
8639 };
8640
8641 static struct hda_bind_ctls alc883_bind_cap_switch = {
8642 .ops = &snd_hda_bind_sw,
8643 .values = {
8644 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
8645 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
8646 0
8647 },
8648 };
8649
8650 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
8651 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8652 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8657 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8658 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8659 { } /* end */
8660 };
8661
8662 static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
8663 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
8664 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
8665 {
8666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8667 /* .name = "Capture Source", */
8668 .name = "Input Source",
8669 .count = 1,
8670 .info = alc_mux_enum_info,
8671 .get = alc_mux_enum_get,
8672 .put = alc_mux_enum_put,
8673 },
8674 { } /* end */
8675 };
8676
8677 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8678 {
8679 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8680 .name = "Channel Mode",
8681 .info = alc_ch_mode_info,
8682 .get = alc_ch_mode_get,
8683 .put = alc_ch_mode_put,
8684 },
8685 { } /* end */
8686 };
8687
8688 /* toggle speaker-output according to the hp-jack state */
8689 static void alc883_mitac_setup(struct hda_codec *codec)
8690 {
8691 struct alc_spec *spec = codec->spec;
8692
8693 spec->autocfg.hp_pins[0] = 0x15;
8694 spec->autocfg.speaker_pins[0] = 0x14;
8695 spec->autocfg.speaker_pins[1] = 0x17;
8696 }
8697
8698 /* auto-toggle front mic */
8699 /*
8700 static void alc883_mitac_mic_automute(struct hda_codec *codec)
8701 {
8702 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
8703
8704 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
8705 }
8706 */
8707
8708 static struct hda_verb alc883_mitac_verbs[] = {
8709 /* HP */
8710 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8711 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8712 /* Subwoofer */
8713 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8714 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8715
8716 /* enable unsolicited event */
8717 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
8719
8720 { } /* end */
8721 };
8722
8723 static struct hda_verb alc883_clevo_m540r_verbs[] = {
8724 /* HP */
8725 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8726 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8727 /* Int speaker */
8728 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8729
8730 /* enable unsolicited event */
8731 /*
8732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8734 */
8735
8736 { } /* end */
8737 };
8738
8739 static struct hda_verb alc883_clevo_m720_verbs[] = {
8740 /* HP */
8741 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8742 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8743 /* Int speaker */
8744 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
8745 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8746
8747 /* enable unsolicited event */
8748 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8749 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8750
8751 { } /* end */
8752 };
8753
8754 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
8755 /* HP */
8756 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8757 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8758 /* Subwoofer */
8759 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8760 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8761
8762 /* enable unsolicited event */
8763 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8764
8765 { } /* end */
8766 };
8767
8768 static struct hda_verb alc883_targa_verbs[] = {
8769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8771
8772 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8773 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8774
8775 /* Connect Line-Out side jack (SPDIF) to Side */
8776 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8777 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8778 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8779 /* Connect Mic jack to CLFE */
8780 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8781 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8782 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
8783 /* Connect Line-in jack to Surround */
8784 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8785 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8786 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8787 /* Connect HP out jack to Front */
8788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8789 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8791
8792 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8793
8794 { } /* end */
8795 };
8796
8797 static struct hda_verb alc883_lenovo_101e_verbs[] = {
8798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
8800 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
8801 { } /* end */
8802 };
8803
8804 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
8805 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8807 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8809 { } /* end */
8810 };
8811
8812 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8816 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
8817 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8818 { } /* end */
8819 };
8820
8821 static struct hda_verb alc883_haier_w66_verbs[] = {
8822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8824
8825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8826
8827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8828 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8829 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8830 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8831 { } /* end */
8832 };
8833
8834 static struct hda_verb alc888_lenovo_sky_verbs[] = {
8835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8836 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8840 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8841 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8842 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8843 { } /* end */
8844 };
8845
8846 static struct hda_verb alc888_6st_dell_verbs[] = {
8847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8848 { }
8849 };
8850
8851 static struct hda_verb alc883_vaiott_verbs[] = {
8852 /* HP */
8853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8855
8856 /* enable unsolicited event */
8857 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8858
8859 { } /* end */
8860 };
8861
8862 static void alc888_3st_hp_setup(struct hda_codec *codec)
8863 {
8864 struct alc_spec *spec = codec->spec;
8865
8866 spec->autocfg.hp_pins[0] = 0x1b;
8867 spec->autocfg.speaker_pins[0] = 0x14;
8868 spec->autocfg.speaker_pins[1] = 0x16;
8869 spec->autocfg.speaker_pins[2] = 0x18;
8870 }
8871
8872 static struct hda_verb alc888_3st_hp_verbs[] = {
8873 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
8874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
8875 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
8876 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8877 { } /* end */
8878 };
8879
8880 /*
8881 * 2ch mode
8882 */
8883 static struct hda_verb alc888_3st_hp_2ch_init[] = {
8884 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8885 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8886 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8887 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8888 { } /* end */
8889 };
8890
8891 /*
8892 * 4ch mode
8893 */
8894 static struct hda_verb alc888_3st_hp_4ch_init[] = {
8895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8898 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8899 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8900 { } /* end */
8901 };
8902
8903 /*
8904 * 6ch mode
8905 */
8906 static struct hda_verb alc888_3st_hp_6ch_init[] = {
8907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8910 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8911 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8912 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
8913 { } /* end */
8914 };
8915
8916 static struct hda_channel_mode alc888_3st_hp_modes[3] = {
8917 { 2, alc888_3st_hp_2ch_init },
8918 { 4, alc888_3st_hp_4ch_init },
8919 { 6, alc888_3st_hp_6ch_init },
8920 };
8921
8922 /* toggle front-jack and RCA according to the hp-jack state */
8923 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
8924 {
8925 unsigned int present = snd_hda_jack_detect(codec, 0x1b);
8926
8927 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8928 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8929 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8930 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8931 }
8932
8933 /* toggle RCA according to the front-jack state */
8934 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
8935 {
8936 unsigned int present = snd_hda_jack_detect(codec, 0x14);
8937
8938 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8939 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8940 }
8941
8942 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
8943 unsigned int res)
8944 {
8945 if ((res >> 26) == ALC880_HP_EVENT)
8946 alc888_lenovo_ms7195_front_automute(codec);
8947 if ((res >> 26) == ALC880_FRONT_EVENT)
8948 alc888_lenovo_ms7195_rca_automute(codec);
8949 }
8950
8951 static struct hda_verb alc883_medion_md2_verbs[] = {
8952 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8954
8955 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8956
8957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8958 { } /* end */
8959 };
8960
8961 /* toggle speaker-output according to the hp-jack state */
8962 static void alc883_medion_md2_setup(struct hda_codec *codec)
8963 {
8964 struct alc_spec *spec = codec->spec;
8965
8966 spec->autocfg.hp_pins[0] = 0x14;
8967 spec->autocfg.speaker_pins[0] = 0x15;
8968 }
8969
8970 /* toggle speaker-output according to the hp-jack state */
8971 #define alc883_targa_init_hook alc882_targa_init_hook
8972 #define alc883_targa_unsol_event alc882_targa_unsol_event
8973
8974 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8975 {
8976 unsigned int present;
8977
8978 present = snd_hda_jack_detect(codec, 0x18);
8979 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
8980 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8981 }
8982
8983 static void alc883_clevo_m720_setup(struct hda_codec *codec)
8984 {
8985 struct alc_spec *spec = codec->spec;
8986
8987 spec->autocfg.hp_pins[0] = 0x15;
8988 spec->autocfg.speaker_pins[0] = 0x14;
8989 }
8990
8991 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8992 {
8993 alc_automute_amp(codec);
8994 alc883_clevo_m720_mic_automute(codec);
8995 }
8996
8997 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8998 unsigned int res)
8999 {
9000 switch (res >> 26) {
9001 case ALC880_MIC_EVENT:
9002 alc883_clevo_m720_mic_automute(codec);
9003 break;
9004 default:
9005 alc_automute_amp_unsol_event(codec, res);
9006 break;
9007 }
9008 }
9009
9010 /* toggle speaker-output according to the hp-jack state */
9011 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9012 {
9013 struct alc_spec *spec = codec->spec;
9014
9015 spec->autocfg.hp_pins[0] = 0x14;
9016 spec->autocfg.speaker_pins[0] = 0x15;
9017 }
9018
9019 static void alc883_haier_w66_setup(struct hda_codec *codec)
9020 {
9021 struct alc_spec *spec = codec->spec;
9022
9023 spec->autocfg.hp_pins[0] = 0x1b;
9024 spec->autocfg.speaker_pins[0] = 0x14;
9025 }
9026
9027 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
9028 {
9029 int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
9030
9031 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9032 HDA_AMP_MUTE, bits);
9033 }
9034
9035 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
9036 {
9037 int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
9038
9039 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9040 HDA_AMP_MUTE, bits);
9041 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9042 HDA_AMP_MUTE, bits);
9043 }
9044
9045 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
9046 unsigned int res)
9047 {
9048 if ((res >> 26) == ALC880_HP_EVENT)
9049 alc883_lenovo_101e_all_automute(codec);
9050 if ((res >> 26) == ALC880_FRONT_EVENT)
9051 alc883_lenovo_101e_ispeaker_automute(codec);
9052 }
9053
9054 /* toggle speaker-output according to the hp-jack state */
9055 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9056 {
9057 struct alc_spec *spec = codec->spec;
9058
9059 spec->autocfg.hp_pins[0] = 0x14;
9060 spec->autocfg.speaker_pins[0] = 0x15;
9061 spec->autocfg.speaker_pins[1] = 0x16;
9062 }
9063
9064 static struct hda_verb alc883_acer_eapd_verbs[] = {
9065 /* HP Pin: output 0 (0x0c) */
9066 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9067 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9068 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9069 /* Front Pin: output 0 (0x0c) */
9070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9072 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9073 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9074 /* eanable EAPD on medion laptop */
9075 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9076 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9077 /* enable unsolicited event */
9078 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9079 { }
9080 };
9081
9082 static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9084 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9085 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9086 { } /* end */
9087 };
9088
9089 static void alc888_6st_dell_setup(struct hda_codec *codec)
9090 {
9091 struct alc_spec *spec = codec->spec;
9092
9093 spec->autocfg.hp_pins[0] = 0x1b;
9094 spec->autocfg.speaker_pins[0] = 0x14;
9095 spec->autocfg.speaker_pins[1] = 0x15;
9096 spec->autocfg.speaker_pins[2] = 0x16;
9097 spec->autocfg.speaker_pins[3] = 0x17;
9098 }
9099
9100 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9101 {
9102 struct alc_spec *spec = codec->spec;
9103
9104 spec->autocfg.hp_pins[0] = 0x1b;
9105 spec->autocfg.speaker_pins[0] = 0x14;
9106 spec->autocfg.speaker_pins[1] = 0x15;
9107 spec->autocfg.speaker_pins[2] = 0x16;
9108 spec->autocfg.speaker_pins[3] = 0x17;
9109 spec->autocfg.speaker_pins[4] = 0x1a;
9110 }
9111
9112 static void alc883_vaiott_setup(struct hda_codec *codec)
9113 {
9114 struct alc_spec *spec = codec->spec;
9115
9116 spec->autocfg.hp_pins[0] = 0x15;
9117 spec->autocfg.speaker_pins[0] = 0x14;
9118 spec->autocfg.speaker_pins[1] = 0x17;
9119 }
9120
9121 static struct hda_verb alc888_asus_m90v_verbs[] = {
9122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9123 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9124 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9125 /* enable unsolicited event */
9126 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9127 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9128 { } /* end */
9129 };
9130
9131 static void alc883_mode2_setup(struct hda_codec *codec)
9132 {
9133 struct alc_spec *spec = codec->spec;
9134
9135 spec->autocfg.hp_pins[0] = 0x1b;
9136 spec->autocfg.speaker_pins[0] = 0x14;
9137 spec->autocfg.speaker_pins[1] = 0x15;
9138 spec->autocfg.speaker_pins[2] = 0x16;
9139 spec->ext_mic.pin = 0x18;
9140 spec->int_mic.pin = 0x19;
9141 spec->ext_mic.mux_idx = 0;
9142 spec->int_mic.mux_idx = 1;
9143 spec->auto_mic = 1;
9144 }
9145
9146 static struct hda_verb alc888_asus_eee1601_verbs[] = {
9147 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9149 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9150 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9152 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9153 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9154 /* enable unsolicited event */
9155 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9156 { } /* end */
9157 };
9158
9159 static void alc883_eee1601_inithook(struct hda_codec *codec)
9160 {
9161 struct alc_spec *spec = codec->spec;
9162
9163 spec->autocfg.hp_pins[0] = 0x14;
9164 spec->autocfg.speaker_pins[0] = 0x1b;
9165 alc_automute_pin(codec);
9166 }
9167
9168 static struct hda_verb alc889A_mb31_verbs[] = {
9169 /* Init rear pin (used as headphone output) */
9170 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9171 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9172 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9173 /* Init line pin (used as output in 4ch and 6ch mode) */
9174 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9175 /* Init line 2 pin (used as headphone out by default) */
9176 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9177 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9178 { } /* end */
9179 };
9180
9181 /* Mute speakers according to the headphone jack state */
9182 static void alc889A_mb31_automute(struct hda_codec *codec)
9183 {
9184 unsigned int present;
9185
9186 /* Mute only in 2ch or 4ch mode */
9187 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9188 == 0x00) {
9189 present = snd_hda_jack_detect(codec, 0x15);
9190 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9191 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9192 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9193 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9194 }
9195 }
9196
9197 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9198 {
9199 if ((res >> 26) == ALC880_HP_EVENT)
9200 alc889A_mb31_automute(codec);
9201 }
9202
9203
9204 #ifdef CONFIG_SND_HDA_POWER_SAVE
9205 #define alc882_loopbacks alc880_loopbacks
9206 #endif
9207
9208 /* pcm configuration: identical with ALC880 */
9209 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
9210 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
9211 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
9212 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
9213
9214 static hda_nid_t alc883_slave_dig_outs[] = {
9215 ALC1200_DIGOUT_NID, 0,
9216 };
9217
9218 static hda_nid_t alc1200_slave_dig_outs[] = {
9219 ALC883_DIGOUT_NID, 0,
9220 };
9221
9222 /*
9223 * configuration and preset
9224 */
9225 static const char *alc882_models[ALC882_MODEL_LAST] = {
9226 [ALC882_3ST_DIG] = "3stack-dig",
9227 [ALC882_6ST_DIG] = "6stack-dig",
9228 [ALC882_ARIMA] = "arima",
9229 [ALC882_W2JC] = "w2jc",
9230 [ALC882_TARGA] = "targa",
9231 [ALC882_ASUS_A7J] = "asus-a7j",
9232 [ALC882_ASUS_A7M] = "asus-a7m",
9233 [ALC885_MACPRO] = "macpro",
9234 [ALC885_MB5] = "mb5",
9235 [ALC885_MACMINI3] = "macmini3",
9236 [ALC885_MBA21] = "mba21",
9237 [ALC885_MBP3] = "mbp3",
9238 [ALC885_IMAC24] = "imac24",
9239 [ALC885_IMAC91] = "imac91",
9240 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9241 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9242 [ALC883_3ST_6ch] = "3stack-6ch",
9243 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9244 [ALC883_TARGA_DIG] = "targa-dig",
9245 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9246 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9247 [ALC883_ACER] = "acer",
9248 [ALC883_ACER_ASPIRE] = "acer-aspire",
9249 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9250 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9251 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9252 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9253 [ALC883_MEDION] = "medion",
9254 [ALC883_MEDION_MD2] = "medion-md2",
9255 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9256 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9257 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9258 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9259 [ALC888_LENOVO_SKY] = "lenovo-sky",
9260 [ALC883_HAIER_W66] = "haier-w66",
9261 [ALC888_3ST_HP] = "3stack-hp",
9262 [ALC888_6ST_DELL] = "6stack-dell",
9263 [ALC883_MITAC] = "mitac",
9264 [ALC883_CLEVO_M540R] = "clevo-m540r",
9265 [ALC883_CLEVO_M720] = "clevo-m720",
9266 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9267 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9268 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9269 [ALC889A_INTEL] = "intel-alc889a",
9270 [ALC889_INTEL] = "intel-x58",
9271 [ALC1200_ASUS_P5Q] = "asus-p5q",
9272 [ALC889A_MB31] = "mb31",
9273 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9274 [ALC882_AUTO] = "auto",
9275 };
9276
9277 static struct snd_pci_quirk alc882_cfg_tbl[] = {
9278 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9279
9280 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9281 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9282 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9283 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9284 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9285 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9286 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9287 ALC888_ACER_ASPIRE_4930G),
9288 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9289 ALC888_ACER_ASPIRE_4930G),
9290 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9291 ALC888_ACER_ASPIRE_8930G),
9292 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9293 ALC888_ACER_ASPIRE_8930G),
9294 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9295 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9296 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9297 ALC888_ACER_ASPIRE_6530G),
9298 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9299 ALC888_ACER_ASPIRE_6530G),
9300 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9301 ALC888_ACER_ASPIRE_7730G),
9302 /* default Acer -- disabled as it causes more problems.
9303 * model=auto should work fine now
9304 */
9305 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9306
9307 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9308
9309 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9310 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9311 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9312 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9313 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9314 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9315
9316 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9317 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9318 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9319 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9320 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9321 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9322 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9323 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9324 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9325 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9326 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9327
9328 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9329 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9330 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9331 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9332 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9333 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9334 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9335 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9336 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9337
9338 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9339 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9340 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9341 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9342 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9343 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9344 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9345 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9346 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9347 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9348 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9349 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9350 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9351 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9352 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9353 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9354 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9355 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9356 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9357 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9358 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9359 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9360 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9361 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9362 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9363 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9364 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9365 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9366 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9367 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9368 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9369
9370 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9371 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9372 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9373 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9374 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9375 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9376 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9377 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9378 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9379 ALC883_FUJITSU_PI2515),
9380 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9381 ALC888_FUJITSU_XA3530),
9382 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9383 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9384 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9385 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9386 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9387 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
9388 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9389 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9390 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9391
9392 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9393 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9394 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9395 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9396 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9397 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9398 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9399
9400 {}
9401 };
9402
9403 /* codec SSID table for Intel Mac */
9404 static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9405 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9406 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9407 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9408 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9409 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9410 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9411 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
9412 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9413 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9414 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
9415 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
9416 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
9417 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
9418 * so apparently no perfect solution yet
9419 */
9420 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9421 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9422 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9423 {} /* terminator */
9424 };
9425
9426 static struct alc_config_preset alc882_presets[] = {
9427 [ALC882_3ST_DIG] = {
9428 .mixers = { alc882_base_mixer },
9429 .init_verbs = { alc882_base_init_verbs,
9430 alc882_adc1_init_verbs },
9431 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9432 .dac_nids = alc882_dac_nids,
9433 .dig_out_nid = ALC882_DIGOUT_NID,
9434 .dig_in_nid = ALC882_DIGIN_NID,
9435 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9436 .channel_mode = alc882_ch_modes,
9437 .need_dac_fix = 1,
9438 .input_mux = &alc882_capture_source,
9439 },
9440 [ALC882_6ST_DIG] = {
9441 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9442 .init_verbs = { alc882_base_init_verbs,
9443 alc882_adc1_init_verbs },
9444 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9445 .dac_nids = alc882_dac_nids,
9446 .dig_out_nid = ALC882_DIGOUT_NID,
9447 .dig_in_nid = ALC882_DIGIN_NID,
9448 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9449 .channel_mode = alc882_sixstack_modes,
9450 .input_mux = &alc882_capture_source,
9451 },
9452 [ALC882_ARIMA] = {
9453 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
9454 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9455 alc882_eapd_verbs },
9456 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9457 .dac_nids = alc882_dac_nids,
9458 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
9459 .channel_mode = alc882_sixstack_modes,
9460 .input_mux = &alc882_capture_source,
9461 },
9462 [ALC882_W2JC] = {
9463 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
9464 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9465 alc882_eapd_verbs, alc880_gpio1_init_verbs },
9466 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9467 .dac_nids = alc882_dac_nids,
9468 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9469 .channel_mode = alc880_threestack_modes,
9470 .need_dac_fix = 1,
9471 .input_mux = &alc882_capture_source,
9472 .dig_out_nid = ALC882_DIGOUT_NID,
9473 },
9474 [ALC885_MBA21] = {
9475 .mixers = { alc885_mba21_mixer },
9476 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9477 .num_dacs = 2,
9478 .dac_nids = alc882_dac_nids,
9479 .channel_mode = alc885_mba21_ch_modes,
9480 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9481 .input_mux = &alc882_capture_source,
9482 .unsol_event = alc_automute_amp_unsol_event,
9483 .setup = alc885_mba21_setup,
9484 .init_hook = alc_automute_amp,
9485 },
9486 [ALC885_MBP3] = {
9487 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9488 .init_verbs = { alc885_mbp3_init_verbs,
9489 alc880_gpio1_init_verbs },
9490 .num_dacs = 2,
9491 .dac_nids = alc882_dac_nids,
9492 .hp_nid = 0x04,
9493 .channel_mode = alc885_mbp_4ch_modes,
9494 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9495 .input_mux = &alc882_capture_source,
9496 .dig_out_nid = ALC882_DIGOUT_NID,
9497 .dig_in_nid = ALC882_DIGIN_NID,
9498 .unsol_event = alc_automute_amp_unsol_event,
9499 .setup = alc885_mbp3_setup,
9500 .init_hook = alc_automute_amp,
9501 },
9502 [ALC885_MB5] = {
9503 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
9504 .init_verbs = { alc885_mb5_init_verbs,
9505 alc880_gpio1_init_verbs },
9506 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9507 .dac_nids = alc882_dac_nids,
9508 .channel_mode = alc885_mb5_6ch_modes,
9509 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
9510 .input_mux = &mb5_capture_source,
9511 .dig_out_nid = ALC882_DIGOUT_NID,
9512 .dig_in_nid = ALC882_DIGIN_NID,
9513 .unsol_event = alc_automute_amp_unsol_event,
9514 .setup = alc885_mb5_setup,
9515 .init_hook = alc_automute_amp,
9516 },
9517 [ALC885_MACMINI3] = {
9518 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9519 .init_verbs = { alc885_macmini3_init_verbs,
9520 alc880_gpio1_init_verbs },
9521 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9522 .dac_nids = alc882_dac_nids,
9523 .channel_mode = alc885_macmini3_6ch_modes,
9524 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9525 .input_mux = &macmini3_capture_source,
9526 .dig_out_nid = ALC882_DIGOUT_NID,
9527 .dig_in_nid = ALC882_DIGIN_NID,
9528 .unsol_event = alc_automute_amp_unsol_event,
9529 .setup = alc885_macmini3_setup,
9530 .init_hook = alc_automute_amp,
9531 },
9532 [ALC885_MACPRO] = {
9533 .mixers = { alc882_macpro_mixer },
9534 .init_verbs = { alc882_macpro_init_verbs },
9535 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9536 .dac_nids = alc882_dac_nids,
9537 .dig_out_nid = ALC882_DIGOUT_NID,
9538 .dig_in_nid = ALC882_DIGIN_NID,
9539 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9540 .channel_mode = alc882_ch_modes,
9541 .input_mux = &alc882_capture_source,
9542 .init_hook = alc885_macpro_init_hook,
9543 },
9544 [ALC885_IMAC24] = {
9545 .mixers = { alc885_imac24_mixer },
9546 .init_verbs = { alc885_imac24_init_verbs },
9547 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9548 .dac_nids = alc882_dac_nids,
9549 .dig_out_nid = ALC882_DIGOUT_NID,
9550 .dig_in_nid = ALC882_DIGIN_NID,
9551 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
9552 .channel_mode = alc882_ch_modes,
9553 .input_mux = &alc882_capture_source,
9554 .unsol_event = alc_automute_amp_unsol_event,
9555 .setup = alc885_imac24_setup,
9556 .init_hook = alc885_imac24_init_hook,
9557 },
9558 [ALC885_IMAC91] = {
9559 .mixers = { alc885_imac91_mixer, alc882_chmode_mixer },
9560 .init_verbs = { alc885_imac91_init_verbs,
9561 alc880_gpio1_init_verbs },
9562 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9563 .dac_nids = alc882_dac_nids,
9564 .channel_mode = alc885_mbp_4ch_modes,
9565 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
9566 .input_mux = &alc882_capture_source,
9567 .dig_out_nid = ALC882_DIGOUT_NID,
9568 .dig_in_nid = ALC882_DIGIN_NID,
9569 .unsol_event = alc_automute_amp_unsol_event,
9570 .setup = alc885_imac91_setup,
9571 .init_hook = alc_automute_amp,
9572 },
9573 [ALC882_TARGA] = {
9574 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
9575 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9576 alc880_gpio3_init_verbs, alc882_targa_verbs},
9577 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9578 .dac_nids = alc882_dac_nids,
9579 .dig_out_nid = ALC882_DIGOUT_NID,
9580 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9581 .adc_nids = alc882_adc_nids,
9582 .capsrc_nids = alc882_capsrc_nids,
9583 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9584 .channel_mode = alc882_3ST_6ch_modes,
9585 .need_dac_fix = 1,
9586 .input_mux = &alc882_capture_source,
9587 .unsol_event = alc882_targa_unsol_event,
9588 .setup = alc882_targa_setup,
9589 .init_hook = alc882_targa_automute,
9590 },
9591 [ALC882_ASUS_A7J] = {
9592 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9593 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9594 alc882_asus_a7j_verbs},
9595 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9596 .dac_nids = alc882_dac_nids,
9597 .dig_out_nid = ALC882_DIGOUT_NID,
9598 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9599 .adc_nids = alc882_adc_nids,
9600 .capsrc_nids = alc882_capsrc_nids,
9601 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9602 .channel_mode = alc882_3ST_6ch_modes,
9603 .need_dac_fix = 1,
9604 .input_mux = &alc882_capture_source,
9605 },
9606 [ALC882_ASUS_A7M] = {
9607 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9608 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9609 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9610 alc882_asus_a7m_verbs },
9611 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9612 .dac_nids = alc882_dac_nids,
9613 .dig_out_nid = ALC882_DIGOUT_NID,
9614 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9615 .channel_mode = alc880_threestack_modes,
9616 .need_dac_fix = 1,
9617 .input_mux = &alc882_capture_source,
9618 },
9619 [ALC883_3ST_2ch_DIG] = {
9620 .mixers = { alc883_3ST_2ch_mixer },
9621 .init_verbs = { alc883_init_verbs },
9622 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9623 .dac_nids = alc883_dac_nids,
9624 .dig_out_nid = ALC883_DIGOUT_NID,
9625 .dig_in_nid = ALC883_DIGIN_NID,
9626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9627 .channel_mode = alc883_3ST_2ch_modes,
9628 .input_mux = &alc883_capture_source,
9629 },
9630 [ALC883_3ST_6ch_DIG] = {
9631 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9632 .init_verbs = { alc883_init_verbs },
9633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9634 .dac_nids = alc883_dac_nids,
9635 .dig_out_nid = ALC883_DIGOUT_NID,
9636 .dig_in_nid = ALC883_DIGIN_NID,
9637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9638 .channel_mode = alc883_3ST_6ch_modes,
9639 .need_dac_fix = 1,
9640 .input_mux = &alc883_capture_source,
9641 },
9642 [ALC883_3ST_6ch] = {
9643 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9644 .init_verbs = { alc883_init_verbs },
9645 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9646 .dac_nids = alc883_dac_nids,
9647 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9648 .channel_mode = alc883_3ST_6ch_modes,
9649 .need_dac_fix = 1,
9650 .input_mux = &alc883_capture_source,
9651 },
9652 [ALC883_3ST_6ch_INTEL] = {
9653 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
9654 .init_verbs = { alc883_init_verbs },
9655 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9656 .dac_nids = alc883_dac_nids,
9657 .dig_out_nid = ALC883_DIGOUT_NID,
9658 .dig_in_nid = ALC883_DIGIN_NID,
9659 .slave_dig_outs = alc883_slave_dig_outs,
9660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
9661 .channel_mode = alc883_3ST_6ch_intel_modes,
9662 .need_dac_fix = 1,
9663 .input_mux = &alc883_3stack_6ch_intel,
9664 },
9665 [ALC889A_INTEL] = {
9666 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9667 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9668 alc_hp15_unsol_verbs },
9669 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9670 .dac_nids = alc883_dac_nids,
9671 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9672 .adc_nids = alc889_adc_nids,
9673 .dig_out_nid = ALC883_DIGOUT_NID,
9674 .dig_in_nid = ALC883_DIGIN_NID,
9675 .slave_dig_outs = alc883_slave_dig_outs,
9676 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9677 .channel_mode = alc889_8ch_intel_modes,
9678 .capsrc_nids = alc889_capsrc_nids,
9679 .input_mux = &alc889_capture_source,
9680 .setup = alc889_automute_setup,
9681 .init_hook = alc_automute_amp,
9682 .unsol_event = alc_automute_amp_unsol_event,
9683 .need_dac_fix = 1,
9684 },
9685 [ALC889_INTEL] = {
9686 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9687 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9688 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9689 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9690 .dac_nids = alc883_dac_nids,
9691 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9692 .adc_nids = alc889_adc_nids,
9693 .dig_out_nid = ALC883_DIGOUT_NID,
9694 .dig_in_nid = ALC883_DIGIN_NID,
9695 .slave_dig_outs = alc883_slave_dig_outs,
9696 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9697 .channel_mode = alc889_8ch_intel_modes,
9698 .capsrc_nids = alc889_capsrc_nids,
9699 .input_mux = &alc889_capture_source,
9700 .setup = alc889_automute_setup,
9701 .init_hook = alc889_intel_init_hook,
9702 .unsol_event = alc_automute_amp_unsol_event,
9703 .need_dac_fix = 1,
9704 },
9705 [ALC883_6ST_DIG] = {
9706 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9707 .init_verbs = { alc883_init_verbs },
9708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9709 .dac_nids = alc883_dac_nids,
9710 .dig_out_nid = ALC883_DIGOUT_NID,
9711 .dig_in_nid = ALC883_DIGIN_NID,
9712 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9713 .channel_mode = alc883_sixstack_modes,
9714 .input_mux = &alc883_capture_source,
9715 },
9716 [ALC883_TARGA_DIG] = {
9717 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
9718 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9719 alc883_targa_verbs},
9720 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9721 .dac_nids = alc883_dac_nids,
9722 .dig_out_nid = ALC883_DIGOUT_NID,
9723 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9724 .channel_mode = alc883_3ST_6ch_modes,
9725 .need_dac_fix = 1,
9726 .input_mux = &alc883_capture_source,
9727 .unsol_event = alc883_targa_unsol_event,
9728 .setup = alc882_targa_setup,
9729 .init_hook = alc882_targa_automute,
9730 },
9731 [ALC883_TARGA_2ch_DIG] = {
9732 .mixers = { alc883_targa_2ch_mixer},
9733 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9734 alc883_targa_verbs},
9735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9736 .dac_nids = alc883_dac_nids,
9737 .adc_nids = alc883_adc_nids_alt,
9738 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9739 .capsrc_nids = alc883_capsrc_nids,
9740 .dig_out_nid = ALC883_DIGOUT_NID,
9741 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9742 .channel_mode = alc883_3ST_2ch_modes,
9743 .input_mux = &alc883_capture_source,
9744 .unsol_event = alc883_targa_unsol_event,
9745 .setup = alc882_targa_setup,
9746 .init_hook = alc882_targa_automute,
9747 },
9748 [ALC883_TARGA_8ch_DIG] = {
9749 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
9750 alc883_chmode_mixer },
9751 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
9752 alc883_targa_verbs },
9753 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9754 .dac_nids = alc883_dac_nids,
9755 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9756 .adc_nids = alc883_adc_nids_rev,
9757 .capsrc_nids = alc883_capsrc_nids_rev,
9758 .dig_out_nid = ALC883_DIGOUT_NID,
9759 .dig_in_nid = ALC883_DIGIN_NID,
9760 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
9761 .channel_mode = alc883_4ST_8ch_modes,
9762 .need_dac_fix = 1,
9763 .input_mux = &alc883_capture_source,
9764 .unsol_event = alc883_targa_unsol_event,
9765 .setup = alc882_targa_setup,
9766 .init_hook = alc882_targa_automute,
9767 },
9768 [ALC883_ACER] = {
9769 .mixers = { alc883_base_mixer },
9770 /* On TravelMate laptops, GPIO 0 enables the internal speaker
9771 * and the headphone jack. Turn this on and rely on the
9772 * standard mute methods whenever the user wants to turn
9773 * these outputs off.
9774 */
9775 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
9776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9777 .dac_nids = alc883_dac_nids,
9778 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9779 .channel_mode = alc883_3ST_2ch_modes,
9780 .input_mux = &alc883_capture_source,
9781 },
9782 [ALC883_ACER_ASPIRE] = {
9783 .mixers = { alc883_acer_aspire_mixer },
9784 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
9785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9786 .dac_nids = alc883_dac_nids,
9787 .dig_out_nid = ALC883_DIGOUT_NID,
9788 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9789 .channel_mode = alc883_3ST_2ch_modes,
9790 .input_mux = &alc883_capture_source,
9791 .unsol_event = alc_automute_amp_unsol_event,
9792 .setup = alc883_acer_aspire_setup,
9793 .init_hook = alc_automute_amp,
9794 },
9795 [ALC888_ACER_ASPIRE_4930G] = {
9796 .mixers = { alc888_base_mixer,
9797 alc883_chmode_mixer },
9798 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9799 alc888_acer_aspire_4930g_verbs },
9800 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9801 .dac_nids = alc883_dac_nids,
9802 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9803 .adc_nids = alc883_adc_nids_rev,
9804 .capsrc_nids = alc883_capsrc_nids_rev,
9805 .dig_out_nid = ALC883_DIGOUT_NID,
9806 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9807 .channel_mode = alc883_3ST_6ch_modes,
9808 .need_dac_fix = 1,
9809 .const_channel_count = 6,
9810 .num_mux_defs =
9811 ARRAY_SIZE(alc888_2_capture_sources),
9812 .input_mux = alc888_2_capture_sources,
9813 .unsol_event = alc_automute_amp_unsol_event,
9814 .setup = alc888_acer_aspire_4930g_setup,
9815 .init_hook = alc_automute_amp,
9816 },
9817 [ALC888_ACER_ASPIRE_6530G] = {
9818 .mixers = { alc888_acer_aspire_6530_mixer },
9819 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9820 alc888_acer_aspire_6530g_verbs },
9821 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9822 .dac_nids = alc883_dac_nids,
9823 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9824 .adc_nids = alc883_adc_nids_rev,
9825 .capsrc_nids = alc883_capsrc_nids_rev,
9826 .dig_out_nid = ALC883_DIGOUT_NID,
9827 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9828 .channel_mode = alc883_3ST_2ch_modes,
9829 .num_mux_defs =
9830 ARRAY_SIZE(alc888_2_capture_sources),
9831 .input_mux = alc888_acer_aspire_6530_sources,
9832 .unsol_event = alc_automute_amp_unsol_event,
9833 .setup = alc888_acer_aspire_6530g_setup,
9834 .init_hook = alc_automute_amp,
9835 },
9836 [ALC888_ACER_ASPIRE_8930G] = {
9837 .mixers = { alc889_acer_aspire_8930g_mixer,
9838 alc883_chmode_mixer },
9839 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9840 alc889_acer_aspire_8930g_verbs,
9841 alc889_eapd_verbs},
9842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9843 .dac_nids = alc883_dac_nids,
9844 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9845 .adc_nids = alc889_adc_nids,
9846 .capsrc_nids = alc889_capsrc_nids,
9847 .dig_out_nid = ALC883_DIGOUT_NID,
9848 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9849 .channel_mode = alc883_3ST_6ch_modes,
9850 .need_dac_fix = 1,
9851 .const_channel_count = 6,
9852 .num_mux_defs =
9853 ARRAY_SIZE(alc889_capture_sources),
9854 .input_mux = alc889_capture_sources,
9855 .unsol_event = alc_automute_amp_unsol_event,
9856 .setup = alc889_acer_aspire_8930g_setup,
9857 .init_hook = alc_automute_amp,
9858 #ifdef CONFIG_SND_HDA_POWER_SAVE
9859 .power_hook = alc_power_eapd,
9860 #endif
9861 },
9862 [ALC888_ACER_ASPIRE_7730G] = {
9863 .mixers = { alc883_3ST_6ch_mixer,
9864 alc883_chmode_mixer },
9865 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9866 alc888_acer_aspire_7730G_verbs },
9867 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9868 .dac_nids = alc883_dac_nids,
9869 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9870 .adc_nids = alc883_adc_nids_rev,
9871 .capsrc_nids = alc883_capsrc_nids_rev,
9872 .dig_out_nid = ALC883_DIGOUT_NID,
9873 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9874 .channel_mode = alc883_3ST_6ch_modes,
9875 .need_dac_fix = 1,
9876 .const_channel_count = 6,
9877 .input_mux = &alc883_capture_source,
9878 .unsol_event = alc_automute_amp_unsol_event,
9879 .setup = alc888_acer_aspire_6530g_setup,
9880 .init_hook = alc_automute_amp,
9881 },
9882 [ALC883_MEDION] = {
9883 .mixers = { alc883_fivestack_mixer,
9884 alc883_chmode_mixer },
9885 .init_verbs = { alc883_init_verbs,
9886 alc883_medion_eapd_verbs },
9887 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9888 .dac_nids = alc883_dac_nids,
9889 .adc_nids = alc883_adc_nids_alt,
9890 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9891 .capsrc_nids = alc883_capsrc_nids,
9892 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
9893 .channel_mode = alc883_sixstack_modes,
9894 .input_mux = &alc883_capture_source,
9895 },
9896 [ALC883_MEDION_MD2] = {
9897 .mixers = { alc883_medion_md2_mixer},
9898 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
9899 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9900 .dac_nids = alc883_dac_nids,
9901 .dig_out_nid = ALC883_DIGOUT_NID,
9902 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9903 .channel_mode = alc883_3ST_2ch_modes,
9904 .input_mux = &alc883_capture_source,
9905 .unsol_event = alc_automute_amp_unsol_event,
9906 .setup = alc883_medion_md2_setup,
9907 .init_hook = alc_automute_amp,
9908 },
9909 [ALC883_LAPTOP_EAPD] = {
9910 .mixers = { alc883_base_mixer },
9911 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
9912 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9913 .dac_nids = alc883_dac_nids,
9914 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9915 .channel_mode = alc883_3ST_2ch_modes,
9916 .input_mux = &alc883_capture_source,
9917 },
9918 [ALC883_CLEVO_M540R] = {
9919 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9920 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9921 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9922 .dac_nids = alc883_dac_nids,
9923 .dig_out_nid = ALC883_DIGOUT_NID,
9924 .dig_in_nid = ALC883_DIGIN_NID,
9925 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9926 .channel_mode = alc883_3ST_6ch_clevo_modes,
9927 .need_dac_fix = 1,
9928 .input_mux = &alc883_capture_source,
9929 /* This machine has the hardware HP auto-muting, thus
9930 * we need no software mute via unsol event
9931 */
9932 },
9933 [ALC883_CLEVO_M720] = {
9934 .mixers = { alc883_clevo_m720_mixer },
9935 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
9936 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9937 .dac_nids = alc883_dac_nids,
9938 .dig_out_nid = ALC883_DIGOUT_NID,
9939 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9940 .channel_mode = alc883_3ST_2ch_modes,
9941 .input_mux = &alc883_capture_source,
9942 .unsol_event = alc883_clevo_m720_unsol_event,
9943 .setup = alc883_clevo_m720_setup,
9944 .init_hook = alc883_clevo_m720_init_hook,
9945 },
9946 [ALC883_LENOVO_101E_2ch] = {
9947 .mixers = { alc883_lenovo_101e_2ch_mixer},
9948 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
9949 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9950 .dac_nids = alc883_dac_nids,
9951 .adc_nids = alc883_adc_nids_alt,
9952 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
9953 .capsrc_nids = alc883_capsrc_nids,
9954 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9955 .channel_mode = alc883_3ST_2ch_modes,
9956 .input_mux = &alc883_lenovo_101e_capture_source,
9957 .unsol_event = alc883_lenovo_101e_unsol_event,
9958 .init_hook = alc883_lenovo_101e_all_automute,
9959 },
9960 [ALC883_LENOVO_NB0763] = {
9961 .mixers = { alc883_lenovo_nb0763_mixer },
9962 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
9963 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9964 .dac_nids = alc883_dac_nids,
9965 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9966 .channel_mode = alc883_3ST_2ch_modes,
9967 .need_dac_fix = 1,
9968 .input_mux = &alc883_lenovo_nb0763_capture_source,
9969 .unsol_event = alc_automute_amp_unsol_event,
9970 .setup = alc883_medion_md2_setup,
9971 .init_hook = alc_automute_amp,
9972 },
9973 [ALC888_LENOVO_MS7195_DIG] = {
9974 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9975 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
9976 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9977 .dac_nids = alc883_dac_nids,
9978 .dig_out_nid = ALC883_DIGOUT_NID,
9979 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9980 .channel_mode = alc883_3ST_6ch_modes,
9981 .need_dac_fix = 1,
9982 .input_mux = &alc883_capture_source,
9983 .unsol_event = alc883_lenovo_ms7195_unsol_event,
9984 .init_hook = alc888_lenovo_ms7195_front_automute,
9985 },
9986 [ALC883_HAIER_W66] = {
9987 .mixers = { alc883_targa_2ch_mixer},
9988 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
9989 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9990 .dac_nids = alc883_dac_nids,
9991 .dig_out_nid = ALC883_DIGOUT_NID,
9992 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
9993 .channel_mode = alc883_3ST_2ch_modes,
9994 .input_mux = &alc883_capture_source,
9995 .unsol_event = alc_automute_amp_unsol_event,
9996 .setup = alc883_haier_w66_setup,
9997 .init_hook = alc_automute_amp,
9998 },
9999 [ALC888_3ST_HP] = {
10000 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10001 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10002 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10003 .dac_nids = alc883_dac_nids,
10004 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10005 .channel_mode = alc888_3st_hp_modes,
10006 .need_dac_fix = 1,
10007 .input_mux = &alc883_capture_source,
10008 .unsol_event = alc_automute_amp_unsol_event,
10009 .setup = alc888_3st_hp_setup,
10010 .init_hook = alc_automute_amp,
10011 },
10012 [ALC888_6ST_DELL] = {
10013 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10014 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10015 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10016 .dac_nids = alc883_dac_nids,
10017 .dig_out_nid = ALC883_DIGOUT_NID,
10018 .dig_in_nid = ALC883_DIGIN_NID,
10019 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10020 .channel_mode = alc883_sixstack_modes,
10021 .input_mux = &alc883_capture_source,
10022 .unsol_event = alc_automute_amp_unsol_event,
10023 .setup = alc888_6st_dell_setup,
10024 .init_hook = alc_automute_amp,
10025 },
10026 [ALC883_MITAC] = {
10027 .mixers = { alc883_mitac_mixer },
10028 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10029 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10030 .dac_nids = alc883_dac_nids,
10031 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10032 .channel_mode = alc883_3ST_2ch_modes,
10033 .input_mux = &alc883_capture_source,
10034 .unsol_event = alc_automute_amp_unsol_event,
10035 .setup = alc883_mitac_setup,
10036 .init_hook = alc_automute_amp,
10037 },
10038 [ALC883_FUJITSU_PI2515] = {
10039 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10040 .init_verbs = { alc883_init_verbs,
10041 alc883_2ch_fujitsu_pi2515_verbs},
10042 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10043 .dac_nids = alc883_dac_nids,
10044 .dig_out_nid = ALC883_DIGOUT_NID,
10045 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10046 .channel_mode = alc883_3ST_2ch_modes,
10047 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10048 .unsol_event = alc_automute_amp_unsol_event,
10049 .setup = alc883_2ch_fujitsu_pi2515_setup,
10050 .init_hook = alc_automute_amp,
10051 },
10052 [ALC888_FUJITSU_XA3530] = {
10053 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10054 .init_verbs = { alc883_init_verbs,
10055 alc888_fujitsu_xa3530_verbs },
10056 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10057 .dac_nids = alc883_dac_nids,
10058 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10059 .adc_nids = alc883_adc_nids_rev,
10060 .capsrc_nids = alc883_capsrc_nids_rev,
10061 .dig_out_nid = ALC883_DIGOUT_NID,
10062 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10063 .channel_mode = alc888_4ST_8ch_intel_modes,
10064 .num_mux_defs =
10065 ARRAY_SIZE(alc888_2_capture_sources),
10066 .input_mux = alc888_2_capture_sources,
10067 .unsol_event = alc_automute_amp_unsol_event,
10068 .setup = alc888_fujitsu_xa3530_setup,
10069 .init_hook = alc_automute_amp,
10070 },
10071 [ALC888_LENOVO_SKY] = {
10072 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10073 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10074 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10075 .dac_nids = alc883_dac_nids,
10076 .dig_out_nid = ALC883_DIGOUT_NID,
10077 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10078 .channel_mode = alc883_sixstack_modes,
10079 .need_dac_fix = 1,
10080 .input_mux = &alc883_lenovo_sky_capture_source,
10081 .unsol_event = alc_automute_amp_unsol_event,
10082 .setup = alc888_lenovo_sky_setup,
10083 .init_hook = alc_automute_amp,
10084 },
10085 [ALC888_ASUS_M90V] = {
10086 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10087 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10088 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10089 .dac_nids = alc883_dac_nids,
10090 .dig_out_nid = ALC883_DIGOUT_NID,
10091 .dig_in_nid = ALC883_DIGIN_NID,
10092 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10093 .channel_mode = alc883_3ST_6ch_modes,
10094 .need_dac_fix = 1,
10095 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10096 .unsol_event = alc_sku_unsol_event,
10097 .setup = alc883_mode2_setup,
10098 .init_hook = alc_inithook,
10099 },
10100 [ALC888_ASUS_EEE1601] = {
10101 .mixers = { alc883_asus_eee1601_mixer },
10102 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10103 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10104 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10105 .dac_nids = alc883_dac_nids,
10106 .dig_out_nid = ALC883_DIGOUT_NID,
10107 .dig_in_nid = ALC883_DIGIN_NID,
10108 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10109 .channel_mode = alc883_3ST_2ch_modes,
10110 .need_dac_fix = 1,
10111 .input_mux = &alc883_asus_eee1601_capture_source,
10112 .unsol_event = alc_sku_unsol_event,
10113 .init_hook = alc883_eee1601_inithook,
10114 },
10115 [ALC1200_ASUS_P5Q] = {
10116 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10117 .init_verbs = { alc883_init_verbs },
10118 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10119 .dac_nids = alc883_dac_nids,
10120 .dig_out_nid = ALC1200_DIGOUT_NID,
10121 .dig_in_nid = ALC883_DIGIN_NID,
10122 .slave_dig_outs = alc1200_slave_dig_outs,
10123 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10124 .channel_mode = alc883_sixstack_modes,
10125 .input_mux = &alc883_capture_source,
10126 },
10127 [ALC889A_MB31] = {
10128 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10129 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10130 alc880_gpio1_init_verbs },
10131 .adc_nids = alc883_adc_nids,
10132 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10133 .capsrc_nids = alc883_capsrc_nids,
10134 .dac_nids = alc883_dac_nids,
10135 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10136 .channel_mode = alc889A_mb31_6ch_modes,
10137 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10138 .input_mux = &alc889A_mb31_capture_source,
10139 .dig_out_nid = ALC883_DIGOUT_NID,
10140 .unsol_event = alc889A_mb31_unsol_event,
10141 .init_hook = alc889A_mb31_automute,
10142 },
10143 [ALC883_SONY_VAIO_TT] = {
10144 .mixers = { alc883_vaiott_mixer },
10145 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10146 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10147 .dac_nids = alc883_dac_nids,
10148 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10149 .channel_mode = alc883_3ST_2ch_modes,
10150 .input_mux = &alc883_capture_source,
10151 .unsol_event = alc_automute_amp_unsol_event,
10152 .setup = alc883_vaiott_setup,
10153 .init_hook = alc_automute_amp,
10154 },
10155 };
10156
10157
10158 /*
10159 * Pin config fixes
10160 */
10161 enum {
10162 PINFIX_ABIT_AW9D_MAX
10163 };
10164
10165 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
10166 { 0x15, 0x01080104 }, /* side */
10167 { 0x16, 0x01011012 }, /* rear */
10168 { 0x17, 0x01016011 }, /* clfe */
10169 { }
10170 };
10171
10172 static const struct alc_fixup alc882_fixups[] = {
10173 [PINFIX_ABIT_AW9D_MAX] = {
10174 .pins = alc882_abit_aw9d_pinfix
10175 },
10176 };
10177
10178 static struct snd_pci_quirk alc882_fixup_tbl[] = {
10179 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
10180 {}
10181 };
10182
10183 /*
10184 * BIOS auto configuration
10185 */
10186 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10187 const struct auto_pin_cfg *cfg)
10188 {
10189 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10190 }
10191
10192 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
10193 hda_nid_t nid, int pin_type,
10194 hda_nid_t dac)
10195 {
10196 int idx;
10197
10198 printk("XXX set output pin %x, dac %x\n", nid, dac);
10199 /* set as output */
10200 alc_set_pin_output(codec, nid, pin_type);
10201
10202 if (dac == 0x25)
10203 idx = 4;
10204 else if (dac >= 0x02 && dac <= 0x05)
10205 idx = dac - 2;
10206 else
10207 return;
10208 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
10209 }
10210
10211 static void alc882_auto_init_multi_out(struct hda_codec *codec)
10212 {
10213 struct alc_spec *spec = codec->spec;
10214 int i;
10215
10216 for (i = 0; i <= HDA_SIDE; i++) {
10217 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10218 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10219 if (nid)
10220 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
10221 spec->multiout.dac_nids[i]);
10222 }
10223 }
10224
10225 static void alc882_auto_init_hp_out(struct hda_codec *codec)
10226 {
10227 struct alc_spec *spec = codec->spec;
10228 hda_nid_t pin, dac;
10229
10230 pin = spec->autocfg.hp_pins[0];
10231 if (pin) {
10232 dac = spec->multiout.hp_nid;
10233 if (!dac)
10234 dac = spec->multiout.dac_nids[0]; /* to front */
10235 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
10236 }
10237 pin = spec->autocfg.speaker_pins[0];
10238 if (pin) {
10239 dac = spec->multiout.extra_out_nid[0];
10240 if (!dac)
10241 dac = spec->multiout.dac_nids[0]; /* to front */
10242 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
10243 }
10244 }
10245
10246 static void alc882_auto_init_analog_input(struct hda_codec *codec)
10247 {
10248 struct alc_spec *spec = codec->spec;
10249 int i;
10250
10251 for (i = 0; i < AUTO_PIN_LAST; i++) {
10252 hda_nid_t nid = spec->autocfg.input_pins[i];
10253 if (!nid)
10254 continue;
10255 alc_set_input_pin(codec, nid, i);
10256 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
10257 snd_hda_codec_write(codec, nid, 0,
10258 AC_VERB_SET_AMP_GAIN_MUTE,
10259 AMP_OUT_MUTE);
10260 }
10261 }
10262
10263 static void alc882_auto_init_input_src(struct hda_codec *codec)
10264 {
10265 struct alc_spec *spec = codec->spec;
10266 int c;
10267
10268 for (c = 0; c < spec->num_adc_nids; c++) {
10269 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
10270 hda_nid_t nid = spec->capsrc_nids[c];
10271 unsigned int mux_idx;
10272 const struct hda_input_mux *imux;
10273 int conns, mute, idx, item;
10274
10275 conns = snd_hda_get_connections(codec, nid, conn_list,
10276 ARRAY_SIZE(conn_list));
10277 if (conns < 0)
10278 continue;
10279 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10280 imux = &spec->input_mux[mux_idx];
10281 if (!imux->num_items && mux_idx > 0)
10282 imux = &spec->input_mux[0];
10283 for (idx = 0; idx < conns; idx++) {
10284 /* if the current connection is the selected one,
10285 * unmute it as default - otherwise mute it
10286 */
10287 mute = AMP_IN_MUTE(idx);
10288 for (item = 0; item < imux->num_items; item++) {
10289 if (imux->items[item].index == idx) {
10290 if (spec->cur_mux[c] == item)
10291 mute = AMP_IN_UNMUTE(idx);
10292 break;
10293 }
10294 }
10295 /* check if we have a selector or mixer
10296 * we could check for the widget type instead, but
10297 * just check for Amp-In presence (in case of mixer
10298 * without amp-in there is something wrong, this
10299 * function shouldn't be used or capsrc nid is wrong)
10300 */
10301 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
10302 snd_hda_codec_write(codec, nid, 0,
10303 AC_VERB_SET_AMP_GAIN_MUTE,
10304 mute);
10305 else if (mute != AMP_IN_MUTE(idx))
10306 snd_hda_codec_write(codec, nid, 0,
10307 AC_VERB_SET_CONNECT_SEL,
10308 idx);
10309 }
10310 }
10311 }
10312
10313 /* add mic boosts if needed */
10314 static int alc_auto_add_mic_boost(struct hda_codec *codec)
10315 {
10316 struct alc_spec *spec = codec->spec;
10317 int err;
10318 hda_nid_t nid;
10319
10320 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
10321 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10322 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10323 "Mic Boost",
10324 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10325 if (err < 0)
10326 return err;
10327 }
10328 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
10329 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
10330 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10331 "Front Mic Boost",
10332 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10333 if (err < 0)
10334 return err;
10335 }
10336 return 0;
10337 }
10338
10339 /* almost identical with ALC880 parser... */
10340 static int alc882_parse_auto_config(struct hda_codec *codec)
10341 {
10342 struct alc_spec *spec = codec->spec;
10343 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
10344 int i, err;
10345
10346 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10347 alc882_ignore);
10348 if (err < 0)
10349 return err;
10350 if (!spec->autocfg.line_outs)
10351 return 0; /* can't find valid BIOS pin config */
10352
10353 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10354 if (err < 0)
10355 return err;
10356 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10357 if (err < 0)
10358 return err;
10359 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
10360 "Headphone");
10361 if (err < 0)
10362 return err;
10363 err = alc880_auto_create_extra_out(spec,
10364 spec->autocfg.speaker_pins[0],
10365 "Speaker");
10366 if (err < 0)
10367 return err;
10368 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
10369 if (err < 0)
10370 return err;
10371
10372 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10373
10374 /* check multiple SPDIF-out (for recent codecs) */
10375 for (i = 0; i < spec->autocfg.dig_outs; i++) {
10376 hda_nid_t dig_nid;
10377 err = snd_hda_get_connections(codec,
10378 spec->autocfg.dig_out_pins[i],
10379 &dig_nid, 1);
10380 if (err < 0)
10381 continue;
10382 if (!i)
10383 spec->multiout.dig_out_nid = dig_nid;
10384 else {
10385 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
10386 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
10387 break;
10388 spec->slave_dig_outs[i - 1] = dig_nid;
10389 }
10390 }
10391 if (spec->autocfg.dig_in_pin)
10392 spec->dig_in_nid = ALC880_DIGIN_NID;
10393
10394 if (spec->kctls.list)
10395 add_mixer(spec, spec->kctls.list);
10396
10397 add_verb(spec, alc883_auto_init_verbs);
10398 /* if ADC 0x07 is available, initialize it, too */
10399 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
10400 add_verb(spec, alc882_adc1_init_verbs);
10401
10402 spec->num_mux_defs = 1;
10403 spec->input_mux = &spec->private_imux[0];
10404
10405 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10406
10407 err = alc_auto_add_mic_boost(codec);
10408 if (err < 0)
10409 return err;
10410
10411 return 1; /* config found */
10412 }
10413
10414 /* additional initialization for auto-configuration model */
10415 static void alc882_auto_init(struct hda_codec *codec)
10416 {
10417 struct alc_spec *spec = codec->spec;
10418 alc882_auto_init_multi_out(codec);
10419 alc882_auto_init_hp_out(codec);
10420 alc882_auto_init_analog_input(codec);
10421 alc882_auto_init_input_src(codec);
10422 if (spec->unsol_event)
10423 alc_inithook(codec);
10424 }
10425
10426 static int patch_alc882(struct hda_codec *codec)
10427 {
10428 struct alc_spec *spec;
10429 int err, board_config;
10430
10431 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10432 if (spec == NULL)
10433 return -ENOMEM;
10434
10435 codec->spec = spec;
10436
10437 alc_auto_parse_customize_define(codec);
10438
10439 switch (codec->vendor_id) {
10440 case 0x10ec0882:
10441 case 0x10ec0885:
10442 break;
10443 default:
10444 /* ALC883 and variants */
10445 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10446 break;
10447 }
10448
10449 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10450 alc882_models,
10451 alc882_cfg_tbl);
10452
10453 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10454 board_config = snd_hda_check_board_codec_sid_config(codec,
10455 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10456
10457 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
10458 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10459 codec->chip_name);
10460 board_config = ALC882_AUTO;
10461 }
10462
10463 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups);
10464
10465 if (board_config == ALC882_AUTO) {
10466 /* automatic parse from the BIOS config */
10467 err = alc882_parse_auto_config(codec);
10468 if (err < 0) {
10469 alc_free(codec);
10470 return err;
10471 } else if (!err) {
10472 printk(KERN_INFO
10473 "hda_codec: Cannot set up configuration "
10474 "from BIOS. Using base mode...\n");
10475 board_config = ALC882_3ST_DIG;
10476 }
10477 }
10478
10479 err = snd_hda_attach_beep_device(codec, 0x1);
10480 if (err < 0) {
10481 alc_free(codec);
10482 return err;
10483 }
10484
10485 if (board_config != ALC882_AUTO)
10486 setup_preset(codec, &alc882_presets[board_config]);
10487
10488 spec->stream_analog_playback = &alc882_pcm_analog_playback;
10489 spec->stream_analog_capture = &alc882_pcm_analog_capture;
10490 /* FIXME: setup DAC5 */
10491 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
10492 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
10493
10494 spec->stream_digital_playback = &alc882_pcm_digital_playback;
10495 spec->stream_digital_capture = &alc882_pcm_digital_capture;
10496
10497 if (codec->vendor_id == 0x10ec0888)
10498 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
10499
10500 if (!spec->adc_nids && spec->input_mux) {
10501 int i, j;
10502 spec->num_adc_nids = 0;
10503 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
10504 const struct hda_input_mux *imux = spec->input_mux;
10505 hda_nid_t cap;
10506 hda_nid_t items[16];
10507 hda_nid_t nid = alc882_adc_nids[i];
10508 unsigned int wcap = get_wcaps(codec, nid);
10509 /* get type */
10510 wcap = get_wcaps_type(wcap);
10511 if (wcap != AC_WID_AUD_IN)
10512 continue;
10513 spec->private_adc_nids[spec->num_adc_nids] = nid;
10514 err = snd_hda_get_connections(codec, nid, &cap, 1);
10515 if (err < 0)
10516 continue;
10517 err = snd_hda_get_connections(codec, cap, items,
10518 ARRAY_SIZE(items));
10519 if (err < 0)
10520 continue;
10521 for (j = 0; j < imux->num_items; j++)
10522 if (imux->items[j].index >= err)
10523 break;
10524 if (j < imux->num_items)
10525 continue;
10526 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
10527 spec->num_adc_nids++;
10528 }
10529 spec->adc_nids = spec->private_adc_nids;
10530 spec->capsrc_nids = spec->private_capsrc_nids;
10531 }
10532
10533 set_capture_mixer(codec);
10534
10535 if (spec->cdefine.enable_pcbeep)
10536 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
10537
10538 spec->vmaster_nid = 0x0c;
10539
10540 codec->patch_ops = alc_patch_ops;
10541 if (board_config == ALC882_AUTO)
10542 spec->init_hook = alc882_auto_init;
10543 #ifdef CONFIG_SND_HDA_POWER_SAVE
10544 if (!spec->loopback.amplist)
10545 spec->loopback.amplist = alc882_loopbacks;
10546 #endif
10547
10548 return 0;
10549 }
10550
10551
10552 /*
10553 * ALC262 support
10554 */
10555
10556 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
10557 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
10558
10559 #define alc262_dac_nids alc260_dac_nids
10560 #define alc262_adc_nids alc882_adc_nids
10561 #define alc262_adc_nids_alt alc882_adc_nids_alt
10562 #define alc262_capsrc_nids alc882_capsrc_nids
10563 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
10564
10565 #define alc262_modes alc260_modes
10566 #define alc262_capture_source alc882_capture_source
10567
10568 static hda_nid_t alc262_dmic_adc_nids[1] = {
10569 /* ADC0 */
10570 0x09
10571 };
10572
10573 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
10574
10575 static struct snd_kcontrol_new alc262_base_mixer[] = {
10576 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10577 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10578 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10579 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10580 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10581 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10582 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10583 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10584 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10585 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10586 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10587 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10588 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
10589 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10590 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
10591 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
10592 { } /* end */
10593 };
10594
10595 /* update HP, line and mono-out pins according to the master switch */
10596 static void alc262_hp_master_update(struct hda_codec *codec)
10597 {
10598 struct alc_spec *spec = codec->spec;
10599 int val = spec->master_sw;
10600
10601 /* HP & line-out */
10602 snd_hda_codec_write_cache(codec, 0x1b, 0,
10603 AC_VERB_SET_PIN_WIDGET_CONTROL,
10604 val ? PIN_HP : 0);
10605 snd_hda_codec_write_cache(codec, 0x15, 0,
10606 AC_VERB_SET_PIN_WIDGET_CONTROL,
10607 val ? PIN_HP : 0);
10608 /* mono (speaker) depending on the HP jack sense */
10609 val = val && !spec->jack_present;
10610 snd_hda_codec_write_cache(codec, 0x16, 0,
10611 AC_VERB_SET_PIN_WIDGET_CONTROL,
10612 val ? PIN_OUT : 0);
10613 }
10614
10615 static void alc262_hp_bpc_automute(struct hda_codec *codec)
10616 {
10617 struct alc_spec *spec = codec->spec;
10618
10619 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
10620 alc262_hp_master_update(codec);
10621 }
10622
10623 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
10624 {
10625 if ((res >> 26) != ALC880_HP_EVENT)
10626 return;
10627 alc262_hp_bpc_automute(codec);
10628 }
10629
10630 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
10631 {
10632 struct alc_spec *spec = codec->spec;
10633
10634 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
10635 alc262_hp_master_update(codec);
10636 }
10637
10638 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
10639 unsigned int res)
10640 {
10641 if ((res >> 26) != ALC880_HP_EVENT)
10642 return;
10643 alc262_hp_wildwest_automute(codec);
10644 }
10645
10646 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
10647
10648 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
10649 struct snd_ctl_elem_value *ucontrol)
10650 {
10651 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10652 struct alc_spec *spec = codec->spec;
10653 int val = !!*ucontrol->value.integer.value;
10654
10655 if (val == spec->master_sw)
10656 return 0;
10657 spec->master_sw = val;
10658 alc262_hp_master_update(codec);
10659 return 1;
10660 }
10661
10662 #define ALC262_HP_MASTER_SWITCH \
10663 { \
10664 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10665 .name = "Master Playback Switch", \
10666 .info = snd_ctl_boolean_mono_info, \
10667 .get = alc262_hp_master_sw_get, \
10668 .put = alc262_hp_master_sw_put, \
10669 }, \
10670 { \
10671 .iface = NID_MAPPING, \
10672 .name = "Master Playback Switch", \
10673 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
10674 }
10675
10676
10677 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
10678 ALC262_HP_MASTER_SWITCH,
10679 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10680 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10681 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10682 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10683 HDA_OUTPUT),
10684 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10685 HDA_OUTPUT),
10686 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10688 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10689 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10691 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10692 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10693 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10694 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10695 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10696 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
10697 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
10698 { } /* end */
10699 };
10700
10701 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
10702 ALC262_HP_MASTER_SWITCH,
10703 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10704 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10705 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10706 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10707 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
10708 HDA_OUTPUT),
10709 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
10710 HDA_OUTPUT),
10711 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
10712 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
10713 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
10714 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10715 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10716 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10717 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10718 { } /* end */
10719 };
10720
10721 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10722 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10723 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10724 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
10725 { } /* end */
10726 };
10727
10728 /* mute/unmute internal speaker according to the hp jack and mute state */
10729 static void alc262_hp_t5735_setup(struct hda_codec *codec)
10730 {
10731 struct alc_spec *spec = codec->spec;
10732
10733 spec->autocfg.hp_pins[0] = 0x15;
10734 spec->autocfg.speaker_pins[0] = 0x14;
10735 }
10736
10737 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
10738 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10739 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10740 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10741 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10742 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10743 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10744 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10745 { } /* end */
10746 };
10747
10748 static struct hda_verb alc262_hp_t5735_verbs[] = {
10749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10750 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10751
10752 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10753 { }
10754 };
10755
10756 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
10757 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10759 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
10760 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
10761 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
10762 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
10763 { } /* end */
10764 };
10765
10766 static struct hda_verb alc262_hp_rp5700_verbs[] = {
10767 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10769 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10772 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10775 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
10777 {}
10778 };
10779
10780 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
10781 .num_items = 1,
10782 .items = {
10783 { "Line", 0x1 },
10784 },
10785 };
10786
10787 /* bind hp and internal speaker mute (with plug check) as master switch */
10788 static void alc262_hippo_master_update(struct hda_codec *codec)
10789 {
10790 struct alc_spec *spec = codec->spec;
10791 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10792 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
10793 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
10794 unsigned int mute;
10795
10796 /* HP */
10797 mute = spec->master_sw ? 0 : HDA_AMP_MUTE;
10798 snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0,
10799 HDA_AMP_MUTE, mute);
10800 /* mute internal speaker per jack sense */
10801 if (spec->jack_present)
10802 mute = HDA_AMP_MUTE;
10803 if (line_nid)
10804 snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0,
10805 HDA_AMP_MUTE, mute);
10806 if (speaker_nid && speaker_nid != line_nid)
10807 snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0,
10808 HDA_AMP_MUTE, mute);
10809 }
10810
10811 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
10812
10813 static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol,
10814 struct snd_ctl_elem_value *ucontrol)
10815 {
10816 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10817 struct alc_spec *spec = codec->spec;
10818 int val = !!*ucontrol->value.integer.value;
10819
10820 if (val == spec->master_sw)
10821 return 0;
10822 spec->master_sw = val;
10823 alc262_hippo_master_update(codec);
10824 return 1;
10825 }
10826
10827 #define ALC262_HIPPO_MASTER_SWITCH \
10828 { \
10829 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
10830 .name = "Master Playback Switch", \
10831 .info = snd_ctl_boolean_mono_info, \
10832 .get = alc262_hippo_master_sw_get, \
10833 .put = alc262_hippo_master_sw_put, \
10834 }, \
10835 { \
10836 .iface = NID_MAPPING, \
10837 .name = "Master Playback Switch", \
10838 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
10839 (SUBDEV_SPEAKER(0) << 16), \
10840 }
10841
10842 static struct snd_kcontrol_new alc262_hippo_mixer[] = {
10843 ALC262_HIPPO_MASTER_SWITCH,
10844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10845 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10846 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10847 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10848 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10850 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10851 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10852 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10853 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10854 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10855 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
10856 { } /* end */
10857 };
10858
10859 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
10860 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10861 ALC262_HIPPO_MASTER_SWITCH,
10862 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10863 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10866 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10867 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10868 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10869 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10870 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10871 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10872 { } /* end */
10873 };
10874
10875 /* mute/unmute internal speaker according to the hp jack and mute state */
10876 static void alc262_hippo_automute(struct hda_codec *codec)
10877 {
10878 struct alc_spec *spec = codec->spec;
10879 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
10880
10881 spec->jack_present = snd_hda_jack_detect(codec, hp_nid);
10882 alc262_hippo_master_update(codec);
10883 }
10884
10885 static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10886 {
10887 if ((res >> 26) != ALC880_HP_EVENT)
10888 return;
10889 alc262_hippo_automute(codec);
10890 }
10891
10892 static void alc262_hippo_setup(struct hda_codec *codec)
10893 {
10894 struct alc_spec *spec = codec->spec;
10895
10896 spec->autocfg.hp_pins[0] = 0x15;
10897 spec->autocfg.speaker_pins[0] = 0x14;
10898 }
10899
10900 static void alc262_hippo1_setup(struct hda_codec *codec)
10901 {
10902 struct alc_spec *spec = codec->spec;
10903
10904 spec->autocfg.hp_pins[0] = 0x1b;
10905 spec->autocfg.speaker_pins[0] = 0x14;
10906 }
10907
10908
10909 static struct snd_kcontrol_new alc262_sony_mixer[] = {
10910 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10911 ALC262_HIPPO_MASTER_SWITCH,
10912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10914 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10915 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10916 { } /* end */
10917 };
10918
10919 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
10920 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10921 ALC262_HIPPO_MASTER_SWITCH,
10922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10923 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10924 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10925 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10926 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10927 { } /* end */
10928 };
10929
10930 static struct snd_kcontrol_new alc262_tyan_mixer[] = {
10931 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10932 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
10933 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
10934 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10936 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10938 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10939 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
10941 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
10942 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10943 { } /* end */
10944 };
10945
10946 static struct hda_verb alc262_tyan_verbs[] = {
10947 /* Headphone automute */
10948 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10949 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10950 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10951
10952 /* P11 AUX_IN, white 4-pin connector */
10953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10954 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
10955 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
10956 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
10957
10958 {}
10959 };
10960
10961 /* unsolicited event for HP jack sensing */
10962 static void alc262_tyan_setup(struct hda_codec *codec)
10963 {
10964 struct alc_spec *spec = codec->spec;
10965
10966 spec->autocfg.hp_pins[0] = 0x1b;
10967 spec->autocfg.speaker_pins[0] = 0x15;
10968 }
10969
10970
10971 #define alc262_capture_mixer alc882_capture_mixer
10972 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
10973
10974 /*
10975 * generic initialization of ADC, input mixers and output mixers
10976 */
10977 static struct hda_verb alc262_init_verbs[] = {
10978 /*
10979 * Unmute ADC0-2 and set the default input to mic-in
10980 */
10981 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10982 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10983 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10984 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10985 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10986 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10987
10988 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10989 * mixer widget
10990 * Note: PASD motherboards uses the Line In 2 as the input for
10991 * front panel mic (mic 2)
10992 */
10993 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10994 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10995 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10996 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10999
11000 /*
11001 * Set up output mixers (0x0c - 0x0e)
11002 */
11003 /* set vol=0 to output mixers */
11004 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11005 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11007 /* set up input amps for analog loopback */
11008 /* Amp Indices: DAC = 0, mixer = 1 */
11009 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11010 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11011 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11012 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11013 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11014 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11015
11016 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11018 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11019 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11020 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11021 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11022
11023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11024 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11025 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11026 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11028
11029 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11030 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11031
11032 /* FIXME: use matrix-type input source selection */
11033 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11034 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11039 /* Input mixer2 */
11040 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11041 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11042 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11043 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11044 /* Input mixer3 */
11045 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11046 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11047 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11048 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11049
11050 { }
11051 };
11052
11053 static struct hda_verb alc262_eapd_verbs[] = {
11054 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11055 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11056 { }
11057 };
11058
11059 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
11060 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11061 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11062 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11063
11064 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11065 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11066 {}
11067 };
11068
11069 static struct hda_verb alc262_sony_unsol_verbs[] = {
11070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11072 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11073
11074 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11076 {}
11077 };
11078
11079 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11081 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11085 { } /* end */
11086 };
11087
11088 static struct hda_verb alc262_toshiba_s06_verbs[] = {
11089 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11093 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11095 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11096 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11097 {}
11098 };
11099
11100 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11101 {
11102 struct alc_spec *spec = codec->spec;
11103
11104 spec->autocfg.hp_pins[0] = 0x15;
11105 spec->autocfg.speaker_pins[0] = 0x14;
11106 spec->ext_mic.pin = 0x18;
11107 spec->ext_mic.mux_idx = 0;
11108 spec->int_mic.pin = 0x12;
11109 spec->int_mic.mux_idx = 9;
11110 spec->auto_mic = 1;
11111 }
11112
11113 /*
11114 * nec model
11115 * 0x15 = headphone
11116 * 0x16 = internal speaker
11117 * 0x18 = external mic
11118 */
11119
11120 static struct snd_kcontrol_new alc262_nec_mixer[] = {
11121 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11122 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11123
11124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11126 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11127
11128 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11129 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11130 { } /* end */
11131 };
11132
11133 static struct hda_verb alc262_nec_verbs[] = {
11134 /* Unmute Speaker */
11135 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11136
11137 /* Headphone */
11138 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11139 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11140
11141 /* External mic to headphone */
11142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 /* External mic to speaker */
11144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11145 {}
11146 };
11147
11148 /*
11149 * fujitsu model
11150 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11151 * 0x1b = port replicator headphone out
11152 */
11153
11154 #define ALC_HP_EVENT 0x37
11155
11156 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11157 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11158 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11159 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11160 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11161 {}
11162 };
11163
11164 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11165 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11166 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11167 {}
11168 };
11169
11170 static struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11171 /* Front Mic pin: input vref at 50% */
11172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11174 {}
11175 };
11176
11177 static struct hda_input_mux alc262_fujitsu_capture_source = {
11178 .num_items = 3,
11179 .items = {
11180 { "Mic", 0x0 },
11181 { "Int Mic", 0x1 },
11182 { "CD", 0x4 },
11183 },
11184 };
11185
11186 static struct hda_input_mux alc262_HP_capture_source = {
11187 .num_items = 5,
11188 .items = {
11189 { "Mic", 0x0 },
11190 { "Front Mic", 0x1 },
11191 { "Line", 0x2 },
11192 { "CD", 0x4 },
11193 { "AUX IN", 0x6 },
11194 },
11195 };
11196
11197 static struct hda_input_mux alc262_HP_D7000_capture_source = {
11198 .num_items = 4,
11199 .items = {
11200 { "Mic", 0x0 },
11201 { "Front Mic", 0x2 },
11202 { "Line", 0x1 },
11203 { "CD", 0x4 },
11204 },
11205 };
11206
11207 /* mute/unmute internal speaker according to the hp jacks and mute state */
11208 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
11209 {
11210 struct alc_spec *spec = codec->spec;
11211 unsigned int mute;
11212
11213 if (force || !spec->sense_updated) {
11214 spec->jack_present = snd_hda_jack_detect(codec, 0x14) ||
11215 snd_hda_jack_detect(codec, 0x1b);
11216 spec->sense_updated = 1;
11217 }
11218 /* unmute internal speaker only if both HPs are unplugged and
11219 * master switch is on
11220 */
11221 if (spec->jack_present)
11222 mute = HDA_AMP_MUTE;
11223 else
11224 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
11225 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11226 HDA_AMP_MUTE, mute);
11227 }
11228
11229 /* unsolicited event for HP jack sensing */
11230 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
11231 unsigned int res)
11232 {
11233 if ((res >> 26) != ALC_HP_EVENT)
11234 return;
11235 alc262_fujitsu_automute(codec, 1);
11236 }
11237
11238 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
11239 {
11240 alc262_fujitsu_automute(codec, 1);
11241 }
11242
11243 /* bind volumes of both NID 0x0c and 0x0d */
11244 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11245 .ops = &snd_hda_bind_vol,
11246 .values = {
11247 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11248 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11249 0
11250 },
11251 };
11252
11253 /* mute/unmute internal speaker according to the hp jack and mute state */
11254 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
11255 {
11256 struct alc_spec *spec = codec->spec;
11257 unsigned int mute;
11258
11259 if (force || !spec->sense_updated) {
11260 spec->jack_present = snd_hda_jack_detect(codec, 0x1b);
11261 spec->sense_updated = 1;
11262 }
11263 if (spec->jack_present) {
11264 /* mute internal speaker */
11265 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11266 HDA_AMP_MUTE, HDA_AMP_MUTE);
11267 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11268 HDA_AMP_MUTE, HDA_AMP_MUTE);
11269 } else {
11270 /* unmute internal speaker if necessary */
11271 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
11272 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11273 HDA_AMP_MUTE, mute);
11274 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
11275 HDA_AMP_MUTE, mute);
11276 }
11277 }
11278
11279 /* unsolicited event for HP jack sensing */
11280 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
11281 unsigned int res)
11282 {
11283 if ((res >> 26) != ALC_HP_EVENT)
11284 return;
11285 alc262_lenovo_3000_automute(codec, 1);
11286 }
11287
11288 static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid,
11289 int dir, int idx, long *valp)
11290 {
11291 int i, change = 0;
11292
11293 for (i = 0; i < 2; i++, valp++)
11294 change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx,
11295 HDA_AMP_MUTE,
11296 *valp ? 0 : HDA_AMP_MUTE);
11297 return change;
11298 }
11299
11300 /* bind hp and internal speaker mute (with plug check) */
11301 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
11302 struct snd_ctl_elem_value *ucontrol)
11303 {
11304 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11305 long *valp = ucontrol->value.integer.value;
11306 int change;
11307
11308 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
11309 change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11310 if (change)
11311 alc262_fujitsu_automute(codec, 0);
11312 return change;
11313 }
11314
11315 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11316 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11317 {
11318 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11319 .name = "Master Playback Switch",
11320 .subdevice = HDA_SUBDEV_AMP_FLAG,
11321 .info = snd_hda_mixer_amp_switch_info,
11322 .get = snd_hda_mixer_amp_switch_get,
11323 .put = alc262_fujitsu_master_sw_put,
11324 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11325 },
11326 {
11327 .iface = NID_MAPPING,
11328 .name = "Master Playback Switch",
11329 .private_value = 0x1b,
11330 },
11331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11333 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11334 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11335 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11337 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11338 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11339 { } /* end */
11340 };
11341
11342 /* bind hp and internal speaker mute (with plug check) */
11343 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
11344 struct snd_ctl_elem_value *ucontrol)
11345 {
11346 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11347 long *valp = ucontrol->value.integer.value;
11348 int change;
11349
11350 change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp);
11351 if (change)
11352 alc262_lenovo_3000_automute(codec, 0);
11353 return change;
11354 }
11355
11356 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11357 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11358 {
11359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11360 .name = "Master Playback Switch",
11361 .subdevice = HDA_SUBDEV_AMP_FLAG,
11362 .info = snd_hda_mixer_amp_switch_info,
11363 .get = snd_hda_mixer_amp_switch_get,
11364 .put = alc262_lenovo_3000_master_sw_put,
11365 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
11366 },
11367 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11368 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11373 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11374 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11375 { } /* end */
11376 };
11377
11378 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11379 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11380 ALC262_HIPPO_MASTER_SWITCH,
11381 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11382 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11383 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11384 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11385 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11386 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11387 { } /* end */
11388 };
11389
11390 /* additional init verbs for Benq laptops */
11391 static struct hda_verb alc262_EAPD_verbs[] = {
11392 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11393 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11394 {}
11395 };
11396
11397 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11398 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11400
11401 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11402 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11403 {}
11404 };
11405
11406 /* Samsung Q1 Ultra Vista model setup */
11407 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11408 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11409 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11410 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11411 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11412 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
11413 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
11414 { } /* end */
11415 };
11416
11417 static struct hda_verb alc262_ultra_verbs[] = {
11418 /* output mixer */
11419 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11422 /* speaker */
11423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11424 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11425 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11426 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11427 /* HP */
11428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11432 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11433 /* internal mic */
11434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11435 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11436 /* ADC, choose mic */
11437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11438 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11439 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11441 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11442 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11443 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11444 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11447 {}
11448 };
11449
11450 /* mute/unmute internal speaker according to the hp jack and mute state */
11451 static void alc262_ultra_automute(struct hda_codec *codec)
11452 {
11453 struct alc_spec *spec = codec->spec;
11454 unsigned int mute;
11455
11456 mute = 0;
11457 /* auto-mute only when HP is used as HP */
11458 if (!spec->cur_mux[0]) {
11459 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11460 if (spec->jack_present)
11461 mute = HDA_AMP_MUTE;
11462 }
11463 /* mute/unmute internal speaker */
11464 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11465 HDA_AMP_MUTE, mute);
11466 /* mute/unmute HP */
11467 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11468 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11469 }
11470
11471 /* unsolicited event for HP jack sensing */
11472 static void alc262_ultra_unsol_event(struct hda_codec *codec,
11473 unsigned int res)
11474 {
11475 if ((res >> 26) != ALC880_HP_EVENT)
11476 return;
11477 alc262_ultra_automute(codec);
11478 }
11479
11480 static struct hda_input_mux alc262_ultra_capture_source = {
11481 .num_items = 2,
11482 .items = {
11483 { "Mic", 0x1 },
11484 { "Headphone", 0x7 },
11485 },
11486 };
11487
11488 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11489 struct snd_ctl_elem_value *ucontrol)
11490 {
11491 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11492 struct alc_spec *spec = codec->spec;
11493 int ret;
11494
11495 ret = alc_mux_enum_put(kcontrol, ucontrol);
11496 if (!ret)
11497 return 0;
11498 /* reprogram the HP pin as mic or HP according to the input source */
11499 snd_hda_codec_write_cache(codec, 0x15, 0,
11500 AC_VERB_SET_PIN_WIDGET_CONTROL,
11501 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11502 alc262_ultra_automute(codec); /* mute/unmute HP */
11503 return ret;
11504 }
11505
11506 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11507 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11508 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11509 {
11510 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11511 .name = "Capture Source",
11512 .info = alc_mux_enum_info,
11513 .get = alc_mux_enum_get,
11514 .put = alc262_ultra_mux_enum_put,
11515 },
11516 {
11517 .iface = NID_MAPPING,
11518 .name = "Capture Source",
11519 .private_value = 0x15,
11520 },
11521 { } /* end */
11522 };
11523
11524 /* We use two mixers depending on the output pin; 0x16 is a mono output
11525 * and thus it's bound with a different mixer.
11526 * This function returns which mixer amp should be used.
11527 */
11528 static int alc262_check_volbit(hda_nid_t nid)
11529 {
11530 if (!nid)
11531 return 0;
11532 else if (nid == 0x16)
11533 return 2;
11534 else
11535 return 1;
11536 }
11537
11538 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
11539 const char *pfx, int *vbits)
11540 {
11541 unsigned long val;
11542 int vbit;
11543
11544 vbit = alc262_check_volbit(nid);
11545 if (!vbit)
11546 return 0;
11547 if (*vbits & vbit) /* a volume control for this mixer already there */
11548 return 0;
11549 *vbits |= vbit;
11550 if (vbit == 2)
11551 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11552 else
11553 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
11554 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, val);
11555 }
11556
11557 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
11558 const char *pfx)
11559 {
11560 unsigned long val;
11561
11562 if (!nid)
11563 return 0;
11564 if (nid == 0x16)
11565 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11566 else
11567 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
11568 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val);
11569 }
11570
11571 /* add playback controls from the parsed DAC table */
11572 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11573 const struct auto_pin_cfg *cfg)
11574 {
11575 const char *pfx;
11576 int vbits;
11577 int err;
11578
11579 spec->multiout.num_dacs = 1; /* only use one dac */
11580 spec->multiout.dac_nids = spec->private_dac_nids;
11581 spec->multiout.dac_nids[0] = 2;
11582
11583 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
11584 pfx = "Master";
11585 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11586 pfx = "Speaker";
11587 else
11588 pfx = "Front";
11589 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
11590 if (err < 0)
11591 return err;
11592 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
11593 if (err < 0)
11594 return err;
11595 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
11596 if (err < 0)
11597 return err;
11598
11599 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11600 alc262_check_volbit(cfg->speaker_pins[0]) |
11601 alc262_check_volbit(cfg->hp_pins[0]);
11602 if (vbits == 1 || vbits == 2)
11603 pfx = "Master"; /* only one mixer is used */
11604 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
11605 pfx = "Speaker";
11606 else
11607 pfx = "Front";
11608 vbits = 0;
11609 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11610 if (err < 0)
11611 return err;
11612 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11613 &vbits);
11614 if (err < 0)
11615 return err;
11616 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11617 &vbits);
11618 if (err < 0)
11619 return err;
11620 return 0;
11621 }
11622
11623 #define alc262_auto_create_input_ctls \
11624 alc882_auto_create_input_ctls
11625
11626 /*
11627 * generic initialization of ADC, input mixers and output mixers
11628 */
11629 static struct hda_verb alc262_volume_init_verbs[] = {
11630 /*
11631 * Unmute ADC0-2 and set the default input to mic-in
11632 */
11633 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11634 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11635 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11636 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11637 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11638 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11639
11640 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11641 * mixer widget
11642 * Note: PASD motherboards uses the Line In 2 as the input for
11643 * front panel mic (mic 2)
11644 */
11645 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11646 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11647 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11648 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11649 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11650 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11651
11652 /*
11653 * Set up output mixers (0x0c - 0x0f)
11654 */
11655 /* set vol=0 to output mixers */
11656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11658 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11659
11660 /* set up input amps for analog loopback */
11661 /* Amp Indices: DAC = 0, mixer = 1 */
11662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11663 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11666 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11668
11669 /* FIXME: use matrix-type input source selection */
11670 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11671 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11672 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11673 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11674 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11675 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11676 /* Input mixer2 */
11677 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11678 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11679 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11680 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11681 /* Input mixer3 */
11682 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11683 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11684 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11685 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11686
11687 { }
11688 };
11689
11690 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
11691 /*
11692 * Unmute ADC0-2 and set the default input to mic-in
11693 */
11694 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11696 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11697 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11698 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11699 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11700
11701 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11702 * mixer widget
11703 * Note: PASD motherboards uses the Line In 2 as the input for
11704 * front panel mic (mic 2)
11705 */
11706 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11708 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11709 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11710 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11711 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11712 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11713 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11714
11715 /*
11716 * Set up output mixers (0x0c - 0x0e)
11717 */
11718 /* set vol=0 to output mixers */
11719 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11720 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11721 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11722
11723 /* set up input amps for analog loopback */
11724 /* Amp Indices: DAC = 0, mixer = 1 */
11725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11727 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11729 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11731
11732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11733 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11734 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11735
11736 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11737 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11738
11739 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11740 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11741
11742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11745 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11746 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11747
11748 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11749 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11751 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11752 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11753 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11754
11755
11756 /* FIXME: use matrix-type input source selection */
11757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
11758 /* Input mixer1: only unmute Mic */
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11765 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11768 /* Input mixer2 */
11769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11771 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11775 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11776 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11777 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11778 /* Input mixer3 */
11779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
11781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11783 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11784 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
11785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
11786 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
11787 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
11788
11789 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11790
11791 { }
11792 };
11793
11794 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
11795 /*
11796 * Unmute ADC0-2 and set the default input to mic-in
11797 */
11798 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11800 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11801 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11802 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11803 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11804
11805 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11806 * mixer widget
11807 * Note: PASD motherboards uses the Line In 2 as the input for front
11808 * panel mic (mic 2)
11809 */
11810 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11811 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11812 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11813 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11814 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11815 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11816 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11817 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11818 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11819 /*
11820 * Set up output mixers (0x0c - 0x0e)
11821 */
11822 /* set vol=0 to output mixers */
11823 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11824 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11825 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11826
11827 /* set up input amps for analog loopback */
11828 /* Amp Indices: DAC = 0, mixer = 1 */
11829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11830 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11831 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11832 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11833 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11834 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11835
11836
11837 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
11838 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
11839 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
11840 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
11841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11842 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
11843 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
11844
11845 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11847
11848 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11849 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11850
11851 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
11852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11854 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
11855 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11856 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
11857
11858 /* FIXME: use matrix-type input source selection */
11859 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11860 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11861 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
11862 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
11863 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
11864 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
11865 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
11866 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11867 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
11868 /* Input mixer2 */
11869 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11870 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11871 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11872 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11873 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11874 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11875 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11876 /* Input mixer3 */
11877 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11878 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
11880 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
11881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
11882 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
11883 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
11884
11885 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11886
11887 { }
11888 };
11889
11890 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
11891
11892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
11893 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11894 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
11895
11896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
11897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
11898 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
11900
11901 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
11902 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11903 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11904 {}
11905 };
11906
11907
11908 #ifdef CONFIG_SND_HDA_POWER_SAVE
11909 #define alc262_loopbacks alc880_loopbacks
11910 #endif
11911
11912 /* pcm configuration: identical with ALC880 */
11913 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
11914 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
11915 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
11916 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
11917
11918 /*
11919 * BIOS auto configuration
11920 */
11921 static int alc262_parse_auto_config(struct hda_codec *codec)
11922 {
11923 struct alc_spec *spec = codec->spec;
11924 int err;
11925 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
11926
11927 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11928 alc262_ignore);
11929 if (err < 0)
11930 return err;
11931 if (!spec->autocfg.line_outs) {
11932 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
11933 spec->multiout.max_channels = 2;
11934 spec->no_analog = 1;
11935 goto dig_only;
11936 }
11937 return 0; /* can't find valid BIOS pin config */
11938 }
11939 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11940 if (err < 0)
11941 return err;
11942 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11943 if (err < 0)
11944 return err;
11945
11946 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11947
11948 dig_only:
11949 if (spec->autocfg.dig_outs) {
11950 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
11951 spec->dig_out_type = spec->autocfg.dig_out_type[0];
11952 }
11953 if (spec->autocfg.dig_in_pin)
11954 spec->dig_in_nid = ALC262_DIGIN_NID;
11955
11956 if (spec->kctls.list)
11957 add_mixer(spec, spec->kctls.list);
11958
11959 add_verb(spec, alc262_volume_init_verbs);
11960 spec->num_mux_defs = 1;
11961 spec->input_mux = &spec->private_imux[0];
11962
11963 err = alc_auto_add_mic_boost(codec);
11964 if (err < 0)
11965 return err;
11966
11967 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11968
11969 return 1;
11970 }
11971
11972 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
11973 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
11974 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
11975 #define alc262_auto_init_input_src alc882_auto_init_input_src
11976
11977
11978 /* init callback for auto-configuration model -- overriding the default init */
11979 static void alc262_auto_init(struct hda_codec *codec)
11980 {
11981 struct alc_spec *spec = codec->spec;
11982 alc262_auto_init_multi_out(codec);
11983 alc262_auto_init_hp_out(codec);
11984 alc262_auto_init_analog_input(codec);
11985 alc262_auto_init_input_src(codec);
11986 if (spec->unsol_event)
11987 alc_inithook(codec);
11988 }
11989
11990 /*
11991 * configuration and preset
11992 */
11993 static const char *alc262_models[ALC262_MODEL_LAST] = {
11994 [ALC262_BASIC] = "basic",
11995 [ALC262_HIPPO] = "hippo",
11996 [ALC262_HIPPO_1] = "hippo_1",
11997 [ALC262_FUJITSU] = "fujitsu",
11998 [ALC262_HP_BPC] = "hp-bpc",
11999 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12000 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12001 [ALC262_HP_RP5700] = "hp-rp5700",
12002 [ALC262_BENQ_ED8] = "benq",
12003 [ALC262_BENQ_T31] = "benq-t31",
12004 [ALC262_SONY_ASSAMD] = "sony-assamd",
12005 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12006 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12007 [ALC262_ULTRA] = "ultra",
12008 [ALC262_LENOVO_3000] = "lenovo-3000",
12009 [ALC262_NEC] = "nec",
12010 [ALC262_TYAN] = "tyan",
12011 [ALC262_AUTO] = "auto",
12012 };
12013
12014 static struct snd_pci_quirk alc262_cfg_tbl[] = {
12015 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12016 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12017 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12018 ALC262_HP_BPC),
12019 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12020 ALC262_HP_BPC),
12021 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12022 ALC262_HP_BPC),
12023 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12024 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12025 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12026 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12027 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12028 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12029 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12030 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12031 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12032 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12033 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12034 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12035 ALC262_HP_TC_T5735),
12036 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12037 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12038 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12039 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12040 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12041 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12042 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12043 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12044 #if 0 /* disable the quirk since model=auto works better in recent versions */
12045 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12046 ALC262_SONY_ASSAMD),
12047 #endif
12048 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12049 ALC262_TOSHIBA_RX1),
12050 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12051 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12052 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12053 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12054 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12055 ALC262_ULTRA),
12056 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12057 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12058 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12059 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12060 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12061 {}
12062 };
12063
12064 static struct alc_config_preset alc262_presets[] = {
12065 [ALC262_BASIC] = {
12066 .mixers = { alc262_base_mixer },
12067 .init_verbs = { alc262_init_verbs },
12068 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12069 .dac_nids = alc262_dac_nids,
12070 .hp_nid = 0x03,
12071 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12072 .channel_mode = alc262_modes,
12073 .input_mux = &alc262_capture_source,
12074 },
12075 [ALC262_HIPPO] = {
12076 .mixers = { alc262_hippo_mixer },
12077 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12078 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12079 .dac_nids = alc262_dac_nids,
12080 .hp_nid = 0x03,
12081 .dig_out_nid = ALC262_DIGOUT_NID,
12082 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12083 .channel_mode = alc262_modes,
12084 .input_mux = &alc262_capture_source,
12085 .unsol_event = alc262_hippo_unsol_event,
12086 .setup = alc262_hippo_setup,
12087 .init_hook = alc262_hippo_automute,
12088 },
12089 [ALC262_HIPPO_1] = {
12090 .mixers = { alc262_hippo1_mixer },
12091 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12092 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12093 .dac_nids = alc262_dac_nids,
12094 .hp_nid = 0x02,
12095 .dig_out_nid = ALC262_DIGOUT_NID,
12096 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12097 .channel_mode = alc262_modes,
12098 .input_mux = &alc262_capture_source,
12099 .unsol_event = alc262_hippo_unsol_event,
12100 .setup = alc262_hippo1_setup,
12101 .init_hook = alc262_hippo_automute,
12102 },
12103 [ALC262_FUJITSU] = {
12104 .mixers = { alc262_fujitsu_mixer },
12105 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12106 alc262_fujitsu_unsol_verbs },
12107 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12108 .dac_nids = alc262_dac_nids,
12109 .hp_nid = 0x03,
12110 .dig_out_nid = ALC262_DIGOUT_NID,
12111 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12112 .channel_mode = alc262_modes,
12113 .input_mux = &alc262_fujitsu_capture_source,
12114 .unsol_event = alc262_fujitsu_unsol_event,
12115 .init_hook = alc262_fujitsu_init_hook,
12116 },
12117 [ALC262_HP_BPC] = {
12118 .mixers = { alc262_HP_BPC_mixer },
12119 .init_verbs = { alc262_HP_BPC_init_verbs },
12120 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12121 .dac_nids = alc262_dac_nids,
12122 .hp_nid = 0x03,
12123 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12124 .channel_mode = alc262_modes,
12125 .input_mux = &alc262_HP_capture_source,
12126 .unsol_event = alc262_hp_bpc_unsol_event,
12127 .init_hook = alc262_hp_bpc_automute,
12128 },
12129 [ALC262_HP_BPC_D7000_WF] = {
12130 .mixers = { alc262_HP_BPC_WildWest_mixer },
12131 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12132 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12133 .dac_nids = alc262_dac_nids,
12134 .hp_nid = 0x03,
12135 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12136 .channel_mode = alc262_modes,
12137 .input_mux = &alc262_HP_D7000_capture_source,
12138 .unsol_event = alc262_hp_wildwest_unsol_event,
12139 .init_hook = alc262_hp_wildwest_automute,
12140 },
12141 [ALC262_HP_BPC_D7000_WL] = {
12142 .mixers = { alc262_HP_BPC_WildWest_mixer,
12143 alc262_HP_BPC_WildWest_option_mixer },
12144 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12145 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12146 .dac_nids = alc262_dac_nids,
12147 .hp_nid = 0x03,
12148 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12149 .channel_mode = alc262_modes,
12150 .input_mux = &alc262_HP_D7000_capture_source,
12151 .unsol_event = alc262_hp_wildwest_unsol_event,
12152 .init_hook = alc262_hp_wildwest_automute,
12153 },
12154 [ALC262_HP_TC_T5735] = {
12155 .mixers = { alc262_hp_t5735_mixer },
12156 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12157 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12158 .dac_nids = alc262_dac_nids,
12159 .hp_nid = 0x03,
12160 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12161 .channel_mode = alc262_modes,
12162 .input_mux = &alc262_capture_source,
12163 .unsol_event = alc_sku_unsol_event,
12164 .setup = alc262_hp_t5735_setup,
12165 .init_hook = alc_inithook,
12166 },
12167 [ALC262_HP_RP5700] = {
12168 .mixers = { alc262_hp_rp5700_mixer },
12169 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12170 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12171 .dac_nids = alc262_dac_nids,
12172 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12173 .channel_mode = alc262_modes,
12174 .input_mux = &alc262_hp_rp5700_capture_source,
12175 },
12176 [ALC262_BENQ_ED8] = {
12177 .mixers = { alc262_base_mixer },
12178 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12179 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12180 .dac_nids = alc262_dac_nids,
12181 .hp_nid = 0x03,
12182 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12183 .channel_mode = alc262_modes,
12184 .input_mux = &alc262_capture_source,
12185 },
12186 [ALC262_SONY_ASSAMD] = {
12187 .mixers = { alc262_sony_mixer },
12188 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12189 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12190 .dac_nids = alc262_dac_nids,
12191 .hp_nid = 0x02,
12192 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12193 .channel_mode = alc262_modes,
12194 .input_mux = &alc262_capture_source,
12195 .unsol_event = alc262_hippo_unsol_event,
12196 .setup = alc262_hippo_setup,
12197 .init_hook = alc262_hippo_automute,
12198 },
12199 [ALC262_BENQ_T31] = {
12200 .mixers = { alc262_benq_t31_mixer },
12201 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12202 alc_hp15_unsol_verbs },
12203 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12204 .dac_nids = alc262_dac_nids,
12205 .hp_nid = 0x03,
12206 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12207 .channel_mode = alc262_modes,
12208 .input_mux = &alc262_capture_source,
12209 .unsol_event = alc262_hippo_unsol_event,
12210 .setup = alc262_hippo_setup,
12211 .init_hook = alc262_hippo_automute,
12212 },
12213 [ALC262_ULTRA] = {
12214 .mixers = { alc262_ultra_mixer },
12215 .cap_mixer = alc262_ultra_capture_mixer,
12216 .init_verbs = { alc262_ultra_verbs },
12217 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12218 .dac_nids = alc262_dac_nids,
12219 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12220 .channel_mode = alc262_modes,
12221 .input_mux = &alc262_ultra_capture_source,
12222 .adc_nids = alc262_adc_nids, /* ADC0 */
12223 .capsrc_nids = alc262_capsrc_nids,
12224 .num_adc_nids = 1, /* single ADC */
12225 .unsol_event = alc262_ultra_unsol_event,
12226 .init_hook = alc262_ultra_automute,
12227 },
12228 [ALC262_LENOVO_3000] = {
12229 .mixers = { alc262_lenovo_3000_mixer },
12230 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12231 alc262_lenovo_3000_unsol_verbs,
12232 alc262_lenovo_3000_init_verbs },
12233 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12234 .dac_nids = alc262_dac_nids,
12235 .hp_nid = 0x03,
12236 .dig_out_nid = ALC262_DIGOUT_NID,
12237 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12238 .channel_mode = alc262_modes,
12239 .input_mux = &alc262_fujitsu_capture_source,
12240 .unsol_event = alc262_lenovo_3000_unsol_event,
12241 },
12242 [ALC262_NEC] = {
12243 .mixers = { alc262_nec_mixer },
12244 .init_verbs = { alc262_nec_verbs },
12245 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12246 .dac_nids = alc262_dac_nids,
12247 .hp_nid = 0x03,
12248 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12249 .channel_mode = alc262_modes,
12250 .input_mux = &alc262_capture_source,
12251 },
12252 [ALC262_TOSHIBA_S06] = {
12253 .mixers = { alc262_toshiba_s06_mixer },
12254 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12255 alc262_eapd_verbs },
12256 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12257 .capsrc_nids = alc262_dmic_capsrc_nids,
12258 .dac_nids = alc262_dac_nids,
12259 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12260 .num_adc_nids = 1, /* single ADC */
12261 .dig_out_nid = ALC262_DIGOUT_NID,
12262 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12263 .channel_mode = alc262_modes,
12264 .unsol_event = alc_sku_unsol_event,
12265 .setup = alc262_toshiba_s06_setup,
12266 .init_hook = alc_inithook,
12267 },
12268 [ALC262_TOSHIBA_RX1] = {
12269 .mixers = { alc262_toshiba_rx1_mixer },
12270 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12271 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12272 .dac_nids = alc262_dac_nids,
12273 .hp_nid = 0x03,
12274 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12275 .channel_mode = alc262_modes,
12276 .input_mux = &alc262_capture_source,
12277 .unsol_event = alc262_hippo_unsol_event,
12278 .setup = alc262_hippo_setup,
12279 .init_hook = alc262_hippo_automute,
12280 },
12281 [ALC262_TYAN] = {
12282 .mixers = { alc262_tyan_mixer },
12283 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12284 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12285 .dac_nids = alc262_dac_nids,
12286 .hp_nid = 0x02,
12287 .dig_out_nid = ALC262_DIGOUT_NID,
12288 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12289 .channel_mode = alc262_modes,
12290 .input_mux = &alc262_capture_source,
12291 .unsol_event = alc_automute_amp_unsol_event,
12292 .setup = alc262_tyan_setup,
12293 .init_hook = alc_automute_amp,
12294 },
12295 };
12296
12297 static int patch_alc262(struct hda_codec *codec)
12298 {
12299 struct alc_spec *spec;
12300 int board_config;
12301 int err;
12302
12303 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12304 if (spec == NULL)
12305 return -ENOMEM;
12306
12307 codec->spec = spec;
12308 #if 0
12309 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12310 * under-run
12311 */
12312 {
12313 int tmp;
12314 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12315 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12316 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12317 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12318 }
12319 #endif
12320 alc_auto_parse_customize_define(codec);
12321
12322 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12323
12324 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12325 alc262_models,
12326 alc262_cfg_tbl);
12327
12328 if (board_config < 0) {
12329 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12330 codec->chip_name);
12331 board_config = ALC262_AUTO;
12332 }
12333
12334 if (board_config == ALC262_AUTO) {
12335 /* automatic parse from the BIOS config */
12336 err = alc262_parse_auto_config(codec);
12337 if (err < 0) {
12338 alc_free(codec);
12339 return err;
12340 } else if (!err) {
12341 printk(KERN_INFO
12342 "hda_codec: Cannot set up configuration "
12343 "from BIOS. Using base mode...\n");
12344 board_config = ALC262_BASIC;
12345 }
12346 }
12347
12348 if (!spec->no_analog) {
12349 err = snd_hda_attach_beep_device(codec, 0x1);
12350 if (err < 0) {
12351 alc_free(codec);
12352 return err;
12353 }
12354 }
12355
12356 if (board_config != ALC262_AUTO)
12357 setup_preset(codec, &alc262_presets[board_config]);
12358
12359 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12360 spec->stream_analog_capture = &alc262_pcm_analog_capture;
12361
12362 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12363 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12364
12365 if (!spec->adc_nids && spec->input_mux) {
12366 int i;
12367 /* check whether the digital-mic has to be supported */
12368 for (i = 0; i < spec->input_mux->num_items; i++) {
12369 if (spec->input_mux->items[i].index >= 9)
12370 break;
12371 }
12372 if (i < spec->input_mux->num_items) {
12373 /* use only ADC0 */
12374 spec->adc_nids = alc262_dmic_adc_nids;
12375 spec->num_adc_nids = 1;
12376 spec->capsrc_nids = alc262_dmic_capsrc_nids;
12377 } else {
12378 /* all analog inputs */
12379 /* check whether NID 0x07 is valid */
12380 unsigned int wcap = get_wcaps(codec, 0x07);
12381
12382 /* get type */
12383 wcap = get_wcaps_type(wcap);
12384 if (wcap != AC_WID_AUD_IN) {
12385 spec->adc_nids = alc262_adc_nids_alt;
12386 spec->num_adc_nids =
12387 ARRAY_SIZE(alc262_adc_nids_alt);
12388 spec->capsrc_nids = alc262_capsrc_nids_alt;
12389 } else {
12390 spec->adc_nids = alc262_adc_nids;
12391 spec->num_adc_nids =
12392 ARRAY_SIZE(alc262_adc_nids);
12393 spec->capsrc_nids = alc262_capsrc_nids;
12394 }
12395 }
12396 }
12397 if (!spec->cap_mixer && !spec->no_analog)
12398 set_capture_mixer(codec);
12399 if (!spec->no_analog && spec->cdefine.enable_pcbeep)
12400 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12401
12402 spec->vmaster_nid = 0x0c;
12403
12404 codec->patch_ops = alc_patch_ops;
12405 if (board_config == ALC262_AUTO)
12406 spec->init_hook = alc262_auto_init;
12407 #ifdef CONFIG_SND_HDA_POWER_SAVE
12408 if (!spec->loopback.amplist)
12409 spec->loopback.amplist = alc262_loopbacks;
12410 #endif
12411
12412 return 0;
12413 }
12414
12415 /*
12416 * ALC268 channel source setting (2 channel)
12417 */
12418 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12419 #define alc268_modes alc260_modes
12420
12421 static hda_nid_t alc268_dac_nids[2] = {
12422 /* front, hp */
12423 0x02, 0x03
12424 };
12425
12426 static hda_nid_t alc268_adc_nids[2] = {
12427 /* ADC0-1 */
12428 0x08, 0x07
12429 };
12430
12431 static hda_nid_t alc268_adc_nids_alt[1] = {
12432 /* ADC0 */
12433 0x08
12434 };
12435
12436 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12437
12438 static struct snd_kcontrol_new alc268_base_mixer[] = {
12439 /* output mixer control */
12440 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12441 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12442 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12444 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12445 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12446 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12447 { }
12448 };
12449
12450 static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12451 /* output mixer control */
12452 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12453 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12454 ALC262_HIPPO_MASTER_SWITCH,
12455 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12456 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
12457 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12458 { }
12459 };
12460
12461 /* bind Beep switches of both NID 0x0f and 0x10 */
12462 static struct hda_bind_ctls alc268_bind_beep_sw = {
12463 .ops = &snd_hda_bind_sw,
12464 .values = {
12465 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12466 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12467 0
12468 },
12469 };
12470
12471 static struct snd_kcontrol_new alc268_beep_mixer[] = {
12472 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12473 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12474 { }
12475 };
12476
12477 static struct hda_verb alc268_eapd_verbs[] = {
12478 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12479 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12480 { }
12481 };
12482
12483 /* Toshiba specific */
12484 static struct hda_verb alc268_toshiba_verbs[] = {
12485 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12486 { } /* end */
12487 };
12488
12489 /* Acer specific */
12490 /* bind volumes of both NID 0x02 and 0x03 */
12491 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
12492 .ops = &snd_hda_bind_vol,
12493 .values = {
12494 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12495 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12496 0
12497 },
12498 };
12499
12500 /* mute/unmute internal speaker according to the hp jack and mute state */
12501 static void alc268_acer_automute(struct hda_codec *codec, int force)
12502 {
12503 struct alc_spec *spec = codec->spec;
12504 unsigned int mute;
12505
12506 if (force || !spec->sense_updated) {
12507 spec->jack_present = snd_hda_jack_detect(codec, 0x14);
12508 spec->sense_updated = 1;
12509 }
12510 if (spec->jack_present)
12511 mute = HDA_AMP_MUTE; /* mute internal speaker */
12512 else /* unmute internal speaker if necessary */
12513 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12514 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12515 HDA_AMP_MUTE, mute);
12516 }
12517
12518
12519 /* bind hp and internal speaker mute (with plug check) */
12520 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
12521 struct snd_ctl_elem_value *ucontrol)
12522 {
12523 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12524 long *valp = ucontrol->value.integer.value;
12525 int change;
12526
12527 change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp);
12528 if (change)
12529 alc268_acer_automute(codec, 0);
12530 return change;
12531 }
12532
12533 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12534 /* output mixer control */
12535 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12536 {
12537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12538 .name = "Master Playback Switch",
12539 .subdevice = HDA_SUBDEV_AMP_FLAG,
12540 .info = snd_hda_mixer_amp_switch_info,
12541 .get = snd_hda_mixer_amp_switch_get,
12542 .put = alc268_acer_master_sw_put,
12543 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12544 },
12545 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12546 { }
12547 };
12548
12549 static struct snd_kcontrol_new alc268_acer_mixer[] = {
12550 /* output mixer control */
12551 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12552 {
12553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12554 .name = "Master Playback Switch",
12555 .subdevice = HDA_SUBDEV_AMP_FLAG,
12556 .info = snd_hda_mixer_amp_switch_info,
12557 .get = snd_hda_mixer_amp_switch_get,
12558 .put = alc268_acer_master_sw_put,
12559 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12560 },
12561 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12562 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12563 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12564 { }
12565 };
12566
12567 static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12568 /* output mixer control */
12569 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12570 {
12571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12572 .name = "Master Playback Switch",
12573 .subdevice = HDA_SUBDEV_AMP_FLAG,
12574 .info = snd_hda_mixer_amp_switch_info,
12575 .get = snd_hda_mixer_amp_switch_get,
12576 .put = alc268_acer_master_sw_put,
12577 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12578 },
12579 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12580 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
12581 { }
12582 };
12583
12584 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
12585 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12587 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12589 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12591 { }
12592 };
12593
12594 static struct hda_verb alc268_acer_verbs[] = {
12595 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12596 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12597 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12598 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12599 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12601 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12602 { }
12603 };
12604
12605 /* unsolicited event for HP jack sensing */
12606 #define alc268_toshiba_unsol_event alc262_hippo_unsol_event
12607 #define alc268_toshiba_setup alc262_hippo_setup
12608 #define alc268_toshiba_automute alc262_hippo_automute
12609
12610 static void alc268_acer_unsol_event(struct hda_codec *codec,
12611 unsigned int res)
12612 {
12613 if ((res >> 26) != ALC880_HP_EVENT)
12614 return;
12615 alc268_acer_automute(codec, 1);
12616 }
12617
12618 static void alc268_acer_init_hook(struct hda_codec *codec)
12619 {
12620 alc268_acer_automute(codec, 1);
12621 }
12622
12623 /* toggle speaker-output according to the hp-jack state */
12624 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
12625 {
12626 unsigned int present;
12627 unsigned char bits;
12628
12629 present = snd_hda_jack_detect(codec, 0x15);
12630 bits = present ? HDA_AMP_MUTE : 0;
12631 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
12632 HDA_AMP_MUTE, bits);
12633 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
12634 HDA_AMP_MUTE, bits);
12635 }
12636
12637 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
12638 unsigned int res)
12639 {
12640 switch (res >> 26) {
12641 case ALC880_HP_EVENT:
12642 alc268_aspire_one_speaker_automute(codec);
12643 break;
12644 case ALC880_MIC_EVENT:
12645 alc_mic_automute(codec);
12646 break;
12647 }
12648 }
12649
12650 static void alc268_acer_lc_setup(struct hda_codec *codec)
12651 {
12652 struct alc_spec *spec = codec->spec;
12653 spec->ext_mic.pin = 0x18;
12654 spec->ext_mic.mux_idx = 0;
12655 spec->int_mic.pin = 0x12;
12656 spec->int_mic.mux_idx = 6;
12657 spec->auto_mic = 1;
12658 }
12659
12660 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
12661 {
12662 alc268_aspire_one_speaker_automute(codec);
12663 alc_mic_automute(codec);
12664 }
12665
12666 static struct snd_kcontrol_new alc268_dell_mixer[] = {
12667 /* output mixer control */
12668 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12669 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12670 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12672 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12673 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12674 { }
12675 };
12676
12677 static struct hda_verb alc268_dell_verbs[] = {
12678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12679 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12680 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12681 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12682 { }
12683 };
12684
12685 /* mute/unmute internal speaker according to the hp jack and mute state */
12686 static void alc268_dell_setup(struct hda_codec *codec)
12687 {
12688 struct alc_spec *spec = codec->spec;
12689
12690 spec->autocfg.hp_pins[0] = 0x15;
12691 spec->autocfg.speaker_pins[0] = 0x14;
12692 spec->ext_mic.pin = 0x18;
12693 spec->ext_mic.mux_idx = 0;
12694 spec->int_mic.pin = 0x19;
12695 spec->int_mic.mux_idx = 1;
12696 spec->auto_mic = 1;
12697 }
12698
12699 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12700 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12701 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12702 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12703 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12704 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12705 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12706 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
12707 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
12708 { }
12709 };
12710
12711 static struct hda_verb alc267_quanta_il1_verbs[] = {
12712 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12713 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12714 { }
12715 };
12716
12717 static void alc267_quanta_il1_setup(struct hda_codec *codec)
12718 {
12719 struct alc_spec *spec = codec->spec;
12720 spec->autocfg.hp_pins[0] = 0x15;
12721 spec->autocfg.speaker_pins[0] = 0x14;
12722 spec->ext_mic.pin = 0x18;
12723 spec->ext_mic.mux_idx = 0;
12724 spec->int_mic.pin = 0x19;
12725 spec->int_mic.mux_idx = 1;
12726 spec->auto_mic = 1;
12727 }
12728
12729 /*
12730 * generic initialization of ADC, input mixers and output mixers
12731 */
12732 static struct hda_verb alc268_base_init_verbs[] = {
12733 /* Unmute DAC0-1 and set vol = 0 */
12734 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12735 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12736
12737 /*
12738 * Set up output mixers (0x0c - 0x0e)
12739 */
12740 /* set vol=0 to output mixers */
12741 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12742 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12743
12744 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12745 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12746
12747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12750 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12751 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12753 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12754 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12755
12756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12757 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12758 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12759 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12761
12762 /* set PCBEEP vol = 0, mute connections */
12763 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12765 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12766
12767 /* Unmute Selector 23h,24h and set the default input to mic-in */
12768
12769 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12770 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12771 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12773
12774 { }
12775 };
12776
12777 /*
12778 * generic initialization of ADC, input mixers and output mixers
12779 */
12780 static struct hda_verb alc268_volume_init_verbs[] = {
12781 /* set output DAC */
12782 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12783 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12784
12785 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12786 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12787 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12789 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12790
12791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12793 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12794
12795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12797
12798 /* set PCBEEP vol = 0, mute connections */
12799 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12801 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12802
12803 { }
12804 };
12805
12806 static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12807 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12808 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12809 { } /* end */
12810 };
12811
12812 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12813 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12814 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12815 _DEFINE_CAPSRC(1),
12816 { } /* end */
12817 };
12818
12819 static struct snd_kcontrol_new alc268_capture_mixer[] = {
12820 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12821 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12822 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12823 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12824 _DEFINE_CAPSRC(2),
12825 { } /* end */
12826 };
12827
12828 static struct hda_input_mux alc268_capture_source = {
12829 .num_items = 4,
12830 .items = {
12831 { "Mic", 0x0 },
12832 { "Front Mic", 0x1 },
12833 { "Line", 0x2 },
12834 { "CD", 0x3 },
12835 },
12836 };
12837
12838 static struct hda_input_mux alc268_acer_capture_source = {
12839 .num_items = 3,
12840 .items = {
12841 { "Mic", 0x0 },
12842 { "Internal Mic", 0x1 },
12843 { "Line", 0x2 },
12844 },
12845 };
12846
12847 static struct hda_input_mux alc268_acer_dmic_capture_source = {
12848 .num_items = 3,
12849 .items = {
12850 { "Mic", 0x0 },
12851 { "Internal Mic", 0x6 },
12852 { "Line", 0x2 },
12853 },
12854 };
12855
12856 #ifdef CONFIG_SND_DEBUG
12857 static struct snd_kcontrol_new alc268_test_mixer[] = {
12858 /* Volume widgets */
12859 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12860 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12861 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
12862 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
12863 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
12864 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
12865 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
12866 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
12867 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
12868 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
12869 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
12870 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
12871 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
12872 /* The below appears problematic on some hardwares */
12873 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
12874 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12875 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
12876 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
12877 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
12878
12879 /* Modes for retasking pin widgets */
12880 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
12881 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
12882 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
12883 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
12884
12885 /* Controls for GPIO pins, assuming they are configured as outputs */
12886 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
12887 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
12888 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
12889 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
12890
12891 /* Switches to allow the digital SPDIF output pin to be enabled.
12892 * The ALC268 does not have an SPDIF input.
12893 */
12894 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
12895
12896 /* A switch allowing EAPD to be enabled. Some laptops seem to use
12897 * this output to turn on an external amplifier.
12898 */
12899 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
12900 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
12901
12902 { } /* end */
12903 };
12904 #endif
12905
12906 /* create input playback/capture controls for the given pin */
12907 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12908 const char *ctlname, int idx)
12909 {
12910 hda_nid_t dac;
12911 int err;
12912
12913 switch (nid) {
12914 case 0x14:
12915 case 0x16:
12916 dac = 0x02;
12917 break;
12918 case 0x15:
12919 dac = 0x03;
12920 break;
12921 default:
12922 return 0;
12923 }
12924 if (spec->multiout.dac_nids[0] != dac &&
12925 spec->multiout.dac_nids[1] != dac) {
12926 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
12927 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12928 HDA_OUTPUT));
12929 if (err < 0)
12930 return err;
12931 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12932 }
12933
12934 if (nid != 0x16)
12935 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12936 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12937 else /* mono */
12938 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
12939 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12940 if (err < 0)
12941 return err;
12942 return 0;
12943 }
12944
12945 /* add playback controls from the parsed DAC table */
12946 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12947 const struct auto_pin_cfg *cfg)
12948 {
12949 hda_nid_t nid;
12950 int err;
12951
12952 spec->multiout.dac_nids = spec->private_dac_nids;
12953
12954 nid = cfg->line_out_pins[0];
12955 if (nid) {
12956 const char *name;
12957 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12958 name = "Speaker";
12959 else
12960 name = "Front";
12961 err = alc268_new_analog_output(spec, nid, name, 0);
12962 if (err < 0)
12963 return err;
12964 }
12965
12966 nid = cfg->speaker_pins[0];
12967 if (nid == 0x1d) {
12968 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
12969 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12970 if (err < 0)
12971 return err;
12972 } else {
12973 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12974 if (err < 0)
12975 return err;
12976 }
12977 nid = cfg->hp_pins[0];
12978 if (nid) {
12979 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12980 if (err < 0)
12981 return err;
12982 }
12983
12984 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12985 if (nid == 0x16) {
12986 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
12987 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12988 if (err < 0)
12989 return err;
12990 }
12991 return 0;
12992 }
12993
12994 /* create playback/capture controls for input pins */
12995 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12996 const struct auto_pin_cfg *cfg)
12997 {
12998 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12999 }
13000
13001 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13002 hda_nid_t nid, int pin_type)
13003 {
13004 int idx;
13005
13006 alc_set_pin_output(codec, nid, pin_type);
13007 if (nid == 0x14 || nid == 0x16)
13008 idx = 0;
13009 else
13010 idx = 1;
13011 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13012 }
13013
13014 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13015 {
13016 struct alc_spec *spec = codec->spec;
13017 hda_nid_t nid = spec->autocfg.line_out_pins[0];
13018 if (nid) {
13019 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13020 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13021 }
13022 }
13023
13024 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13025 {
13026 struct alc_spec *spec = codec->spec;
13027 hda_nid_t pin;
13028
13029 pin = spec->autocfg.hp_pins[0];
13030 if (pin)
13031 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13032 pin = spec->autocfg.speaker_pins[0];
13033 if (pin)
13034 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13035 }
13036
13037 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13038 {
13039 struct alc_spec *spec = codec->spec;
13040 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13041 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13042 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13043 unsigned int dac_vol1, dac_vol2;
13044
13045 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13046 snd_hda_codec_write(codec, speaker_nid, 0,
13047 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13048 /* mute mixer inputs from 0x1d */
13049 snd_hda_codec_write(codec, 0x0f, 0,
13050 AC_VERB_SET_AMP_GAIN_MUTE,
13051 AMP_IN_UNMUTE(1));
13052 snd_hda_codec_write(codec, 0x10, 0,
13053 AC_VERB_SET_AMP_GAIN_MUTE,
13054 AMP_IN_UNMUTE(1));
13055 } else {
13056 /* unmute mixer inputs from 0x1d */
13057 snd_hda_codec_write(codec, 0x0f, 0,
13058 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13059 snd_hda_codec_write(codec, 0x10, 0,
13060 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13061 }
13062
13063 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13064 if (line_nid == 0x14)
13065 dac_vol2 = AMP_OUT_ZERO;
13066 else if (line_nid == 0x15)
13067 dac_vol1 = AMP_OUT_ZERO;
13068 if (hp_nid == 0x14)
13069 dac_vol2 = AMP_OUT_ZERO;
13070 else if (hp_nid == 0x15)
13071 dac_vol1 = AMP_OUT_ZERO;
13072 if (line_nid != 0x16 || hp_nid != 0x16 ||
13073 spec->autocfg.line_out_pins[1] != 0x16 ||
13074 spec->autocfg.line_out_pins[2] != 0x16)
13075 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13076
13077 snd_hda_codec_write(codec, 0x02, 0,
13078 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13079 snd_hda_codec_write(codec, 0x03, 0,
13080 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13081 }
13082
13083 /* pcm configuration: identical with ALC880 */
13084 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13085 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13086 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13087 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13088
13089 /*
13090 * BIOS auto configuration
13091 */
13092 static int alc268_parse_auto_config(struct hda_codec *codec)
13093 {
13094 struct alc_spec *spec = codec->spec;
13095 int err;
13096 static hda_nid_t alc268_ignore[] = { 0 };
13097
13098 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13099 alc268_ignore);
13100 if (err < 0)
13101 return err;
13102 if (!spec->autocfg.line_outs) {
13103 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13104 spec->multiout.max_channels = 2;
13105 spec->no_analog = 1;
13106 goto dig_only;
13107 }
13108 return 0; /* can't find valid BIOS pin config */
13109 }
13110 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13111 if (err < 0)
13112 return err;
13113 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13114 if (err < 0)
13115 return err;
13116
13117 spec->multiout.max_channels = 2;
13118
13119 dig_only:
13120 /* digital only support output */
13121 if (spec->autocfg.dig_outs) {
13122 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
13123 spec->dig_out_type = spec->autocfg.dig_out_type[0];
13124 }
13125 if (spec->kctls.list)
13126 add_mixer(spec, spec->kctls.list);
13127
13128 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13129 add_mixer(spec, alc268_beep_mixer);
13130
13131 add_verb(spec, alc268_volume_init_verbs);
13132 spec->num_mux_defs = 2;
13133 spec->input_mux = &spec->private_imux[0];
13134
13135 err = alc_auto_add_mic_boost(codec);
13136 if (err < 0)
13137 return err;
13138
13139 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13140
13141 return 1;
13142 }
13143
13144 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13145
13146 /* init callback for auto-configuration model -- overriding the default init */
13147 static void alc268_auto_init(struct hda_codec *codec)
13148 {
13149 struct alc_spec *spec = codec->spec;
13150 alc268_auto_init_multi_out(codec);
13151 alc268_auto_init_hp_out(codec);
13152 alc268_auto_init_mono_speaker_out(codec);
13153 alc268_auto_init_analog_input(codec);
13154 if (spec->unsol_event)
13155 alc_inithook(codec);
13156 }
13157
13158 /*
13159 * configuration and preset
13160 */
13161 static const char *alc268_models[ALC268_MODEL_LAST] = {
13162 [ALC267_QUANTA_IL1] = "quanta-il1",
13163 [ALC268_3ST] = "3stack",
13164 [ALC268_TOSHIBA] = "toshiba",
13165 [ALC268_ACER] = "acer",
13166 [ALC268_ACER_DMIC] = "acer-dmic",
13167 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13168 [ALC268_DELL] = "dell",
13169 [ALC268_ZEPTO] = "zepto",
13170 #ifdef CONFIG_SND_DEBUG
13171 [ALC268_TEST] = "test",
13172 #endif
13173 [ALC268_AUTO] = "auto",
13174 };
13175
13176 static struct snd_pci_quirk alc268_cfg_tbl[] = {
13177 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13178 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13179 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13180 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13181 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13182 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13183 ALC268_ACER_ASPIRE_ONE),
13184 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13185 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13186 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13187 /* almost compatible with toshiba but with optional digital outs;
13188 * auto-probing seems working fine
13189 */
13190 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13191 ALC268_AUTO),
13192 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13193 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13194 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13195 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
13196 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13197 SND_PCI_QUIRK(0x1854, 0x1775, "LG R510", ALC268_DELL),
13198 {}
13199 };
13200
13201 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13202 static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13203 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13204 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13205 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13206 ALC268_TOSHIBA),
13207 {}
13208 };
13209
13210 static struct alc_config_preset alc268_presets[] = {
13211 [ALC267_QUANTA_IL1] = {
13212 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13213 alc268_capture_nosrc_mixer },
13214 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13215 alc267_quanta_il1_verbs },
13216 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13217 .dac_nids = alc268_dac_nids,
13218 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13219 .adc_nids = alc268_adc_nids_alt,
13220 .hp_nid = 0x03,
13221 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13222 .channel_mode = alc268_modes,
13223 .unsol_event = alc_sku_unsol_event,
13224 .setup = alc267_quanta_il1_setup,
13225 .init_hook = alc_inithook,
13226 },
13227 [ALC268_3ST] = {
13228 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13229 alc268_beep_mixer },
13230 .init_verbs = { alc268_base_init_verbs },
13231 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13232 .dac_nids = alc268_dac_nids,
13233 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13234 .adc_nids = alc268_adc_nids_alt,
13235 .capsrc_nids = alc268_capsrc_nids,
13236 .hp_nid = 0x03,
13237 .dig_out_nid = ALC268_DIGOUT_NID,
13238 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13239 .channel_mode = alc268_modes,
13240 .input_mux = &alc268_capture_source,
13241 },
13242 [ALC268_TOSHIBA] = {
13243 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13244 alc268_beep_mixer },
13245 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13246 alc268_toshiba_verbs },
13247 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13248 .dac_nids = alc268_dac_nids,
13249 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13250 .adc_nids = alc268_adc_nids_alt,
13251 .capsrc_nids = alc268_capsrc_nids,
13252 .hp_nid = 0x03,
13253 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13254 .channel_mode = alc268_modes,
13255 .input_mux = &alc268_capture_source,
13256 .unsol_event = alc268_toshiba_unsol_event,
13257 .setup = alc268_toshiba_setup,
13258 .init_hook = alc268_toshiba_automute,
13259 },
13260 [ALC268_ACER] = {
13261 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13262 alc268_beep_mixer },
13263 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13264 alc268_acer_verbs },
13265 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13266 .dac_nids = alc268_dac_nids,
13267 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13268 .adc_nids = alc268_adc_nids_alt,
13269 .capsrc_nids = alc268_capsrc_nids,
13270 .hp_nid = 0x02,
13271 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13272 .channel_mode = alc268_modes,
13273 .input_mux = &alc268_acer_capture_source,
13274 .unsol_event = alc268_acer_unsol_event,
13275 .init_hook = alc268_acer_init_hook,
13276 },
13277 [ALC268_ACER_DMIC] = {
13278 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13279 alc268_beep_mixer },
13280 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13281 alc268_acer_verbs },
13282 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13283 .dac_nids = alc268_dac_nids,
13284 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13285 .adc_nids = alc268_adc_nids_alt,
13286 .capsrc_nids = alc268_capsrc_nids,
13287 .hp_nid = 0x02,
13288 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13289 .channel_mode = alc268_modes,
13290 .input_mux = &alc268_acer_dmic_capture_source,
13291 .unsol_event = alc268_acer_unsol_event,
13292 .init_hook = alc268_acer_init_hook,
13293 },
13294 [ALC268_ACER_ASPIRE_ONE] = {
13295 .mixers = { alc268_acer_aspire_one_mixer,
13296 alc268_beep_mixer,
13297 alc268_capture_nosrc_mixer },
13298 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13299 alc268_acer_aspire_one_verbs },
13300 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13301 .dac_nids = alc268_dac_nids,
13302 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13303 .adc_nids = alc268_adc_nids_alt,
13304 .capsrc_nids = alc268_capsrc_nids,
13305 .hp_nid = 0x03,
13306 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13307 .channel_mode = alc268_modes,
13308 .unsol_event = alc268_acer_lc_unsol_event,
13309 .setup = alc268_acer_lc_setup,
13310 .init_hook = alc268_acer_lc_init_hook,
13311 },
13312 [ALC268_DELL] = {
13313 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13314 alc268_capture_nosrc_mixer },
13315 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13316 alc268_dell_verbs },
13317 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13318 .dac_nids = alc268_dac_nids,
13319 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13320 .adc_nids = alc268_adc_nids_alt,
13321 .capsrc_nids = alc268_capsrc_nids,
13322 .hp_nid = 0x02,
13323 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13324 .channel_mode = alc268_modes,
13325 .unsol_event = alc_sku_unsol_event,
13326 .setup = alc268_dell_setup,
13327 .init_hook = alc_inithook,
13328 },
13329 [ALC268_ZEPTO] = {
13330 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13331 alc268_beep_mixer },
13332 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13333 alc268_toshiba_verbs },
13334 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13335 .dac_nids = alc268_dac_nids,
13336 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13337 .adc_nids = alc268_adc_nids_alt,
13338 .capsrc_nids = alc268_capsrc_nids,
13339 .hp_nid = 0x03,
13340 .dig_out_nid = ALC268_DIGOUT_NID,
13341 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13342 .channel_mode = alc268_modes,
13343 .input_mux = &alc268_capture_source,
13344 .setup = alc268_toshiba_setup,
13345 .init_hook = alc268_toshiba_automute,
13346 },
13347 #ifdef CONFIG_SND_DEBUG
13348 [ALC268_TEST] = {
13349 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13350 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13351 alc268_volume_init_verbs },
13352 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13353 .dac_nids = alc268_dac_nids,
13354 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13355 .adc_nids = alc268_adc_nids_alt,
13356 .capsrc_nids = alc268_capsrc_nids,
13357 .hp_nid = 0x03,
13358 .dig_out_nid = ALC268_DIGOUT_NID,
13359 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13360 .channel_mode = alc268_modes,
13361 .input_mux = &alc268_capture_source,
13362 },
13363 #endif
13364 };
13365
13366 static int patch_alc268(struct hda_codec *codec)
13367 {
13368 struct alc_spec *spec;
13369 int board_config;
13370 int i, has_beep, err;
13371
13372 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13373 if (spec == NULL)
13374 return -ENOMEM;
13375
13376 codec->spec = spec;
13377
13378 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13379 alc268_models,
13380 alc268_cfg_tbl);
13381
13382 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13383 board_config = snd_hda_check_board_codec_sid_config(codec,
13384 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13385
13386 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
13387 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13388 codec->chip_name);
13389 board_config = ALC268_AUTO;
13390 }
13391
13392 if (board_config == ALC268_AUTO) {
13393 /* automatic parse from the BIOS config */
13394 err = alc268_parse_auto_config(codec);
13395 if (err < 0) {
13396 alc_free(codec);
13397 return err;
13398 } else if (!err) {
13399 printk(KERN_INFO
13400 "hda_codec: Cannot set up configuration "
13401 "from BIOS. Using base mode...\n");
13402 board_config = ALC268_3ST;
13403 }
13404 }
13405
13406 if (board_config != ALC268_AUTO)
13407 setup_preset(codec, &alc268_presets[board_config]);
13408
13409 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13410 spec->stream_analog_capture = &alc268_pcm_analog_capture;
13411 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
13412
13413 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13414
13415 has_beep = 0;
13416 for (i = 0; i < spec->num_mixers; i++) {
13417 if (spec->mixers[i] == alc268_beep_mixer) {
13418 has_beep = 1;
13419 break;
13420 }
13421 }
13422
13423 if (has_beep) {
13424 err = snd_hda_attach_beep_device(codec, 0x1);
13425 if (err < 0) {
13426 alc_free(codec);
13427 return err;
13428 }
13429 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13430 /* override the amp caps for beep generator */
13431 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
13432 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13433 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13434 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13435 (0 << AC_AMPCAP_MUTE_SHIFT));
13436 }
13437
13438 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
13439 /* check whether NID 0x07 is valid */
13440 unsigned int wcap = get_wcaps(codec, 0x07);
13441 int i;
13442
13443 spec->capsrc_nids = alc268_capsrc_nids;
13444 /* get type */
13445 wcap = get_wcaps_type(wcap);
13446 if (spec->auto_mic ||
13447 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
13448 spec->adc_nids = alc268_adc_nids_alt;
13449 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
13450 if (spec->auto_mic)
13451 fixup_automic_adc(codec);
13452 if (spec->auto_mic || spec->input_mux->num_items == 1)
13453 add_mixer(spec, alc268_capture_nosrc_mixer);
13454 else
13455 add_mixer(spec, alc268_capture_alt_mixer);
13456 } else {
13457 spec->adc_nids = alc268_adc_nids;
13458 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
13459 add_mixer(spec, alc268_capture_mixer);
13460 }
13461 /* set default input source */
13462 for (i = 0; i < spec->num_adc_nids; i++)
13463 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
13464 0, AC_VERB_SET_CONNECT_SEL,
13465 i < spec->num_mux_defs ?
13466 spec->input_mux[i].items[0].index :
13467 spec->input_mux->items[0].index);
13468 }
13469
13470 spec->vmaster_nid = 0x02;
13471
13472 codec->patch_ops = alc_patch_ops;
13473 if (board_config == ALC268_AUTO)
13474 spec->init_hook = alc268_auto_init;
13475
13476 return 0;
13477 }
13478
13479 /*
13480 * ALC269 channel source setting (2 channel)
13481 */
13482 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13483
13484 #define alc269_dac_nids alc260_dac_nids
13485
13486 static hda_nid_t alc269_adc_nids[1] = {
13487 /* ADC1 */
13488 0x08,
13489 };
13490
13491 static hda_nid_t alc269_capsrc_nids[1] = {
13492 0x23,
13493 };
13494
13495 static hda_nid_t alc269vb_adc_nids[1] = {
13496 /* ADC1 */
13497 0x09,
13498 };
13499
13500 static hda_nid_t alc269vb_capsrc_nids[1] = {
13501 0x22,
13502 };
13503
13504 static hda_nid_t alc269_adc_candidates[] = {
13505 0x08, 0x09, 0x07,
13506 };
13507
13508 #define alc269_modes alc260_modes
13509 #define alc269_capture_source alc880_lg_lw_capture_source
13510
13511 static struct snd_kcontrol_new alc269_base_mixer[] = {
13512 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13513 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13514 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13515 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13516 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13518 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13519 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13520 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13521 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13522 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13523 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13524 { } /* end */
13525 };
13526
13527 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13528 /* output mixer control */
13529 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13530 {
13531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13532 .name = "Master Playback Switch",
13533 .subdevice = HDA_SUBDEV_AMP_FLAG,
13534 .info = snd_hda_mixer_amp_switch_info,
13535 .get = snd_hda_mixer_amp_switch_get,
13536 .put = alc268_acer_master_sw_put,
13537 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13538 },
13539 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13540 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13541 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13542 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13543 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13544 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13545 { }
13546 };
13547
13548 static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13549 /* output mixer control */
13550 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13551 {
13552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13553 .name = "Master Playback Switch",
13554 .subdevice = HDA_SUBDEV_AMP_FLAG,
13555 .info = snd_hda_mixer_amp_switch_info,
13556 .get = snd_hda_mixer_amp_switch_get,
13557 .put = alc268_acer_master_sw_put,
13558 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13559 },
13560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13562 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13563 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13564 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13565 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
13566 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13567 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13568 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
13569 { }
13570 };
13571
13572 static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13573 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13574 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13576 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13577 { } /* end */
13578 };
13579
13580 static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13581 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13582 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13583 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13584 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13585 { } /* end */
13586 };
13587
13588 /* capture mixer elements */
13589 static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13590 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13591 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13592 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13593 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13594 { } /* end */
13595 };
13596
13597 static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13598 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13599 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13600 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13601 { } /* end */
13602 };
13603
13604 static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13605 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13606 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13607 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13608 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13609 { } /* end */
13610 };
13611
13612 static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13613 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13614 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13615 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13616 { } /* end */
13617 };
13618
13619 /* FSC amilo */
13620 #define alc269_fujitsu_mixer alc269_laptop_mixer
13621
13622 static struct hda_verb alc269_quanta_fl1_verbs[] = {
13623 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13624 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13626 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13627 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13628 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13629 { }
13630 };
13631
13632 static struct hda_verb alc269_lifebook_verbs[] = {
13633 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13634 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13635 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13637 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13640 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13641 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13642 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13643 { }
13644 };
13645
13646 /* toggle speaker-output according to the hp-jack state */
13647 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13648 {
13649 unsigned int present;
13650 unsigned char bits;
13651
13652 present = snd_hda_jack_detect(codec, 0x15);
13653 bits = present ? HDA_AMP_MUTE : 0;
13654 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13655 HDA_AMP_MUTE, bits);
13656 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13657 HDA_AMP_MUTE, bits);
13658
13659 snd_hda_codec_write(codec, 0x20, 0,
13660 AC_VERB_SET_COEF_INDEX, 0x0c);
13661 snd_hda_codec_write(codec, 0x20, 0,
13662 AC_VERB_SET_PROC_COEF, 0x680);
13663
13664 snd_hda_codec_write(codec, 0x20, 0,
13665 AC_VERB_SET_COEF_INDEX, 0x0c);
13666 snd_hda_codec_write(codec, 0x20, 0,
13667 AC_VERB_SET_PROC_COEF, 0x480);
13668 }
13669
13670 /* toggle speaker-output according to the hp-jacks state */
13671 static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
13672 {
13673 unsigned int present;
13674 unsigned char bits;
13675
13676 /* Check laptop headphone socket */
13677 present = snd_hda_jack_detect(codec, 0x15);
13678
13679 /* Check port replicator headphone socket */
13680 present |= snd_hda_jack_detect(codec, 0x1a);
13681
13682 bits = present ? HDA_AMP_MUTE : 0;
13683 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13684 HDA_AMP_MUTE, bits);
13685 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13686 HDA_AMP_MUTE, bits);
13687
13688 snd_hda_codec_write(codec, 0x20, 0,
13689 AC_VERB_SET_COEF_INDEX, 0x0c);
13690 snd_hda_codec_write(codec, 0x20, 0,
13691 AC_VERB_SET_PROC_COEF, 0x680);
13692
13693 snd_hda_codec_write(codec, 0x20, 0,
13694 AC_VERB_SET_COEF_INDEX, 0x0c);
13695 snd_hda_codec_write(codec, 0x20, 0,
13696 AC_VERB_SET_PROC_COEF, 0x480);
13697 }
13698
13699 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13700 {
13701 unsigned int present_laptop;
13702 unsigned int present_dock;
13703
13704 present_laptop = snd_hda_jack_detect(codec, 0x18);
13705 present_dock = snd_hda_jack_detect(codec, 0x1b);
13706
13707 /* Laptop mic port overrides dock mic port, design decision */
13708 if (present_dock)
13709 snd_hda_codec_write(codec, 0x23, 0,
13710 AC_VERB_SET_CONNECT_SEL, 0x3);
13711 if (present_laptop)
13712 snd_hda_codec_write(codec, 0x23, 0,
13713 AC_VERB_SET_CONNECT_SEL, 0x0);
13714 if (!present_dock && !present_laptop)
13715 snd_hda_codec_write(codec, 0x23, 0,
13716 AC_VERB_SET_CONNECT_SEL, 0x1);
13717 }
13718
13719 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13720 unsigned int res)
13721 {
13722 switch (res >> 26) {
13723 case ALC880_HP_EVENT:
13724 alc269_quanta_fl1_speaker_automute(codec);
13725 break;
13726 case ALC880_MIC_EVENT:
13727 alc_mic_automute(codec);
13728 break;
13729 }
13730 }
13731
13732 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13733 unsigned int res)
13734 {
13735 if ((res >> 26) == ALC880_HP_EVENT)
13736 alc269_lifebook_speaker_automute(codec);
13737 if ((res >> 26) == ALC880_MIC_EVENT)
13738 alc269_lifebook_mic_autoswitch(codec);
13739 }
13740
13741 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13742 {
13743 struct alc_spec *spec = codec->spec;
13744 spec->autocfg.hp_pins[0] = 0x15;
13745 spec->autocfg.speaker_pins[0] = 0x14;
13746 spec->ext_mic.pin = 0x18;
13747 spec->ext_mic.mux_idx = 0;
13748 spec->int_mic.pin = 0x19;
13749 spec->int_mic.mux_idx = 1;
13750 spec->auto_mic = 1;
13751 }
13752
13753 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13754 {
13755 alc269_quanta_fl1_speaker_automute(codec);
13756 alc_mic_automute(codec);
13757 }
13758
13759 static void alc269_lifebook_init_hook(struct hda_codec *codec)
13760 {
13761 alc269_lifebook_speaker_automute(codec);
13762 alc269_lifebook_mic_autoswitch(codec);
13763 }
13764
13765 static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13766 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13767 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13768 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13770 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13771 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13773 {}
13774 };
13775
13776 static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13777 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13778 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13779 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13780 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13781 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13782 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13783 {}
13784 };
13785
13786 static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13787 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13788 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13789 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13791 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13792 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13793 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13794 {}
13795 };
13796
13797 static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13798 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13799 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13800 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13801 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13802 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13803 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13804 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13805 {}
13806 };
13807
13808 /* toggle speaker-output according to the hp-jack state */
13809 static void alc269_speaker_automute(struct hda_codec *codec)
13810 {
13811 struct alc_spec *spec = codec->spec;
13812 unsigned int nid = spec->autocfg.hp_pins[0];
13813 unsigned int present;
13814 unsigned char bits;
13815
13816 present = snd_hda_jack_detect(codec, nid);
13817 bits = present ? HDA_AMP_MUTE : 0;
13818 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
13819 HDA_AMP_MUTE, bits);
13820 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
13821 HDA_AMP_MUTE, bits);
13822 }
13823
13824 /* unsolicited event for HP jack sensing */
13825 static void alc269_laptop_unsol_event(struct hda_codec *codec,
13826 unsigned int res)
13827 {
13828 switch (res >> 26) {
13829 case ALC880_HP_EVENT:
13830 alc269_speaker_automute(codec);
13831 break;
13832 case ALC880_MIC_EVENT:
13833 alc_mic_automute(codec);
13834 break;
13835 }
13836 }
13837
13838 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13839 {
13840 struct alc_spec *spec = codec->spec;
13841 spec->autocfg.hp_pins[0] = 0x15;
13842 spec->autocfg.speaker_pins[0] = 0x14;
13843 spec->ext_mic.pin = 0x18;
13844 spec->ext_mic.mux_idx = 0;
13845 spec->int_mic.pin = 0x12;
13846 spec->int_mic.mux_idx = 5;
13847 spec->auto_mic = 1;
13848 }
13849
13850 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13851 {
13852 struct alc_spec *spec = codec->spec;
13853 spec->autocfg.hp_pins[0] = 0x15;
13854 spec->autocfg.speaker_pins[0] = 0x14;
13855 spec->ext_mic.pin = 0x18;
13856 spec->ext_mic.mux_idx = 0;
13857 spec->int_mic.pin = 0x12;
13858 spec->int_mic.mux_idx = 6;
13859 spec->auto_mic = 1;
13860 }
13861
13862 static void alc269_laptop_amic_setup(struct hda_codec *codec)
13863 {
13864 struct alc_spec *spec = codec->spec;
13865 spec->autocfg.hp_pins[0] = 0x15;
13866 spec->autocfg.speaker_pins[0] = 0x14;
13867 spec->ext_mic.pin = 0x18;
13868 spec->ext_mic.mux_idx = 0;
13869 spec->int_mic.pin = 0x19;
13870 spec->int_mic.mux_idx = 1;
13871 spec->auto_mic = 1;
13872 }
13873
13874 static void alc269_laptop_inithook(struct hda_codec *codec)
13875 {
13876 alc269_speaker_automute(codec);
13877 alc_mic_automute(codec);
13878 }
13879
13880 /*
13881 * generic initialization of ADC, input mixers and output mixers
13882 */
13883 static struct hda_verb alc269_init_verbs[] = {
13884 /*
13885 * Unmute ADC0 and set the default input to mic-in
13886 */
13887 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13888
13889 /*
13890 * Set up output mixers (0x02 - 0x03)
13891 */
13892 /* set vol=0 to output mixers */
13893 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13894 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13895
13896 /* set up input amps for analog loopback */
13897 /* Amp Indices: DAC = 0, mixer = 1 */
13898 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13899 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13900 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13901 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13902 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13903 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13904
13905 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13906 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13907 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13908 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13909 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13911 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13912
13913 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13914 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13915
13916 /* FIXME: use Mux-type input source selection */
13917 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13918 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13919 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13920
13921 /* set EAPD */
13922 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13923 { }
13924 };
13925
13926 static struct hda_verb alc269vb_init_verbs[] = {
13927 /*
13928 * Unmute ADC0 and set the default input to mic-in
13929 */
13930 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13931
13932 /*
13933 * Set up output mixers (0x02 - 0x03)
13934 */
13935 /* set vol=0 to output mixers */
13936 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13937 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13938
13939 /* set up input amps for analog loopback */
13940 /* Amp Indices: DAC = 0, mixer = 1 */
13941 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13942 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13943 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13944 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13945 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13946 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13947
13948 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13949 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13950 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13952 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13953 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13955
13956 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13957 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13958
13959 /* FIXME: use Mux-type input source selection */
13960 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13961 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13962 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13963
13964 /* set EAPD */
13965 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13966 { }
13967 };
13968
13969 #define alc269_auto_create_multi_out_ctls \
13970 alc268_auto_create_multi_out_ctls
13971 #define alc269_auto_create_input_ctls \
13972 alc268_auto_create_input_ctls
13973
13974 #ifdef CONFIG_SND_HDA_POWER_SAVE
13975 #define alc269_loopbacks alc880_loopbacks
13976 #endif
13977
13978 /* pcm configuration: identical with ALC880 */
13979 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
13980 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
13981 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
13982 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
13983
13984 static struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
13985 .substreams = 1,
13986 .channels_min = 2,
13987 .channels_max = 8,
13988 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
13989 /* NID is set in alc_build_pcms */
13990 .ops = {
13991 .open = alc880_playback_pcm_open,
13992 .prepare = alc880_playback_pcm_prepare,
13993 .cleanup = alc880_playback_pcm_cleanup
13994 },
13995 };
13996
13997 static struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
13998 .substreams = 1,
13999 .channels_min = 2,
14000 .channels_max = 2,
14001 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14002 /* NID is set in alc_build_pcms */
14003 };
14004
14005 #ifdef CONFIG_SND_HDA_POWER_SAVE
14006 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14007 {
14008 switch (codec->subsystem_id) {
14009 case 0x103c1586:
14010 return 1;
14011 }
14012 return 0;
14013 }
14014
14015 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14016 {
14017 /* update mute-LED according to the speaker mute state */
14018 if (nid == 0x01 || nid == 0x14) {
14019 int pinval;
14020 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14021 HDA_AMP_MUTE)
14022 pinval = 0x24;
14023 else
14024 pinval = 0x20;
14025 /* mic2 vref pin is used for mute LED control */
14026 snd_hda_codec_update_cache(codec, 0x19, 0,
14027 AC_VERB_SET_PIN_WIDGET_CONTROL,
14028 pinval);
14029 }
14030 return alc_check_power_status(codec, nid);
14031 }
14032 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14033
14034 /*
14035 * BIOS auto configuration
14036 */
14037 static int alc269_parse_auto_config(struct hda_codec *codec)
14038 {
14039 struct alc_spec *spec = codec->spec;
14040 int err;
14041 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14042
14043 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14044 alc269_ignore);
14045 if (err < 0)
14046 return err;
14047
14048 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14049 if (err < 0)
14050 return err;
14051 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14052 if (err < 0)
14053 return err;
14054
14055 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14056
14057 if (spec->autocfg.dig_outs)
14058 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
14059
14060 if (spec->kctls.list)
14061 add_mixer(spec, spec->kctls.list);
14062
14063 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
14064 add_verb(spec, alc269vb_init_verbs);
14065 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14066 } else {
14067 add_verb(spec, alc269_init_verbs);
14068 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14069 }
14070
14071 spec->num_mux_defs = 1;
14072 spec->input_mux = &spec->private_imux[0];
14073 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14074 sizeof(alc269_adc_candidates));
14075
14076 /* set default input source */
14077 snd_hda_codec_write_cache(codec, spec->capsrc_nids[0],
14078 0, AC_VERB_SET_CONNECT_SEL,
14079 spec->input_mux->items[0].index);
14080
14081 err = alc_auto_add_mic_boost(codec);
14082 if (err < 0)
14083 return err;
14084
14085 if (!spec->cap_mixer && !spec->no_analog)
14086 set_capture_mixer(codec);
14087
14088 return 1;
14089 }
14090
14091 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14092 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14093 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14094
14095
14096 /* init callback for auto-configuration model -- overriding the default init */
14097 static void alc269_auto_init(struct hda_codec *codec)
14098 {
14099 struct alc_spec *spec = codec->spec;
14100 alc269_auto_init_multi_out(codec);
14101 alc269_auto_init_hp_out(codec);
14102 alc269_auto_init_analog_input(codec);
14103 if (spec->unsol_event)
14104 alc_inithook(codec);
14105 }
14106
14107 /*
14108 * configuration and preset
14109 */
14110 static const char *alc269_models[ALC269_MODEL_LAST] = {
14111 [ALC269_BASIC] = "basic",
14112 [ALC269_QUANTA_FL1] = "quanta",
14113 [ALC269_AMIC] = "laptop-amic",
14114 [ALC269_DMIC] = "laptop-dmic",
14115 [ALC269_FUJITSU] = "fujitsu",
14116 [ALC269_LIFEBOOK] = "lifebook",
14117 [ALC269_AUTO] = "auto",
14118 };
14119
14120 static struct snd_pci_quirk alc269_cfg_tbl[] = {
14121 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14122 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14123 ALC269_AMIC),
14124 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14125 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14126 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14127 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14128 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14129 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14130 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14131 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14132 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14133 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
14134 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14135 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14136 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14137 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14138 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14139 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14140 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14141 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14142 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14143 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14144 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14145 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14146 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14147 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14148 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14149 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14150 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14151 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14152 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14153 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14154 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14155 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14156 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14157 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14158 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14159 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14160 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14161 ALC269_DMIC),
14162 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14163 ALC269_DMIC),
14164 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14165 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14166 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
14167 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14168 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14169 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14170 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14171 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14172 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14173 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14174 {}
14175 };
14176
14177 static struct alc_config_preset alc269_presets[] = {
14178 [ALC269_BASIC] = {
14179 .mixers = { alc269_base_mixer },
14180 .init_verbs = { alc269_init_verbs },
14181 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14182 .dac_nids = alc269_dac_nids,
14183 .hp_nid = 0x03,
14184 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14185 .channel_mode = alc269_modes,
14186 .input_mux = &alc269_capture_source,
14187 },
14188 [ALC269_QUANTA_FL1] = {
14189 .mixers = { alc269_quanta_fl1_mixer },
14190 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14191 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14192 .dac_nids = alc269_dac_nids,
14193 .hp_nid = 0x03,
14194 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14195 .channel_mode = alc269_modes,
14196 .input_mux = &alc269_capture_source,
14197 .unsol_event = alc269_quanta_fl1_unsol_event,
14198 .setup = alc269_quanta_fl1_setup,
14199 .init_hook = alc269_quanta_fl1_init_hook,
14200 },
14201 [ALC269_AMIC] = {
14202 .mixers = { alc269_laptop_mixer },
14203 .cap_mixer = alc269_laptop_analog_capture_mixer,
14204 .init_verbs = { alc269_init_verbs,
14205 alc269_laptop_amic_init_verbs },
14206 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14207 .dac_nids = alc269_dac_nids,
14208 .hp_nid = 0x03,
14209 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14210 .channel_mode = alc269_modes,
14211 .unsol_event = alc269_laptop_unsol_event,
14212 .setup = alc269_laptop_amic_setup,
14213 .init_hook = alc269_laptop_inithook,
14214 },
14215 [ALC269_DMIC] = {
14216 .mixers = { alc269_laptop_mixer },
14217 .cap_mixer = alc269_laptop_digital_capture_mixer,
14218 .init_verbs = { alc269_init_verbs,
14219 alc269_laptop_dmic_init_verbs },
14220 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14221 .dac_nids = alc269_dac_nids,
14222 .hp_nid = 0x03,
14223 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14224 .channel_mode = alc269_modes,
14225 .unsol_event = alc269_laptop_unsol_event,
14226 .setup = alc269_laptop_dmic_setup,
14227 .init_hook = alc269_laptop_inithook,
14228 },
14229 [ALC269VB_AMIC] = {
14230 .mixers = { alc269vb_laptop_mixer },
14231 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14232 .init_verbs = { alc269vb_init_verbs,
14233 alc269vb_laptop_amic_init_verbs },
14234 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14235 .dac_nids = alc269_dac_nids,
14236 .hp_nid = 0x03,
14237 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14238 .channel_mode = alc269_modes,
14239 .unsol_event = alc269_laptop_unsol_event,
14240 .setup = alc269_laptop_amic_setup,
14241 .init_hook = alc269_laptop_inithook,
14242 },
14243 [ALC269VB_DMIC] = {
14244 .mixers = { alc269vb_laptop_mixer },
14245 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14246 .init_verbs = { alc269vb_init_verbs,
14247 alc269vb_laptop_dmic_init_verbs },
14248 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14249 .dac_nids = alc269_dac_nids,
14250 .hp_nid = 0x03,
14251 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14252 .channel_mode = alc269_modes,
14253 .unsol_event = alc269_laptop_unsol_event,
14254 .setup = alc269vb_laptop_dmic_setup,
14255 .init_hook = alc269_laptop_inithook,
14256 },
14257 [ALC269_FUJITSU] = {
14258 .mixers = { alc269_fujitsu_mixer },
14259 .cap_mixer = alc269_laptop_digital_capture_mixer,
14260 .init_verbs = { alc269_init_verbs,
14261 alc269_laptop_dmic_init_verbs },
14262 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14263 .dac_nids = alc269_dac_nids,
14264 .hp_nid = 0x03,
14265 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14266 .channel_mode = alc269_modes,
14267 .unsol_event = alc269_laptop_unsol_event,
14268 .setup = alc269_laptop_dmic_setup,
14269 .init_hook = alc269_laptop_inithook,
14270 },
14271 [ALC269_LIFEBOOK] = {
14272 .mixers = { alc269_lifebook_mixer },
14273 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14274 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14275 .dac_nids = alc269_dac_nids,
14276 .hp_nid = 0x03,
14277 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14278 .channel_mode = alc269_modes,
14279 .input_mux = &alc269_capture_source,
14280 .unsol_event = alc269_lifebook_unsol_event,
14281 .init_hook = alc269_lifebook_init_hook,
14282 },
14283 };
14284
14285 static int patch_alc269(struct hda_codec *codec)
14286 {
14287 struct alc_spec *spec;
14288 int board_config;
14289 int err;
14290 int is_alc269vb = 0;
14291
14292 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14293 if (spec == NULL)
14294 return -ENOMEM;
14295
14296 codec->spec = spec;
14297
14298 alc_auto_parse_customize_define(codec);
14299
14300 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010){
14301 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14302 spec->cdefine.platform_type == 1)
14303 alc_codec_rename(codec, "ALC271X");
14304 else
14305 alc_codec_rename(codec, "ALC259");
14306 is_alc269vb = 1;
14307 } else
14308 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14309
14310 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14311 alc269_models,
14312 alc269_cfg_tbl);
14313
14314 if (board_config < 0) {
14315 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14316 codec->chip_name);
14317 board_config = ALC269_AUTO;
14318 }
14319
14320 if (board_config == ALC269_AUTO) {
14321 /* automatic parse from the BIOS config */
14322 err = alc269_parse_auto_config(codec);
14323 if (err < 0) {
14324 alc_free(codec);
14325 return err;
14326 } else if (!err) {
14327 printk(KERN_INFO
14328 "hda_codec: Cannot set up configuration "
14329 "from BIOS. Using base mode...\n");
14330 board_config = ALC269_BASIC;
14331 }
14332 }
14333
14334 err = snd_hda_attach_beep_device(codec, 0x1);
14335 if (err < 0) {
14336 alc_free(codec);
14337 return err;
14338 }
14339
14340 if (board_config != ALC269_AUTO)
14341 setup_preset(codec, &alc269_presets[board_config]);
14342
14343 if (board_config == ALC269_QUANTA_FL1) {
14344 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14345 * fix the sample rate of analog I/O to 44.1kHz
14346 */
14347 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14348 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14349 } else {
14350 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14351 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14352 }
14353 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14354 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14355
14356 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14357 if (!is_alc269vb) {
14358 spec->adc_nids = alc269_adc_nids;
14359 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14360 spec->capsrc_nids = alc269_capsrc_nids;
14361 } else {
14362 spec->adc_nids = alc269vb_adc_nids;
14363 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14364 spec->capsrc_nids = alc269vb_capsrc_nids;
14365 }
14366 }
14367
14368 if (!spec->cap_mixer)
14369 set_capture_mixer(codec);
14370 if (spec->cdefine.enable_pcbeep)
14371 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
14372
14373 spec->vmaster_nid = 0x02;
14374
14375 codec->patch_ops = alc_patch_ops;
14376 if (board_config == ALC269_AUTO)
14377 spec->init_hook = alc269_auto_init;
14378 #ifdef CONFIG_SND_HDA_POWER_SAVE
14379 if (!spec->loopback.amplist)
14380 spec->loopback.amplist = alc269_loopbacks;
14381 if (alc269_mic2_for_mute_led(codec))
14382 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
14383 #endif
14384
14385 return 0;
14386 }
14387
14388 /*
14389 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14390 */
14391
14392 /*
14393 * set the path ways for 2 channel output
14394 * need to set the codec line out and mic 1 pin widgets to inputs
14395 */
14396 static struct hda_verb alc861_threestack_ch2_init[] = {
14397 /* set pin widget 1Ah (line in) for input */
14398 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14399 /* set pin widget 18h (mic1/2) for input, for mic also enable
14400 * the vref
14401 */
14402 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14403
14404 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14405 #if 0
14406 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14407 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14408 #endif
14409 { } /* end */
14410 };
14411 /*
14412 * 6ch mode
14413 * need to set the codec line out and mic 1 pin widgets to outputs
14414 */
14415 static struct hda_verb alc861_threestack_ch6_init[] = {
14416 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14418 /* set pin widget 18h (mic1) for output (CLFE)*/
14419 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14420
14421 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14422 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14423
14424 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14425 #if 0
14426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14428 #endif
14429 { } /* end */
14430 };
14431
14432 static struct hda_channel_mode alc861_threestack_modes[2] = {
14433 { 2, alc861_threestack_ch2_init },
14434 { 6, alc861_threestack_ch6_init },
14435 };
14436 /* Set mic1 as input and unmute the mixer */
14437 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14438 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14439 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14440 { } /* end */
14441 };
14442 /* Set mic1 as output and mute mixer */
14443 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14444 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14445 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14446 { } /* end */
14447 };
14448
14449 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14450 { 2, alc861_uniwill_m31_ch2_init },
14451 { 4, alc861_uniwill_m31_ch4_init },
14452 };
14453
14454 /* Set mic1 and line-in as input and unmute the mixer */
14455 static struct hda_verb alc861_asus_ch2_init[] = {
14456 /* set pin widget 1Ah (line in) for input */
14457 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14458 /* set pin widget 18h (mic1/2) for input, for mic also enable
14459 * the vref
14460 */
14461 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14462
14463 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14464 #if 0
14465 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14466 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14467 #endif
14468 { } /* end */
14469 };
14470 /* Set mic1 nad line-in as output and mute mixer */
14471 static struct hda_verb alc861_asus_ch6_init[] = {
14472 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14473 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14474 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14475 /* set pin widget 18h (mic1) for output (CLFE)*/
14476 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14477 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14478 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14479 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14480
14481 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14482 #if 0
14483 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14484 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14485 #endif
14486 { } /* end */
14487 };
14488
14489 static struct hda_channel_mode alc861_asus_modes[2] = {
14490 { 2, alc861_asus_ch2_init },
14491 { 6, alc861_asus_ch6_init },
14492 };
14493
14494 /* patch-ALC861 */
14495
14496 static struct snd_kcontrol_new alc861_base_mixer[] = {
14497 /* output mixer control */
14498 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14499 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14500 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14501 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14502 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14503
14504 /*Input mixer control */
14505 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14506 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14507 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14508 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14509 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14510 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14512 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14513 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14515
14516 { } /* end */
14517 };
14518
14519 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
14520 /* output mixer control */
14521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14523 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14524 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14525 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14526
14527 /* Input mixer control */
14528 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14529 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14530 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14531 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14532 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14533 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14535 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14538
14539 {
14540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14541 .name = "Channel Mode",
14542 .info = alc_ch_mode_info,
14543 .get = alc_ch_mode_get,
14544 .put = alc_ch_mode_put,
14545 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14546 },
14547 { } /* end */
14548 };
14549
14550 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14551 /* output mixer control */
14552 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14553 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14554 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14555
14556 { } /* end */
14557 };
14558
14559 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14560 /* output mixer control */
14561 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14562 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14563 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14564 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14565 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14566
14567 /* Input mixer control */
14568 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14569 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14570 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14571 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14572 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14573 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14575 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14576 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14577 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14578
14579 {
14580 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14581 .name = "Channel Mode",
14582 .info = alc_ch_mode_info,
14583 .get = alc_ch_mode_get,
14584 .put = alc_ch_mode_put,
14585 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
14586 },
14587 { } /* end */
14588 };
14589
14590 static struct snd_kcontrol_new alc861_asus_mixer[] = {
14591 /* output mixer control */
14592 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14593 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14594 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14595 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14596 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14597
14598 /* Input mixer control */
14599 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14600 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14601 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14602 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14603 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14604 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14605 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14606 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14607 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14608 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
14609
14610 {
14611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14612 .name = "Channel Mode",
14613 .info = alc_ch_mode_info,
14614 .get = alc_ch_mode_get,
14615 .put = alc_ch_mode_put,
14616 .private_value = ARRAY_SIZE(alc861_asus_modes),
14617 },
14618 { }
14619 };
14620
14621 /* additional mixer */
14622 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
14623 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14624 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14625 { }
14626 };
14627
14628 /*
14629 * generic initialization of ADC, input mixers and output mixers
14630 */
14631 static struct hda_verb alc861_base_init_verbs[] = {
14632 /*
14633 * Unmute ADC0 and set the default input to mic-in
14634 */
14635 /* port-A for surround (rear panel) */
14636 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14637 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
14638 /* port-B for mic-in (rear panel) with vref */
14639 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14640 /* port-C for line-in (rear panel) */
14641 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14642 /* port-D for Front */
14643 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14644 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14645 /* port-E for HP out (front panel) */
14646 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14647 /* route front PCM to HP */
14648 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14649 /* port-F for mic-in (front panel) with vref */
14650 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14651 /* port-G for CLFE (rear panel) */
14652 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14653 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14654 /* port-H for side (rear panel) */
14655 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14656 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
14657 /* CD-in */
14658 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14659 /* route front mic to ADC1*/
14660 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14661 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14662
14663 /* Unmute DAC0~3 & spdif out*/
14664 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14665 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14666 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14667 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14668 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14669
14670 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14671 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14672 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14673 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14674 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14675
14676 /* Unmute Stereo Mixer 15 */
14677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14678 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14680 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14681
14682 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14684 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14685 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14686 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14687 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14688 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14689 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14690 /* hp used DAC 3 (Front) */
14691 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14692 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14693
14694 { }
14695 };
14696
14697 static struct hda_verb alc861_threestack_init_verbs[] = {
14698 /*
14699 * Unmute ADC0 and set the default input to mic-in
14700 */
14701 /* port-A for surround (rear panel) */
14702 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14703 /* port-B for mic-in (rear panel) with vref */
14704 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14705 /* port-C for line-in (rear panel) */
14706 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14707 /* port-D for Front */
14708 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14709 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14710 /* port-E for HP out (front panel) */
14711 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
14712 /* route front PCM to HP */
14713 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14714 /* port-F for mic-in (front panel) with vref */
14715 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14716 /* port-G for CLFE (rear panel) */
14717 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14718 /* port-H for side (rear panel) */
14719 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14720 /* CD-in */
14721 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14722 /* route front mic to ADC1*/
14723 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14724 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14725 /* Unmute DAC0~3 & spdif out*/
14726 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14727 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14728 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14729 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14731
14732 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14733 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14734 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14735 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14736 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14737
14738 /* Unmute Stereo Mixer 15 */
14739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14740 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14743
14744 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14745 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14746 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14749 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14751 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14752 /* hp used DAC 3 (Front) */
14753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14755 { }
14756 };
14757
14758 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
14759 /*
14760 * Unmute ADC0 and set the default input to mic-in
14761 */
14762 /* port-A for surround (rear panel) */
14763 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14764 /* port-B for mic-in (rear panel) with vref */
14765 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14766 /* port-C for line-in (rear panel) */
14767 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14768 /* port-D for Front */
14769 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14770 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14771 /* port-E for HP out (front panel) */
14772 /* this has to be set to VREF80 */
14773 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14774 /* route front PCM to HP */
14775 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14776 /* port-F for mic-in (front panel) with vref */
14777 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14778 /* port-G for CLFE (rear panel) */
14779 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14780 /* port-H for side (rear panel) */
14781 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14782 /* CD-in */
14783 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14784 /* route front mic to ADC1*/
14785 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14787 /* Unmute DAC0~3 & spdif out*/
14788 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14789 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14790 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14791 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14793
14794 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14795 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14796 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14797 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14798 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14799
14800 /* Unmute Stereo Mixer 15 */
14801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14803 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14804 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14805
14806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14808 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14809 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14810 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14811 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14812 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14813 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14814 /* hp used DAC 3 (Front) */
14815 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14817 { }
14818 };
14819
14820 static struct hda_verb alc861_asus_init_verbs[] = {
14821 /*
14822 * Unmute ADC0 and set the default input to mic-in
14823 */
14824 /* port-A for surround (rear panel)
14825 * according to codec#0 this is the HP jack
14826 */
14827 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
14828 /* route front PCM to HP */
14829 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
14830 /* port-B for mic-in (rear panel) with vref */
14831 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14832 /* port-C for line-in (rear panel) */
14833 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14834 /* port-D for Front */
14835 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14836 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
14837 /* port-E for HP out (front panel) */
14838 /* this has to be set to VREF80 */
14839 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14840 /* route front PCM to HP */
14841 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
14842 /* port-F for mic-in (front panel) with vref */
14843 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14844 /* port-G for CLFE (rear panel) */
14845 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14846 /* port-H for side (rear panel) */
14847 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14848 /* CD-in */
14849 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14850 /* route front mic to ADC1*/
14851 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
14852 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14853 /* Unmute DAC0~3 & spdif out*/
14854 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14855 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14856 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14857 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14859 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14860 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14861 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14862 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14863 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14864
14865 /* Unmute Stereo Mixer 15 */
14866 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14868 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14869 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
14870
14871 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14872 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14873 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14874 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14875 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14876 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14877 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14879 /* hp used DAC 3 (Front) */
14880 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
14881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14882 { }
14883 };
14884
14885 /* additional init verbs for ASUS laptops */
14886 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
14887 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
14888 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
14889 { }
14890 };
14891
14892 /*
14893 * generic initialization of ADC, input mixers and output mixers
14894 */
14895 static struct hda_verb alc861_auto_init_verbs[] = {
14896 /*
14897 * Unmute ADC0 and set the default input to mic-in
14898 */
14899 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
14900 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14901
14902 /* Unmute DAC0~3 & spdif out*/
14903 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14904 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14905 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14906 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14908
14909 /* Unmute Mixer 14 (mic) 1c (Line in)*/
14910 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14911 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14912 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14913 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14914
14915 /* Unmute Stereo Mixer 15 */
14916 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14917 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14918 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14919 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14920
14921 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14922 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14923 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14924 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14925 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14926 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14927 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14928 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14929
14930 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14931 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14932 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14933 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14934 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14935 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14937 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14938
14939 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14940
14941 { }
14942 };
14943
14944 static struct hda_verb alc861_toshiba_init_verbs[] = {
14945 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14946
14947 { }
14948 };
14949
14950 /* toggle speaker-output according to the hp-jack state */
14951 static void alc861_toshiba_automute(struct hda_codec *codec)
14952 {
14953 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
14954
14955 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
14956 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14957 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
14958 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
14959 }
14960
14961 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
14962 unsigned int res)
14963 {
14964 if ((res >> 26) == ALC880_HP_EVENT)
14965 alc861_toshiba_automute(codec);
14966 }
14967
14968 /* pcm configuration: identical with ALC880 */
14969 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
14970 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
14971 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
14972 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
14973
14974
14975 #define ALC861_DIGOUT_NID 0x07
14976
14977 static struct hda_channel_mode alc861_8ch_modes[1] = {
14978 { 8, NULL }
14979 };
14980
14981 static hda_nid_t alc861_dac_nids[4] = {
14982 /* front, surround, clfe, side */
14983 0x03, 0x06, 0x05, 0x04
14984 };
14985
14986 static hda_nid_t alc660_dac_nids[3] = {
14987 /* front, clfe, surround */
14988 0x03, 0x05, 0x06
14989 };
14990
14991 static hda_nid_t alc861_adc_nids[1] = {
14992 /* ADC0-2 */
14993 0x08,
14994 };
14995
14996 static struct hda_input_mux alc861_capture_source = {
14997 .num_items = 5,
14998 .items = {
14999 { "Mic", 0x0 },
15000 { "Front Mic", 0x3 },
15001 { "Line", 0x1 },
15002 { "CD", 0x4 },
15003 { "Mixer", 0x5 },
15004 },
15005 };
15006
15007 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15008 {
15009 struct alc_spec *spec = codec->spec;
15010 hda_nid_t mix, srcs[5];
15011 int i, j, num;
15012
15013 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15014 return 0;
15015 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15016 if (num < 0)
15017 return 0;
15018 for (i = 0; i < num; i++) {
15019 unsigned int type;
15020 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15021 if (type != AC_WID_AUD_OUT)
15022 continue;
15023 for (j = 0; j < spec->multiout.num_dacs; j++)
15024 if (spec->multiout.dac_nids[j] == srcs[i])
15025 break;
15026 if (j >= spec->multiout.num_dacs)
15027 return srcs[i];
15028 }
15029 return 0;
15030 }
15031
15032 /* fill in the dac_nids table from the parsed pin configuration */
15033 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15034 const struct auto_pin_cfg *cfg)
15035 {
15036 struct alc_spec *spec = codec->spec;
15037 int i;
15038 hda_nid_t nid, dac;
15039
15040 spec->multiout.dac_nids = spec->private_dac_nids;
15041 for (i = 0; i < cfg->line_outs; i++) {
15042 nid = cfg->line_out_pins[i];
15043 dac = alc861_look_for_dac(codec, nid);
15044 if (!dac)
15045 continue;
15046 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
15047 }
15048 return 0;
15049 }
15050
15051 static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15052 hda_nid_t nid, unsigned int chs)
15053 {
15054 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx,
15055 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15056 }
15057
15058 /* add playback controls from the parsed DAC table */
15059 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15060 const struct auto_pin_cfg *cfg)
15061 {
15062 struct alc_spec *spec = codec->spec;
15063 static const char *chname[4] = {
15064 "Front", "Surround", NULL /*CLFE*/, "Side"
15065 };
15066 hda_nid_t nid;
15067 int i, err;
15068
15069 if (cfg->line_outs == 1) {
15070 const char *pfx = NULL;
15071 if (!cfg->hp_outs)
15072 pfx = "Master";
15073 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15074 pfx = "Speaker";
15075 if (pfx) {
15076 nid = spec->multiout.dac_nids[0];
15077 return alc861_create_out_sw(codec, pfx, nid, 3);
15078 }
15079 }
15080
15081 for (i = 0; i < cfg->line_outs; i++) {
15082 nid = spec->multiout.dac_nids[i];
15083 if (!nid)
15084 continue;
15085 if (i == 2) {
15086 /* Center/LFE */
15087 err = alc861_create_out_sw(codec, "Center", nid, 1);
15088 if (err < 0)
15089 return err;
15090 err = alc861_create_out_sw(codec, "LFE", nid, 2);
15091 if (err < 0)
15092 return err;
15093 } else {
15094 err = alc861_create_out_sw(codec, chname[i], nid, 3);
15095 if (err < 0)
15096 return err;
15097 }
15098 }
15099 return 0;
15100 }
15101
15102 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
15103 {
15104 struct alc_spec *spec = codec->spec;
15105 int err;
15106 hda_nid_t nid;
15107
15108 if (!pin)
15109 return 0;
15110
15111 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
15112 nid = alc861_look_for_dac(codec, pin);
15113 if (nid) {
15114 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15115 if (err < 0)
15116 return err;
15117 spec->multiout.hp_nid = nid;
15118 }
15119 }
15120 return 0;
15121 }
15122
15123 /* create playback/capture controls for input pins */
15124 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
15125 const struct auto_pin_cfg *cfg)
15126 {
15127 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
15128 }
15129
15130 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15131 hda_nid_t nid,
15132 int pin_type, hda_nid_t dac)
15133 {
15134 hda_nid_t mix, srcs[5];
15135 int i, num;
15136
15137 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15138 pin_type);
15139 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15140 AMP_OUT_UNMUTE);
15141 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15142 return;
15143 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15144 if (num < 0)
15145 return;
15146 for (i = 0; i < num; i++) {
15147 unsigned int mute;
15148 if (srcs[i] == dac || srcs[i] == 0x15)
15149 mute = AMP_IN_UNMUTE(i);
15150 else
15151 mute = AMP_IN_MUTE(i);
15152 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15153 mute);
15154 }
15155 }
15156
15157 static void alc861_auto_init_multi_out(struct hda_codec *codec)
15158 {
15159 struct alc_spec *spec = codec->spec;
15160 int i;
15161
15162 for (i = 0; i < spec->autocfg.line_outs; i++) {
15163 hda_nid_t nid = spec->autocfg.line_out_pins[i];
15164 int pin_type = get_pin_type(spec->autocfg.line_out_type);
15165 if (nid)
15166 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
15167 spec->multiout.dac_nids[i]);
15168 }
15169 }
15170
15171 static void alc861_auto_init_hp_out(struct hda_codec *codec)
15172 {
15173 struct alc_spec *spec = codec->spec;
15174
15175 if (spec->autocfg.hp_outs)
15176 alc861_auto_set_output_and_unmute(codec,
15177 spec->autocfg.hp_pins[0],
15178 PIN_HP,
15179 spec->multiout.hp_nid);
15180 if (spec->autocfg.speaker_outs)
15181 alc861_auto_set_output_and_unmute(codec,
15182 spec->autocfg.speaker_pins[0],
15183 PIN_OUT,
15184 spec->multiout.dac_nids[0]);
15185 }
15186
15187 static void alc861_auto_init_analog_input(struct hda_codec *codec)
15188 {
15189 struct alc_spec *spec = codec->spec;
15190 int i;
15191
15192 for (i = 0; i < AUTO_PIN_LAST; i++) {
15193 hda_nid_t nid = spec->autocfg.input_pins[i];
15194 if (nid >= 0x0c && nid <= 0x11)
15195 alc_set_input_pin(codec, nid, i);
15196 }
15197 }
15198
15199 /* parse the BIOS configuration and set up the alc_spec */
15200 /* return 1 if successful, 0 if the proper config is not found,
15201 * or a negative error code
15202 */
15203 static int alc861_parse_auto_config(struct hda_codec *codec)
15204 {
15205 struct alc_spec *spec = codec->spec;
15206 int err;
15207 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
15208
15209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15210 alc861_ignore);
15211 if (err < 0)
15212 return err;
15213 if (!spec->autocfg.line_outs)
15214 return 0; /* can't find valid BIOS pin config */
15215
15216 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
15217 if (err < 0)
15218 return err;
15219 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
15220 if (err < 0)
15221 return err;
15222 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
15223 if (err < 0)
15224 return err;
15225 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
15226 if (err < 0)
15227 return err;
15228
15229 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15230
15231 if (spec->autocfg.dig_outs)
15232 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
15233
15234 if (spec->kctls.list)
15235 add_mixer(spec, spec->kctls.list);
15236
15237 add_verb(spec, alc861_auto_init_verbs);
15238
15239 spec->num_mux_defs = 1;
15240 spec->input_mux = &spec->private_imux[0];
15241
15242 spec->adc_nids = alc861_adc_nids;
15243 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
15244 set_capture_mixer(codec);
15245
15246 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
15247
15248 return 1;
15249 }
15250
15251 /* additional initialization for auto-configuration model */
15252 static void alc861_auto_init(struct hda_codec *codec)
15253 {
15254 struct alc_spec *spec = codec->spec;
15255 alc861_auto_init_multi_out(codec);
15256 alc861_auto_init_hp_out(codec);
15257 alc861_auto_init_analog_input(codec);
15258 if (spec->unsol_event)
15259 alc_inithook(codec);
15260 }
15261
15262 #ifdef CONFIG_SND_HDA_POWER_SAVE
15263 static struct hda_amp_list alc861_loopbacks[] = {
15264 { 0x15, HDA_INPUT, 0 },
15265 { 0x15, HDA_INPUT, 1 },
15266 { 0x15, HDA_INPUT, 2 },
15267 { 0x15, HDA_INPUT, 3 },
15268 { } /* end */
15269 };
15270 #endif
15271
15272
15273 /*
15274 * configuration and preset
15275 */
15276 static const char *alc861_models[ALC861_MODEL_LAST] = {
15277 [ALC861_3ST] = "3stack",
15278 [ALC660_3ST] = "3stack-660",
15279 [ALC861_3ST_DIG] = "3stack-dig",
15280 [ALC861_6ST_DIG] = "6stack-dig",
15281 [ALC861_UNIWILL_M31] = "uniwill-m31",
15282 [ALC861_TOSHIBA] = "toshiba",
15283 [ALC861_ASUS] = "asus",
15284 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15285 [ALC861_AUTO] = "auto",
15286 };
15287
15288 static struct snd_pci_quirk alc861_cfg_tbl[] = {
15289 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15290 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15291 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15292 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15293 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15294 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15295 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15296 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15297 * Any other models that need this preset?
15298 */
15299 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15300 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15301 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15302 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15303 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15304 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15305 /* FIXME: the below seems conflict */
15306 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15307 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15308 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15309 {}
15310 };
15311
15312 static struct alc_config_preset alc861_presets[] = {
15313 [ALC861_3ST] = {
15314 .mixers = { alc861_3ST_mixer },
15315 .init_verbs = { alc861_threestack_init_verbs },
15316 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15317 .dac_nids = alc861_dac_nids,
15318 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15319 .channel_mode = alc861_threestack_modes,
15320 .need_dac_fix = 1,
15321 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15322 .adc_nids = alc861_adc_nids,
15323 .input_mux = &alc861_capture_source,
15324 },
15325 [ALC861_3ST_DIG] = {
15326 .mixers = { alc861_base_mixer },
15327 .init_verbs = { alc861_threestack_init_verbs },
15328 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15329 .dac_nids = alc861_dac_nids,
15330 .dig_out_nid = ALC861_DIGOUT_NID,
15331 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15332 .channel_mode = alc861_threestack_modes,
15333 .need_dac_fix = 1,
15334 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15335 .adc_nids = alc861_adc_nids,
15336 .input_mux = &alc861_capture_source,
15337 },
15338 [ALC861_6ST_DIG] = {
15339 .mixers = { alc861_base_mixer },
15340 .init_verbs = { alc861_base_init_verbs },
15341 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15342 .dac_nids = alc861_dac_nids,
15343 .dig_out_nid = ALC861_DIGOUT_NID,
15344 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15345 .channel_mode = alc861_8ch_modes,
15346 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15347 .adc_nids = alc861_adc_nids,
15348 .input_mux = &alc861_capture_source,
15349 },
15350 [ALC660_3ST] = {
15351 .mixers = { alc861_3ST_mixer },
15352 .init_verbs = { alc861_threestack_init_verbs },
15353 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15354 .dac_nids = alc660_dac_nids,
15355 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15356 .channel_mode = alc861_threestack_modes,
15357 .need_dac_fix = 1,
15358 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15359 .adc_nids = alc861_adc_nids,
15360 .input_mux = &alc861_capture_source,
15361 },
15362 [ALC861_UNIWILL_M31] = {
15363 .mixers = { alc861_uniwill_m31_mixer },
15364 .init_verbs = { alc861_uniwill_m31_init_verbs },
15365 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15366 .dac_nids = alc861_dac_nids,
15367 .dig_out_nid = ALC861_DIGOUT_NID,
15368 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15369 .channel_mode = alc861_uniwill_m31_modes,
15370 .need_dac_fix = 1,
15371 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15372 .adc_nids = alc861_adc_nids,
15373 .input_mux = &alc861_capture_source,
15374 },
15375 [ALC861_TOSHIBA] = {
15376 .mixers = { alc861_toshiba_mixer },
15377 .init_verbs = { alc861_base_init_verbs,
15378 alc861_toshiba_init_verbs },
15379 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15380 .dac_nids = alc861_dac_nids,
15381 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15382 .channel_mode = alc883_3ST_2ch_modes,
15383 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15384 .adc_nids = alc861_adc_nids,
15385 .input_mux = &alc861_capture_source,
15386 .unsol_event = alc861_toshiba_unsol_event,
15387 .init_hook = alc861_toshiba_automute,
15388 },
15389 [ALC861_ASUS] = {
15390 .mixers = { alc861_asus_mixer },
15391 .init_verbs = { alc861_asus_init_verbs },
15392 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15393 .dac_nids = alc861_dac_nids,
15394 .dig_out_nid = ALC861_DIGOUT_NID,
15395 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15396 .channel_mode = alc861_asus_modes,
15397 .need_dac_fix = 1,
15398 .hp_nid = 0x06,
15399 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15400 .adc_nids = alc861_adc_nids,
15401 .input_mux = &alc861_capture_source,
15402 },
15403 [ALC861_ASUS_LAPTOP] = {
15404 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15405 .init_verbs = { alc861_asus_init_verbs,
15406 alc861_asus_laptop_init_verbs },
15407 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15408 .dac_nids = alc861_dac_nids,
15409 .dig_out_nid = ALC861_DIGOUT_NID,
15410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15411 .channel_mode = alc883_3ST_2ch_modes,
15412 .need_dac_fix = 1,
15413 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15414 .adc_nids = alc861_adc_nids,
15415 .input_mux = &alc861_capture_source,
15416 },
15417 };
15418
15419 /* Pin config fixes */
15420 enum {
15421 PINFIX_FSC_AMILO_PI1505,
15422 };
15423
15424 static struct alc_pincfg alc861_fsc_amilo_pi1505_pinfix[] = {
15425 { 0x0b, 0x0221101f }, /* HP */
15426 { 0x0f, 0x90170310 }, /* speaker */
15427 { }
15428 };
15429
15430 static const struct alc_fixup alc861_fixups[] = {
15431 [PINFIX_FSC_AMILO_PI1505] = {
15432 .pins = alc861_fsc_amilo_pi1505_pinfix
15433 },
15434 };
15435
15436 static struct snd_pci_quirk alc861_fixup_tbl[] = {
15437 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15438 {}
15439 };
15440
15441 static int patch_alc861(struct hda_codec *codec)
15442 {
15443 struct alc_spec *spec;
15444 int board_config;
15445 int err;
15446
15447 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15448 if (spec == NULL)
15449 return -ENOMEM;
15450
15451 codec->spec = spec;
15452
15453 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15454 alc861_models,
15455 alc861_cfg_tbl);
15456
15457 if (board_config < 0) {
15458 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15459 codec->chip_name);
15460 board_config = ALC861_AUTO;
15461 }
15462
15463 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups);
15464
15465 if (board_config == ALC861_AUTO) {
15466 /* automatic parse from the BIOS config */
15467 err = alc861_parse_auto_config(codec);
15468 if (err < 0) {
15469 alc_free(codec);
15470 return err;
15471 } else if (!err) {
15472 printk(KERN_INFO
15473 "hda_codec: Cannot set up configuration "
15474 "from BIOS. Using base mode...\n");
15475 board_config = ALC861_3ST_DIG;
15476 }
15477 }
15478
15479 err = snd_hda_attach_beep_device(codec, 0x23);
15480 if (err < 0) {
15481 alc_free(codec);
15482 return err;
15483 }
15484
15485 if (board_config != ALC861_AUTO)
15486 setup_preset(codec, &alc861_presets[board_config]);
15487
15488 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15489 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15490
15491 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15492 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15493
15494 if (!spec->cap_mixer)
15495 set_capture_mixer(codec);
15496 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15497
15498 spec->vmaster_nid = 0x03;
15499
15500 codec->patch_ops = alc_patch_ops;
15501 if (board_config == ALC861_AUTO) {
15502 spec->init_hook = alc861_auto_init;
15503 #ifdef CONFIG_SND_HDA_POWER_SAVE
15504 spec->power_hook = alc_power_eapd;
15505 #endif
15506 }
15507 #ifdef CONFIG_SND_HDA_POWER_SAVE
15508 if (!spec->loopback.amplist)
15509 spec->loopback.amplist = alc861_loopbacks;
15510 #endif
15511
15512 return 0;
15513 }
15514
15515 /*
15516 * ALC861-VD support
15517 *
15518 * Based on ALC882
15519 *
15520 * In addition, an independent DAC
15521 */
15522 #define ALC861VD_DIGOUT_NID 0x06
15523
15524 static hda_nid_t alc861vd_dac_nids[4] = {
15525 /* front, surr, clfe, side surr */
15526 0x02, 0x03, 0x04, 0x05
15527 };
15528
15529 /* dac_nids for ALC660vd are in a different order - according to
15530 * Realtek's driver.
15531 * This should probably result in a different mixer for 6stack models
15532 * of ALC660vd codecs, but for now there is only 3stack mixer
15533 * - and it is the same as in 861vd.
15534 * adc_nids in ALC660vd are (is) the same as in 861vd
15535 */
15536 static hda_nid_t alc660vd_dac_nids[3] = {
15537 /* front, rear, clfe, rear_surr */
15538 0x02, 0x04, 0x03
15539 };
15540
15541 static hda_nid_t alc861vd_adc_nids[1] = {
15542 /* ADC0 */
15543 0x09,
15544 };
15545
15546 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15547
15548 /* input MUX */
15549 /* FIXME: should be a matrix-type input source selection */
15550 static struct hda_input_mux alc861vd_capture_source = {
15551 .num_items = 4,
15552 .items = {
15553 { "Mic", 0x0 },
15554 { "Front Mic", 0x1 },
15555 { "Line", 0x2 },
15556 { "CD", 0x4 },
15557 },
15558 };
15559
15560 static struct hda_input_mux alc861vd_dallas_capture_source = {
15561 .num_items = 2,
15562 .items = {
15563 { "Ext Mic", 0x0 },
15564 { "Int Mic", 0x1 },
15565 },
15566 };
15567
15568 static struct hda_input_mux alc861vd_hp_capture_source = {
15569 .num_items = 2,
15570 .items = {
15571 { "Front Mic", 0x0 },
15572 { "ATAPI Mic", 0x1 },
15573 },
15574 };
15575
15576 /*
15577 * 2ch mode
15578 */
15579 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15580 { 2, NULL }
15581 };
15582
15583 /*
15584 * 6ch mode
15585 */
15586 static struct hda_verb alc861vd_6stack_ch6_init[] = {
15587 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15588 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15589 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15590 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15591 { } /* end */
15592 };
15593
15594 /*
15595 * 8ch mode
15596 */
15597 static struct hda_verb alc861vd_6stack_ch8_init[] = {
15598 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15599 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15600 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15601 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15602 { } /* end */
15603 };
15604
15605 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
15606 { 6, alc861vd_6stack_ch6_init },
15607 { 8, alc861vd_6stack_ch8_init },
15608 };
15609
15610 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15611 {
15612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15613 .name = "Channel Mode",
15614 .info = alc_ch_mode_info,
15615 .get = alc_ch_mode_get,
15616 .put = alc_ch_mode_put,
15617 },
15618 { } /* end */
15619 };
15620
15621 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15622 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15623 */
15624 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15625 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15626 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15627
15628 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15629 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15630
15631 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15632 HDA_OUTPUT),
15633 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15634 HDA_OUTPUT),
15635 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15636 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15637
15638 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15639 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15640
15641 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15642
15643 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15646
15647 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15648 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15649 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15650
15651 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15652 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15653
15654 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15655 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15656
15657 { } /* end */
15658 };
15659
15660 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
15661 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15662 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15663
15664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15665
15666 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15669
15670 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15671 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15672 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15673
15674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15676
15677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15679
15680 { } /* end */
15681 };
15682
15683 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
15684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15685 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
15686 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
15687
15688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15689
15690 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
15691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15693
15694 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
15695 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15696 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15697
15698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15700
15701 { } /* end */
15702 };
15703
15704 /* Pin assignment: Speaker=0x14, HP = 0x15,
15705 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
15706 */
15707 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
15708 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15709 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
15710 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15711 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15712 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
15713 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15714 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15715 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
15716 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15717 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15718 { } /* end */
15719 };
15720
15721 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
15722 * Front Mic=0x18, ATAPI Mic = 0x19,
15723 */
15724 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
15725 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15726 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15727 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15728 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
15729 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15730 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15731 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15732 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15733
15734 { } /* end */
15735 };
15736
15737 /*
15738 * generic initialization of ADC, input mixers and output mixers
15739 */
15740 static struct hda_verb alc861vd_volume_init_verbs[] = {
15741 /*
15742 * Unmute ADC0 and set the default input to mic-in
15743 */
15744 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15745 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15746
15747 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
15748 * the analog-loopback mixer widget
15749 */
15750 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15751 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15752 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15753 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15754 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15755 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15756
15757 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
15758 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15761 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15762
15763 /*
15764 * Set up output mixers (0x02 - 0x05)
15765 */
15766 /* set vol=0 to output mixers */
15767 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15768 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15769 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15770 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15771
15772 /* set up input amps for analog loopback */
15773 /* Amp Indices: DAC = 0, mixer = 1 */
15774 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15777 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15779 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15780 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15781 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15782
15783 { }
15784 };
15785
15786 /*
15787 * 3-stack pin configuration:
15788 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
15789 */
15790 static struct hda_verb alc861vd_3stack_init_verbs[] = {
15791 /*
15792 * Set pin mode and muting
15793 */
15794 /* set front pin widgets 0x14 for output */
15795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15797 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15798
15799 /* Mic (rear) pin: input vref at 80% */
15800 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15801 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15802 /* Front Mic pin: input vref at 80% */
15803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15804 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15805 /* Line In pin: input */
15806 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15807 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15808 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15809 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15810 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15811 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15812 /* CD pin widget for input */
15813 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15814
15815 { }
15816 };
15817
15818 /*
15819 * 6-stack pin configuration:
15820 */
15821 static struct hda_verb alc861vd_6stack_init_verbs[] = {
15822 /*
15823 * Set pin mode and muting
15824 */
15825 /* set front pin widgets 0x14 for output */
15826 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15827 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15828 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
15829
15830 /* Rear Pin: output 1 (0x0d) */
15831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15832 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
15834 /* CLFE Pin: output 2 (0x0e) */
15835 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15836 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
15838 /* Side Pin: output 3 (0x0f) */
15839 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15840 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15841 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
15842
15843 /* Mic (rear) pin: input vref at 80% */
15844 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15845 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15846 /* Front Mic pin: input vref at 80% */
15847 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15848 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15849 /* Line In pin: input */
15850 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15852 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15853 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15854 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15855 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15856 /* CD pin widget for input */
15857 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15858
15859 { }
15860 };
15861
15862 static struct hda_verb alc861vd_eapd_verbs[] = {
15863 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15864 { }
15865 };
15866
15867 static struct hda_verb alc660vd_eapd_verbs[] = {
15868 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15869 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15870 { }
15871 };
15872
15873 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
15874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15876 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
15877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15878 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15879 {}
15880 };
15881
15882 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15883 {
15884 unsigned int present;
15885 unsigned char bits;
15886
15887 present = snd_hda_jack_detect(codec, 0x18);
15888 bits = present ? HDA_AMP_MUTE : 0;
15889
15890 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
15891 HDA_AMP_MUTE, bits);
15892 }
15893
15894 static void alc861vd_lenovo_setup(struct hda_codec *codec)
15895 {
15896 struct alc_spec *spec = codec->spec;
15897 spec->autocfg.hp_pins[0] = 0x1b;
15898 spec->autocfg.speaker_pins[0] = 0x14;
15899 }
15900
15901 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15902 {
15903 alc_automute_amp(codec);
15904 alc861vd_lenovo_mic_automute(codec);
15905 }
15906
15907 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
15908 unsigned int res)
15909 {
15910 switch (res >> 26) {
15911 case ALC880_MIC_EVENT:
15912 alc861vd_lenovo_mic_automute(codec);
15913 break;
15914 default:
15915 alc_automute_amp_unsol_event(codec, res);
15916 break;
15917 }
15918 }
15919
15920 static struct hda_verb alc861vd_dallas_verbs[] = {
15921 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15922 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15923 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15924 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15925
15926 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15927 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15928 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15929 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15930 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15932 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15933 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15934
15935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15939 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15940 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15941 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15942 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15943
15944 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15945 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15946 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
15947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15948 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15949 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15950 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15951 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15952
15953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15957
15958 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15959 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15960 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15961
15962 { } /* end */
15963 };
15964
15965 /* toggle speaker-output according to the hp-jack state */
15966 static void alc861vd_dallas_setup(struct hda_codec *codec)
15967 {
15968 struct alc_spec *spec = codec->spec;
15969
15970 spec->autocfg.hp_pins[0] = 0x15;
15971 spec->autocfg.speaker_pins[0] = 0x14;
15972 }
15973
15974 #ifdef CONFIG_SND_HDA_POWER_SAVE
15975 #define alc861vd_loopbacks alc880_loopbacks
15976 #endif
15977
15978 /* pcm configuration: identical with ALC880 */
15979 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
15980 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
15981 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
15982 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
15983
15984 /*
15985 * configuration and preset
15986 */
15987 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
15988 [ALC660VD_3ST] = "3stack-660",
15989 [ALC660VD_3ST_DIG] = "3stack-660-digout",
15990 [ALC660VD_ASUS_V1S] = "asus-v1s",
15991 [ALC861VD_3ST] = "3stack",
15992 [ALC861VD_3ST_DIG] = "3stack-digout",
15993 [ALC861VD_6ST_DIG] = "6stack-digout",
15994 [ALC861VD_LENOVO] = "lenovo",
15995 [ALC861VD_DALLAS] = "dallas",
15996 [ALC861VD_HP] = "hp",
15997 [ALC861VD_AUTO] = "auto",
15998 };
15999
16000 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16001 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16002 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16003 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16004 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16005 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16006 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16007 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16008 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16009 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16010 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16011 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16012 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16013 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16014 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16015 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16016 {}
16017 };
16018
16019 static struct alc_config_preset alc861vd_presets[] = {
16020 [ALC660VD_3ST] = {
16021 .mixers = { alc861vd_3st_mixer },
16022 .init_verbs = { alc861vd_volume_init_verbs,
16023 alc861vd_3stack_init_verbs },
16024 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16025 .dac_nids = alc660vd_dac_nids,
16026 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16027 .channel_mode = alc861vd_3stack_2ch_modes,
16028 .input_mux = &alc861vd_capture_source,
16029 },
16030 [ALC660VD_3ST_DIG] = {
16031 .mixers = { alc861vd_3st_mixer },
16032 .init_verbs = { alc861vd_volume_init_verbs,
16033 alc861vd_3stack_init_verbs },
16034 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16035 .dac_nids = alc660vd_dac_nids,
16036 .dig_out_nid = ALC861VD_DIGOUT_NID,
16037 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16038 .channel_mode = alc861vd_3stack_2ch_modes,
16039 .input_mux = &alc861vd_capture_source,
16040 },
16041 [ALC861VD_3ST] = {
16042 .mixers = { alc861vd_3st_mixer },
16043 .init_verbs = { alc861vd_volume_init_verbs,
16044 alc861vd_3stack_init_verbs },
16045 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16046 .dac_nids = alc861vd_dac_nids,
16047 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16048 .channel_mode = alc861vd_3stack_2ch_modes,
16049 .input_mux = &alc861vd_capture_source,
16050 },
16051 [ALC861VD_3ST_DIG] = {
16052 .mixers = { alc861vd_3st_mixer },
16053 .init_verbs = { alc861vd_volume_init_verbs,
16054 alc861vd_3stack_init_verbs },
16055 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16056 .dac_nids = alc861vd_dac_nids,
16057 .dig_out_nid = ALC861VD_DIGOUT_NID,
16058 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16059 .channel_mode = alc861vd_3stack_2ch_modes,
16060 .input_mux = &alc861vd_capture_source,
16061 },
16062 [ALC861VD_6ST_DIG] = {
16063 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16064 .init_verbs = { alc861vd_volume_init_verbs,
16065 alc861vd_6stack_init_verbs },
16066 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16067 .dac_nids = alc861vd_dac_nids,
16068 .dig_out_nid = ALC861VD_DIGOUT_NID,
16069 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16070 .channel_mode = alc861vd_6stack_modes,
16071 .input_mux = &alc861vd_capture_source,
16072 },
16073 [ALC861VD_LENOVO] = {
16074 .mixers = { alc861vd_lenovo_mixer },
16075 .init_verbs = { alc861vd_volume_init_verbs,
16076 alc861vd_3stack_init_verbs,
16077 alc861vd_eapd_verbs,
16078 alc861vd_lenovo_unsol_verbs },
16079 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16080 .dac_nids = alc660vd_dac_nids,
16081 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16082 .channel_mode = alc861vd_3stack_2ch_modes,
16083 .input_mux = &alc861vd_capture_source,
16084 .unsol_event = alc861vd_lenovo_unsol_event,
16085 .setup = alc861vd_lenovo_setup,
16086 .init_hook = alc861vd_lenovo_init_hook,
16087 },
16088 [ALC861VD_DALLAS] = {
16089 .mixers = { alc861vd_dallas_mixer },
16090 .init_verbs = { alc861vd_dallas_verbs },
16091 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16092 .dac_nids = alc861vd_dac_nids,
16093 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16094 .channel_mode = alc861vd_3stack_2ch_modes,
16095 .input_mux = &alc861vd_dallas_capture_source,
16096 .unsol_event = alc_automute_amp_unsol_event,
16097 .setup = alc861vd_dallas_setup,
16098 .init_hook = alc_automute_amp,
16099 },
16100 [ALC861VD_HP] = {
16101 .mixers = { alc861vd_hp_mixer },
16102 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16103 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16104 .dac_nids = alc861vd_dac_nids,
16105 .dig_out_nid = ALC861VD_DIGOUT_NID,
16106 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16107 .channel_mode = alc861vd_3stack_2ch_modes,
16108 .input_mux = &alc861vd_hp_capture_source,
16109 .unsol_event = alc_automute_amp_unsol_event,
16110 .setup = alc861vd_dallas_setup,
16111 .init_hook = alc_automute_amp,
16112 },
16113 [ALC660VD_ASUS_V1S] = {
16114 .mixers = { alc861vd_lenovo_mixer },
16115 .init_verbs = { alc861vd_volume_init_verbs,
16116 alc861vd_3stack_init_verbs,
16117 alc861vd_eapd_verbs,
16118 alc861vd_lenovo_unsol_verbs },
16119 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16120 .dac_nids = alc660vd_dac_nids,
16121 .dig_out_nid = ALC861VD_DIGOUT_NID,
16122 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16123 .channel_mode = alc861vd_3stack_2ch_modes,
16124 .input_mux = &alc861vd_capture_source,
16125 .unsol_event = alc861vd_lenovo_unsol_event,
16126 .setup = alc861vd_lenovo_setup,
16127 .init_hook = alc861vd_lenovo_init_hook,
16128 },
16129 };
16130
16131 /*
16132 * BIOS auto configuration
16133 */
16134 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16135 const struct auto_pin_cfg *cfg)
16136 {
16137 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
16138 }
16139
16140
16141 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
16142 hda_nid_t nid, int pin_type, int dac_idx)
16143 {
16144 alc_set_pin_output(codec, nid, pin_type);
16145 }
16146
16147 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
16148 {
16149 struct alc_spec *spec = codec->spec;
16150 int i;
16151
16152 for (i = 0; i <= HDA_SIDE; i++) {
16153 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16154 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16155 if (nid)
16156 alc861vd_auto_set_output_and_unmute(codec, nid,
16157 pin_type, i);
16158 }
16159 }
16160
16161
16162 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
16163 {
16164 struct alc_spec *spec = codec->spec;
16165 hda_nid_t pin;
16166
16167 pin = spec->autocfg.hp_pins[0];
16168 if (pin) /* connect to front and use dac 0 */
16169 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16170 pin = spec->autocfg.speaker_pins[0];
16171 if (pin)
16172 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16173 }
16174
16175 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
16176
16177 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
16178 {
16179 struct alc_spec *spec = codec->spec;
16180 int i;
16181
16182 for (i = 0; i < AUTO_PIN_LAST; i++) {
16183 hda_nid_t nid = spec->autocfg.input_pins[i];
16184 if (alc_is_input_pin(codec, nid)) {
16185 alc_set_input_pin(codec, nid, i);
16186 if (nid != ALC861VD_PIN_CD_NID &&
16187 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
16188 snd_hda_codec_write(codec, nid, 0,
16189 AC_VERB_SET_AMP_GAIN_MUTE,
16190 AMP_OUT_MUTE);
16191 }
16192 }
16193 }
16194
16195 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
16196
16197 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16198 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16199
16200 /* add playback controls from the parsed DAC table */
16201 /* Based on ALC880 version. But ALC861VD has separate,
16202 * different NIDs for mute/unmute switch and volume control */
16203 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16204 const struct auto_pin_cfg *cfg)
16205 {
16206 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
16207 hda_nid_t nid_v, nid_s;
16208 int i, err;
16209
16210 for (i = 0; i < cfg->line_outs; i++) {
16211 if (!spec->multiout.dac_nids[i])
16212 continue;
16213 nid_v = alc861vd_idx_to_mixer_vol(
16214 alc880_dac_to_idx(
16215 spec->multiout.dac_nids[i]));
16216 nid_s = alc861vd_idx_to_mixer_switch(
16217 alc880_dac_to_idx(
16218 spec->multiout.dac_nids[i]));
16219
16220 if (i == 2) {
16221 /* Center/LFE */
16222 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16223 "Center",
16224 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16225 HDA_OUTPUT));
16226 if (err < 0)
16227 return err;
16228 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16229 "LFE",
16230 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16231 HDA_OUTPUT));
16232 if (err < 0)
16233 return err;
16234 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16235 "Center",
16236 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16237 HDA_INPUT));
16238 if (err < 0)
16239 return err;
16240 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16241 "LFE",
16242 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16243 HDA_INPUT));
16244 if (err < 0)
16245 return err;
16246 } else {
16247 const char *pfx;
16248 if (cfg->line_outs == 1 &&
16249 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
16250 if (!cfg->hp_pins)
16251 pfx = "Speaker";
16252 else
16253 pfx = "PCM";
16254 } else
16255 pfx = chname[i];
16256 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16257 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16258 HDA_OUTPUT));
16259 if (err < 0)
16260 return err;
16261 if (cfg->line_outs == 1 &&
16262 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
16263 pfx = "Speaker";
16264 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16265 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
16266 HDA_INPUT));
16267 if (err < 0)
16268 return err;
16269 }
16270 }
16271 return 0;
16272 }
16273
16274 /* add playback controls for speaker and HP outputs */
16275 /* Based on ALC880 version. But ALC861VD has separate,
16276 * different NIDs for mute/unmute switch and volume control */
16277 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16278 hda_nid_t pin, const char *pfx)
16279 {
16280 hda_nid_t nid_v, nid_s;
16281 int err;
16282
16283 if (!pin)
16284 return 0;
16285
16286 if (alc880_is_fixed_pin(pin)) {
16287 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16288 /* specify the DAC as the extra output */
16289 if (!spec->multiout.hp_nid)
16290 spec->multiout.hp_nid = nid_v;
16291 else
16292 spec->multiout.extra_out_nid[0] = nid_v;
16293 /* control HP volume/switch on the output mixer amp */
16294 nid_v = alc861vd_idx_to_mixer_vol(
16295 alc880_fixed_pin_idx(pin));
16296 nid_s = alc861vd_idx_to_mixer_switch(
16297 alc880_fixed_pin_idx(pin));
16298
16299 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16300 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16301 if (err < 0)
16302 return err;
16303 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
16304 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16305 if (err < 0)
16306 return err;
16307 } else if (alc880_is_multi_pin(pin)) {
16308 /* set manual connection */
16309 /* we have only a switch on HP-out PIN */
16310 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
16311 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16312 if (err < 0)
16313 return err;
16314 }
16315 return 0;
16316 }
16317
16318 /* parse the BIOS configuration and set up the alc_spec
16319 * return 1 if successful, 0 if the proper config is not found,
16320 * or a negative error code
16321 * Based on ALC880 version - had to change it to override
16322 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16323 static int alc861vd_parse_auto_config(struct hda_codec *codec)
16324 {
16325 struct alc_spec *spec = codec->spec;
16326 int err;
16327 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
16328
16329 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16330 alc861vd_ignore);
16331 if (err < 0)
16332 return err;
16333 if (!spec->autocfg.line_outs)
16334 return 0; /* can't find valid BIOS pin config */
16335
16336 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16337 if (err < 0)
16338 return err;
16339 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16340 if (err < 0)
16341 return err;
16342 err = alc861vd_auto_create_extra_out(spec,
16343 spec->autocfg.speaker_pins[0],
16344 "Speaker");
16345 if (err < 0)
16346 return err;
16347 err = alc861vd_auto_create_extra_out(spec,
16348 spec->autocfg.hp_pins[0],
16349 "Headphone");
16350 if (err < 0)
16351 return err;
16352 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
16353 if (err < 0)
16354 return err;
16355
16356 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16357
16358 if (spec->autocfg.dig_outs)
16359 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
16360
16361 if (spec->kctls.list)
16362 add_mixer(spec, spec->kctls.list);
16363
16364 add_verb(spec, alc861vd_volume_init_verbs);
16365
16366 spec->num_mux_defs = 1;
16367 spec->input_mux = &spec->private_imux[0];
16368
16369 err = alc_auto_add_mic_boost(codec);
16370 if (err < 0)
16371 return err;
16372
16373 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16374
16375 return 1;
16376 }
16377
16378 /* additional initialization for auto-configuration model */
16379 static void alc861vd_auto_init(struct hda_codec *codec)
16380 {
16381 struct alc_spec *spec = codec->spec;
16382 alc861vd_auto_init_multi_out(codec);
16383 alc861vd_auto_init_hp_out(codec);
16384 alc861vd_auto_init_analog_input(codec);
16385 alc861vd_auto_init_input_src(codec);
16386 if (spec->unsol_event)
16387 alc_inithook(codec);
16388 }
16389
16390 enum {
16391 ALC660VD_FIX_ASUS_GPIO1
16392 };
16393
16394 /* reset GPIO1 */
16395 static const struct hda_verb alc660vd_fix_asus_gpio1_verbs[] = {
16396 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16397 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16398 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16399 { }
16400 };
16401
16402 static const struct alc_fixup alc861vd_fixups[] = {
16403 [ALC660VD_FIX_ASUS_GPIO1] = {
16404 .verbs = alc660vd_fix_asus_gpio1_verbs,
16405 },
16406 };
16407
16408 static struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16409 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16410 {}
16411 };
16412
16413 static int patch_alc861vd(struct hda_codec *codec)
16414 {
16415 struct alc_spec *spec;
16416 int err, board_config;
16417
16418 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16419 if (spec == NULL)
16420 return -ENOMEM;
16421
16422 codec->spec = spec;
16423
16424 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16425 alc861vd_models,
16426 alc861vd_cfg_tbl);
16427
16428 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
16429 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16430 codec->chip_name);
16431 board_config = ALC861VD_AUTO;
16432 }
16433
16434 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups);
16435
16436 if (board_config == ALC861VD_AUTO) {
16437 /* automatic parse from the BIOS config */
16438 err = alc861vd_parse_auto_config(codec);
16439 if (err < 0) {
16440 alc_free(codec);
16441 return err;
16442 } else if (!err) {
16443 printk(KERN_INFO
16444 "hda_codec: Cannot set up configuration "
16445 "from BIOS. Using base mode...\n");
16446 board_config = ALC861VD_3ST;
16447 }
16448 }
16449
16450 err = snd_hda_attach_beep_device(codec, 0x23);
16451 if (err < 0) {
16452 alc_free(codec);
16453 return err;
16454 }
16455
16456 if (board_config != ALC861VD_AUTO)
16457 setup_preset(codec, &alc861vd_presets[board_config]);
16458
16459 if (codec->vendor_id == 0x10ec0660) {
16460 /* always turn on EAPD */
16461 add_verb(spec, alc660vd_eapd_verbs);
16462 }
16463
16464 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16465 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16466
16467 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16468 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16469
16470 if (!spec->adc_nids) {
16471 spec->adc_nids = alc861vd_adc_nids;
16472 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
16473 }
16474 if (!spec->capsrc_nids)
16475 spec->capsrc_nids = alc861vd_capsrc_nids;
16476
16477 set_capture_mixer(codec);
16478 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
16479
16480 spec->vmaster_nid = 0x02;
16481
16482 codec->patch_ops = alc_patch_ops;
16483
16484 if (board_config == ALC861VD_AUTO)
16485 spec->init_hook = alc861vd_auto_init;
16486 #ifdef CONFIG_SND_HDA_POWER_SAVE
16487 if (!spec->loopback.amplist)
16488 spec->loopback.amplist = alc861vd_loopbacks;
16489 #endif
16490
16491 return 0;
16492 }
16493
16494 /*
16495 * ALC662 support
16496 *
16497 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16498 * configuration. Each pin widget can choose any input DACs and a mixer.
16499 * Each ADC is connected from a mixer of all inputs. This makes possible
16500 * 6-channel independent captures.
16501 *
16502 * In addition, an independent DAC for the multi-playback (not used in this
16503 * driver yet).
16504 */
16505 #define ALC662_DIGOUT_NID 0x06
16506 #define ALC662_DIGIN_NID 0x0a
16507
16508 static hda_nid_t alc662_dac_nids[4] = {
16509 /* front, rear, clfe, rear_surr */
16510 0x02, 0x03, 0x04
16511 };
16512
16513 static hda_nid_t alc272_dac_nids[2] = {
16514 0x02, 0x03
16515 };
16516
16517 static hda_nid_t alc662_adc_nids[2] = {
16518 /* ADC1-2 */
16519 0x09, 0x08
16520 };
16521
16522 static hda_nid_t alc272_adc_nids[1] = {
16523 /* ADC1-2 */
16524 0x08,
16525 };
16526
16527 static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16528 static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16529
16530
16531 /* input MUX */
16532 /* FIXME: should be a matrix-type input source selection */
16533 static struct hda_input_mux alc662_capture_source = {
16534 .num_items = 4,
16535 .items = {
16536 { "Mic", 0x0 },
16537 { "Front Mic", 0x1 },
16538 { "Line", 0x2 },
16539 { "CD", 0x4 },
16540 },
16541 };
16542
16543 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
16544 .num_items = 2,
16545 .items = {
16546 { "Mic", 0x1 },
16547 { "Line", 0x2 },
16548 },
16549 };
16550
16551 static struct hda_input_mux alc663_capture_source = {
16552 .num_items = 3,
16553 .items = {
16554 { "Mic", 0x0 },
16555 { "Front Mic", 0x1 },
16556 { "Line", 0x2 },
16557 },
16558 };
16559
16560 #if 0 /* set to 1 for testing other input sources below */
16561 static struct hda_input_mux alc272_nc10_capture_source = {
16562 .num_items = 16,
16563 .items = {
16564 { "Autoselect Mic", 0x0 },
16565 { "Internal Mic", 0x1 },
16566 { "In-0x02", 0x2 },
16567 { "In-0x03", 0x3 },
16568 { "In-0x04", 0x4 },
16569 { "In-0x05", 0x5 },
16570 { "In-0x06", 0x6 },
16571 { "In-0x07", 0x7 },
16572 { "In-0x08", 0x8 },
16573 { "In-0x09", 0x9 },
16574 { "In-0x0a", 0x0a },
16575 { "In-0x0b", 0x0b },
16576 { "In-0x0c", 0x0c },
16577 { "In-0x0d", 0x0d },
16578 { "In-0x0e", 0x0e },
16579 { "In-0x0f", 0x0f },
16580 },
16581 };
16582 #endif
16583
16584 /*
16585 * 2ch mode
16586 */
16587 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16588 { 2, NULL }
16589 };
16590
16591 /*
16592 * 2ch mode
16593 */
16594 static struct hda_verb alc662_3ST_ch2_init[] = {
16595 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16596 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16597 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16598 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16599 { } /* end */
16600 };
16601
16602 /*
16603 * 6ch mode
16604 */
16605 static struct hda_verb alc662_3ST_ch6_init[] = {
16606 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16607 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16608 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16609 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16610 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16611 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16612 { } /* end */
16613 };
16614
16615 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16616 { 2, alc662_3ST_ch2_init },
16617 { 6, alc662_3ST_ch6_init },
16618 };
16619
16620 /*
16621 * 2ch mode
16622 */
16623 static struct hda_verb alc662_sixstack_ch6_init[] = {
16624 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16625 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16626 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16627 { } /* end */
16628 };
16629
16630 /*
16631 * 6ch mode
16632 */
16633 static struct hda_verb alc662_sixstack_ch8_init[] = {
16634 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16635 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16636 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16637 { } /* end */
16638 };
16639
16640 static struct hda_channel_mode alc662_5stack_modes[2] = {
16641 { 2, alc662_sixstack_ch6_init },
16642 { 6, alc662_sixstack_ch8_init },
16643 };
16644
16645 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16646 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16647 */
16648
16649 static struct snd_kcontrol_new alc662_base_mixer[] = {
16650 /* output mixer control */
16651 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16652 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16653 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16654 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16655 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16656 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16657 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16658 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16660
16661 /*Input mixer control */
16662 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16663 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16664 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16665 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16666 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16667 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16668 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16669 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16670 { } /* end */
16671 };
16672
16673 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16674 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16675 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16676 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16677 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16678 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16679 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16680 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16683 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16684 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16685 { } /* end */
16686 };
16687
16688 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16689 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16690 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16691 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16692 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16693 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16694 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16695 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16696 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16697 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16698 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16699 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16700 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16701 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16704 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16705 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16706 { } /* end */
16707 };
16708
16709 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16710 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16711 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
16712 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16713 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
16714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16715 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16716 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16717 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16718 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16719 { } /* end */
16720 };
16721
16722 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
16723 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16724 ALC262_HIPPO_MASTER_SWITCH,
16725
16726 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
16727 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16728 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16729
16730 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
16731 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16732 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16733 { } /* end */
16734 };
16735
16736 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
16737 ALC262_HIPPO_MASTER_SWITCH,
16738 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16739 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16740 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16741 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16742 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
16743 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16744 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16747 { } /* end */
16748 };
16749
16750 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
16751 .ops = &snd_hda_bind_vol,
16752 .values = {
16753 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16754 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
16755 0
16756 },
16757 };
16758
16759 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
16760 .ops = &snd_hda_bind_sw,
16761 .values = {
16762 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16763 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16764 0
16765 },
16766 };
16767
16768 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
16769 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16770 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
16771 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16772 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16773 { } /* end */
16774 };
16775
16776 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
16777 .ops = &snd_hda_bind_sw,
16778 .values = {
16779 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16780 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16781 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16782 0
16783 },
16784 };
16785
16786 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
16787 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16788 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
16789 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16790 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16791 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16792 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16793
16794 { } /* end */
16795 };
16796
16797 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
16798 .ops = &snd_hda_bind_sw,
16799 .values = {
16800 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16801 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16802 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16803 0
16804 },
16805 };
16806
16807 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
16808 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16809 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
16810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16811 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16812 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16813 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16814 { } /* end */
16815 };
16816
16817 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
16818 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16819 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16820 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16823 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16824 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16825 { } /* end */
16826 };
16827
16828 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
16829 .ops = &snd_hda_bind_vol,
16830 .values = {
16831 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
16832 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
16833 0
16834 },
16835 };
16836
16837 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
16838 .ops = &snd_hda_bind_sw,
16839 .values = {
16840 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16841 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
16842 0
16843 },
16844 };
16845
16846 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
16847 HDA_BIND_VOL("Master Playback Volume",
16848 &alc663_asus_two_bind_master_vol),
16849 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16850 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16851 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16854 { } /* end */
16855 };
16856
16857 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
16858 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
16859 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
16860 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16861 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16862 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16863 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16864 { } /* end */
16865 };
16866
16867 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
16868 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16869 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16870 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16871 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16872 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16873
16874 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16875 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16876 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16877 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16878 { } /* end */
16879 };
16880
16881 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
16882 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16883 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16884 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16885
16886 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16887 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16888 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16889 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16890 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16891 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16892 { } /* end */
16893 };
16894
16895 static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
16896 .ops = &snd_hda_bind_sw,
16897 .values = {
16898 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16899 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
16900 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16901 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
16902 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
16903 0
16904 },
16905 };
16906
16907 static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
16908 .ops = &snd_hda_bind_sw,
16909 .values = {
16910 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
16911 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
16912 0
16913 },
16914 };
16915
16916 static struct snd_kcontrol_new alc663_mode7_mixer[] = {
16917 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16918 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16919 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16920 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16921 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16922 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16923 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16925 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16926 { } /* end */
16927 };
16928
16929 static struct snd_kcontrol_new alc663_mode8_mixer[] = {
16930 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
16931 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
16932 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
16933 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
16934 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
16935 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16936 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16937 { } /* end */
16938 };
16939
16940
16941 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
16942 {
16943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16944 .name = "Channel Mode",
16945 .info = alc_ch_mode_info,
16946 .get = alc_ch_mode_get,
16947 .put = alc_ch_mode_put,
16948 },
16949 { } /* end */
16950 };
16951
16952 static struct hda_verb alc662_init_verbs[] = {
16953 /* ADC: mute amp left and right */
16954 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16955 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16956
16957 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16959 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16960 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16961 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16962 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16963
16964 /* Front Pin: output 0 (0x0c) */
16965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16966 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16967
16968 /* Rear Pin: output 1 (0x0d) */
16969 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16971
16972 /* CLFE Pin: output 2 (0x0e) */
16973 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16974 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16975
16976 /* Mic (rear) pin: input vref at 80% */
16977 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16978 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16979 /* Front Mic pin: input vref at 80% */
16980 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16981 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16982 /* Line In pin: input */
16983 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16985 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16987 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16988 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16989 /* CD pin widget for input */
16990 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16991
16992 /* FIXME: use matrix-type input source selection */
16993 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16994 /* Input mixer */
16995 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16996 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16997
16998 /* always trun on EAPD */
16999 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17000 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17001
17002 { }
17003 };
17004
17005 static struct hda_verb alc663_init_verbs[] = {
17006 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17007 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17008 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17009 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17010 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17011 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17012 { }
17013 };
17014
17015 static struct hda_verb alc272_init_verbs[] = {
17016 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17017 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17018 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17019 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17020 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17021 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17022 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17023 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17024 { }
17025 };
17026
17027 static struct hda_verb alc662_sue_init_verbs[] = {
17028 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17029 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17030 {}
17031 };
17032
17033 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17034 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17035 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17036 {}
17037 };
17038
17039 /* Set Unsolicited Event*/
17040 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17041 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17042 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17043 {}
17044 };
17045
17046 static struct hda_verb alc663_m51va_init_verbs[] = {
17047 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17048 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17049 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17050 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17051 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17055 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17056 {}
17057 };
17058
17059 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
17060 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17061 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17062 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17064 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17065 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17066 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17067 {}
17068 };
17069
17070 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17071 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17072 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17073 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17074 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17076 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17077 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17078 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17079 {}
17080 };
17081
17082 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
17083 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17084 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17085 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17087 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17088 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17090 {}
17091 };
17092
17093 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17094 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17095 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17096 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17097 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17098 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17100 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17103 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17105 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17106 {}
17107 };
17108
17109 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17110 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17111 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17112 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17113 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17114 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17115 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17116 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17119 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17120 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17121 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17122 {}
17123 };
17124
17125 static struct hda_verb alc663_g71v_init_verbs[] = {
17126 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17127 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17128 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17129
17130 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17131 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17132 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17133
17134 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17135 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17136 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17137 {}
17138 };
17139
17140 static struct hda_verb alc663_g50v_init_verbs[] = {
17141 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17143 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17144
17145 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17146 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17147 {}
17148 };
17149
17150 static struct hda_verb alc662_ecs_init_verbs[] = {
17151 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17152 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17153 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17154 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17155 {}
17156 };
17157
17158 static struct hda_verb alc272_dell_zm1_init_verbs[] = {
17159 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17160 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17161 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17162 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17163 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17164 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17165 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17168 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17169 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17170 {}
17171 };
17172
17173 static struct hda_verb alc272_dell_init_verbs[] = {
17174 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17175 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17176 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17177 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17178 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17179 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17180 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17181 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17182 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17183 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17184 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17185 {}
17186 };
17187
17188 static struct hda_verb alc663_mode7_init_verbs[] = {
17189 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17190 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17191 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17192 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17193 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17194 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17195 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17196 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17197 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17198 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17199 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17201 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17202 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17203 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17204 {}
17205 };
17206
17207 static struct hda_verb alc663_mode8_init_verbs[] = {
17208 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17212 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17213 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17214 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17215 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17216 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17217 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17218 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17221 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17222 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17223 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17224 {}
17225 };
17226
17227 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17228 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17229 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17230 { } /* end */
17231 };
17232
17233 static struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17234 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17235 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17236 { } /* end */
17237 };
17238
17239 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
17240 {
17241 unsigned int present;
17242 unsigned char bits;
17243
17244 present = snd_hda_jack_detect(codec, 0x14);
17245 bits = present ? HDA_AMP_MUTE : 0;
17246
17247 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17248 HDA_AMP_MUTE, bits);
17249 }
17250
17251 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
17252 {
17253 unsigned int present;
17254 unsigned char bits;
17255
17256 present = snd_hda_jack_detect(codec, 0x1b);
17257 bits = present ? HDA_AMP_MUTE : 0;
17258
17259 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17260 HDA_AMP_MUTE, bits);
17261 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17262 HDA_AMP_MUTE, bits);
17263 }
17264
17265 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
17266 unsigned int res)
17267 {
17268 if ((res >> 26) == ALC880_HP_EVENT)
17269 alc662_lenovo_101e_all_automute(codec);
17270 if ((res >> 26) == ALC880_FRONT_EVENT)
17271 alc662_lenovo_101e_ispeaker_automute(codec);
17272 }
17273
17274 /* unsolicited event for HP jack sensing */
17275 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
17276 unsigned int res)
17277 {
17278 if ((res >> 26) == ALC880_MIC_EVENT)
17279 alc_mic_automute(codec);
17280 else
17281 alc262_hippo_unsol_event(codec, res);
17282 }
17283
17284 static void alc662_eeepc_setup(struct hda_codec *codec)
17285 {
17286 struct alc_spec *spec = codec->spec;
17287
17288 alc262_hippo1_setup(codec);
17289 spec->ext_mic.pin = 0x18;
17290 spec->ext_mic.mux_idx = 0;
17291 spec->int_mic.pin = 0x19;
17292 spec->int_mic.mux_idx = 1;
17293 spec->auto_mic = 1;
17294 }
17295
17296 static void alc662_eeepc_inithook(struct hda_codec *codec)
17297 {
17298 alc262_hippo_automute(codec);
17299 alc_mic_automute(codec);
17300 }
17301
17302 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17303 {
17304 struct alc_spec *spec = codec->spec;
17305
17306 spec->autocfg.hp_pins[0] = 0x14;
17307 spec->autocfg.speaker_pins[0] = 0x1b;
17308 }
17309
17310 #define alc662_eeepc_ep20_inithook alc262_hippo_master_update
17311
17312 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
17313 {
17314 unsigned int present;
17315 unsigned char bits;
17316
17317 present = snd_hda_jack_detect(codec, 0x21);
17318 bits = present ? HDA_AMP_MUTE : 0;
17319 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17320 HDA_AMP_MUTE, bits);
17321 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17322 HDA_AMP_MUTE, bits);
17323 }
17324
17325 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
17326 {
17327 unsigned int present;
17328 unsigned char bits;
17329
17330 present = snd_hda_jack_detect(codec, 0x21);
17331 bits = present ? HDA_AMP_MUTE : 0;
17332 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17333 HDA_AMP_MUTE, bits);
17334 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17335 HDA_AMP_MUTE, bits);
17336 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17337 HDA_AMP_MUTE, bits);
17338 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17339 HDA_AMP_MUTE, bits);
17340 }
17341
17342 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
17343 {
17344 unsigned int present;
17345 unsigned char bits;
17346
17347 present = snd_hda_jack_detect(codec, 0x15);
17348 bits = present ? HDA_AMP_MUTE : 0;
17349 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17350 HDA_AMP_MUTE, bits);
17351 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17352 HDA_AMP_MUTE, bits);
17353 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
17354 HDA_AMP_MUTE, bits);
17355 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
17356 HDA_AMP_MUTE, bits);
17357 }
17358
17359 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
17360 {
17361 unsigned int present;
17362 unsigned char bits;
17363
17364 present = snd_hda_jack_detect(codec, 0x1b);
17365 bits = present ? 0 : PIN_OUT;
17366 snd_hda_codec_write(codec, 0x14, 0,
17367 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
17368 }
17369
17370 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
17371 {
17372 unsigned int present1, present2;
17373
17374 present1 = snd_hda_jack_detect(codec, 0x21);
17375 present2 = snd_hda_jack_detect(codec, 0x15);
17376
17377 if (present1 || present2) {
17378 snd_hda_codec_write_cache(codec, 0x14, 0,
17379 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17380 } else {
17381 snd_hda_codec_write_cache(codec, 0x14, 0,
17382 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17383 }
17384 }
17385
17386 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
17387 {
17388 unsigned int present1, present2;
17389
17390 present1 = snd_hda_jack_detect(codec, 0x1b);
17391 present2 = snd_hda_jack_detect(codec, 0x15);
17392
17393 if (present1 || present2) {
17394 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17395 HDA_AMP_MUTE, HDA_AMP_MUTE);
17396 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17397 HDA_AMP_MUTE, HDA_AMP_MUTE);
17398 } else {
17399 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
17400 HDA_AMP_MUTE, 0);
17401 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
17402 HDA_AMP_MUTE, 0);
17403 }
17404 }
17405
17406 static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec)
17407 {
17408 unsigned int present1, present2;
17409
17410 present1 = snd_hda_codec_read(codec, 0x1b, 0,
17411 AC_VERB_GET_PIN_SENSE, 0)
17412 & AC_PINSENSE_PRESENCE;
17413 present2 = snd_hda_codec_read(codec, 0x21, 0,
17414 AC_VERB_GET_PIN_SENSE, 0)
17415 & AC_PINSENSE_PRESENCE;
17416
17417 if (present1 || present2) {
17418 snd_hda_codec_write_cache(codec, 0x14, 0,
17419 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17420 snd_hda_codec_write_cache(codec, 0x17, 0,
17421 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17422 } else {
17423 snd_hda_codec_write_cache(codec, 0x14, 0,
17424 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17425 snd_hda_codec_write_cache(codec, 0x17, 0,
17426 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17427 }
17428 }
17429
17430 static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec)
17431 {
17432 unsigned int present1, present2;
17433
17434 present1 = snd_hda_codec_read(codec, 0x21, 0,
17435 AC_VERB_GET_PIN_SENSE, 0)
17436 & AC_PINSENSE_PRESENCE;
17437 present2 = snd_hda_codec_read(codec, 0x15, 0,
17438 AC_VERB_GET_PIN_SENSE, 0)
17439 & AC_PINSENSE_PRESENCE;
17440
17441 if (present1 || present2) {
17442 snd_hda_codec_write_cache(codec, 0x14, 0,
17443 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17444 snd_hda_codec_write_cache(codec, 0x17, 0,
17445 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
17446 } else {
17447 snd_hda_codec_write_cache(codec, 0x14, 0,
17448 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17449 snd_hda_codec_write_cache(codec, 0x17, 0,
17450 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
17451 }
17452 }
17453
17454 static void alc663_m51va_unsol_event(struct hda_codec *codec,
17455 unsigned int res)
17456 {
17457 switch (res >> 26) {
17458 case ALC880_HP_EVENT:
17459 alc663_m51va_speaker_automute(codec);
17460 break;
17461 case ALC880_MIC_EVENT:
17462 alc_mic_automute(codec);
17463 break;
17464 }
17465 }
17466
17467 static void alc663_m51va_setup(struct hda_codec *codec)
17468 {
17469 struct alc_spec *spec = codec->spec;
17470 spec->ext_mic.pin = 0x18;
17471 spec->ext_mic.mux_idx = 0;
17472 spec->int_mic.pin = 0x12;
17473 spec->int_mic.mux_idx = 9;
17474 spec->auto_mic = 1;
17475 }
17476
17477 static void alc663_m51va_inithook(struct hda_codec *codec)
17478 {
17479 alc663_m51va_speaker_automute(codec);
17480 alc_mic_automute(codec);
17481 }
17482
17483 /* ***************** Mode1 ******************************/
17484 #define alc663_mode1_unsol_event alc663_m51va_unsol_event
17485
17486 static void alc663_mode1_setup(struct hda_codec *codec)
17487 {
17488 struct alc_spec *spec = codec->spec;
17489 spec->ext_mic.pin = 0x18;
17490 spec->ext_mic.mux_idx = 0;
17491 spec->int_mic.pin = 0x19;
17492 spec->int_mic.mux_idx = 1;
17493 spec->auto_mic = 1;
17494 }
17495
17496 #define alc663_mode1_inithook alc663_m51va_inithook
17497
17498 /* ***************** Mode2 ******************************/
17499 static void alc662_mode2_unsol_event(struct hda_codec *codec,
17500 unsigned int res)
17501 {
17502 switch (res >> 26) {
17503 case ALC880_HP_EVENT:
17504 alc662_f5z_speaker_automute(codec);
17505 break;
17506 case ALC880_MIC_EVENT:
17507 alc_mic_automute(codec);
17508 break;
17509 }
17510 }
17511
17512 #define alc662_mode2_setup alc663_mode1_setup
17513
17514 static void alc662_mode2_inithook(struct hda_codec *codec)
17515 {
17516 alc662_f5z_speaker_automute(codec);
17517 alc_mic_automute(codec);
17518 }
17519 /* ***************** Mode3 ******************************/
17520 static void alc663_mode3_unsol_event(struct hda_codec *codec,
17521 unsigned int res)
17522 {
17523 switch (res >> 26) {
17524 case ALC880_HP_EVENT:
17525 alc663_two_hp_m1_speaker_automute(codec);
17526 break;
17527 case ALC880_MIC_EVENT:
17528 alc_mic_automute(codec);
17529 break;
17530 }
17531 }
17532
17533 #define alc663_mode3_setup alc663_mode1_setup
17534
17535 static void alc663_mode3_inithook(struct hda_codec *codec)
17536 {
17537 alc663_two_hp_m1_speaker_automute(codec);
17538 alc_mic_automute(codec);
17539 }
17540 /* ***************** Mode4 ******************************/
17541 static void alc663_mode4_unsol_event(struct hda_codec *codec,
17542 unsigned int res)
17543 {
17544 switch (res >> 26) {
17545 case ALC880_HP_EVENT:
17546 alc663_21jd_two_speaker_automute(codec);
17547 break;
17548 case ALC880_MIC_EVENT:
17549 alc_mic_automute(codec);
17550 break;
17551 }
17552 }
17553
17554 #define alc663_mode4_setup alc663_mode1_setup
17555
17556 static void alc663_mode4_inithook(struct hda_codec *codec)
17557 {
17558 alc663_21jd_two_speaker_automute(codec);
17559 alc_mic_automute(codec);
17560 }
17561 /* ***************** Mode5 ******************************/
17562 static void alc663_mode5_unsol_event(struct hda_codec *codec,
17563 unsigned int res)
17564 {
17565 switch (res >> 26) {
17566 case ALC880_HP_EVENT:
17567 alc663_15jd_two_speaker_automute(codec);
17568 break;
17569 case ALC880_MIC_EVENT:
17570 alc_mic_automute(codec);
17571 break;
17572 }
17573 }
17574
17575 #define alc663_mode5_setup alc663_mode1_setup
17576
17577 static void alc663_mode5_inithook(struct hda_codec *codec)
17578 {
17579 alc663_15jd_two_speaker_automute(codec);
17580 alc_mic_automute(codec);
17581 }
17582 /* ***************** Mode6 ******************************/
17583 static void alc663_mode6_unsol_event(struct hda_codec *codec,
17584 unsigned int res)
17585 {
17586 switch (res >> 26) {
17587 case ALC880_HP_EVENT:
17588 alc663_two_hp_m2_speaker_automute(codec);
17589 break;
17590 case ALC880_MIC_EVENT:
17591 alc_mic_automute(codec);
17592 break;
17593 }
17594 }
17595
17596 #define alc663_mode6_setup alc663_mode1_setup
17597
17598 static void alc663_mode6_inithook(struct hda_codec *codec)
17599 {
17600 alc663_two_hp_m2_speaker_automute(codec);
17601 alc_mic_automute(codec);
17602 }
17603
17604 /* ***************** Mode7 ******************************/
17605 static void alc663_mode7_unsol_event(struct hda_codec *codec,
17606 unsigned int res)
17607 {
17608 switch (res >> 26) {
17609 case ALC880_HP_EVENT:
17610 alc663_two_hp_m7_speaker_automute(codec);
17611 break;
17612 case ALC880_MIC_EVENT:
17613 alc_mic_automute(codec);
17614 break;
17615 }
17616 }
17617
17618 #define alc663_mode7_setup alc663_mode1_setup
17619
17620 static void alc663_mode7_inithook(struct hda_codec *codec)
17621 {
17622 alc663_two_hp_m7_speaker_automute(codec);
17623 alc_mic_automute(codec);
17624 }
17625
17626 /* ***************** Mode8 ******************************/
17627 static void alc663_mode8_unsol_event(struct hda_codec *codec,
17628 unsigned int res)
17629 {
17630 switch (res >> 26) {
17631 case ALC880_HP_EVENT:
17632 alc663_two_hp_m8_speaker_automute(codec);
17633 break;
17634 case ALC880_MIC_EVENT:
17635 alc_mic_automute(codec);
17636 break;
17637 }
17638 }
17639
17640 #define alc663_mode8_setup alc663_m51va_setup
17641
17642 static void alc663_mode8_inithook(struct hda_codec *codec)
17643 {
17644 alc663_two_hp_m8_speaker_automute(codec);
17645 alc_mic_automute(codec);
17646 }
17647
17648 static void alc663_g71v_hp_automute(struct hda_codec *codec)
17649 {
17650 unsigned int present;
17651 unsigned char bits;
17652
17653 present = snd_hda_jack_detect(codec, 0x21);
17654 bits = present ? HDA_AMP_MUTE : 0;
17655 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
17656 HDA_AMP_MUTE, bits);
17657 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17658 HDA_AMP_MUTE, bits);
17659 }
17660
17661 static void alc663_g71v_front_automute(struct hda_codec *codec)
17662 {
17663 unsigned int present;
17664 unsigned char bits;
17665
17666 present = snd_hda_jack_detect(codec, 0x15);
17667 bits = present ? HDA_AMP_MUTE : 0;
17668 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
17669 HDA_AMP_MUTE, bits);
17670 }
17671
17672 static void alc663_g71v_unsol_event(struct hda_codec *codec,
17673 unsigned int res)
17674 {
17675 switch (res >> 26) {
17676 case ALC880_HP_EVENT:
17677 alc663_g71v_hp_automute(codec);
17678 break;
17679 case ALC880_FRONT_EVENT:
17680 alc663_g71v_front_automute(codec);
17681 break;
17682 case ALC880_MIC_EVENT:
17683 alc_mic_automute(codec);
17684 break;
17685 }
17686 }
17687
17688 #define alc663_g71v_setup alc663_m51va_setup
17689
17690 static void alc663_g71v_inithook(struct hda_codec *codec)
17691 {
17692 alc663_g71v_front_automute(codec);
17693 alc663_g71v_hp_automute(codec);
17694 alc_mic_automute(codec);
17695 }
17696
17697 static void alc663_g50v_unsol_event(struct hda_codec *codec,
17698 unsigned int res)
17699 {
17700 switch (res >> 26) {
17701 case ALC880_HP_EVENT:
17702 alc663_m51va_speaker_automute(codec);
17703 break;
17704 case ALC880_MIC_EVENT:
17705 alc_mic_automute(codec);
17706 break;
17707 }
17708 }
17709
17710 #define alc663_g50v_setup alc663_m51va_setup
17711
17712 static void alc663_g50v_inithook(struct hda_codec *codec)
17713 {
17714 alc663_m51va_speaker_automute(codec);
17715 alc_mic_automute(codec);
17716 }
17717
17718 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
17719 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17720 ALC262_HIPPO_MASTER_SWITCH,
17721
17722 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
17723 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17724 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17725
17726 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
17727 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17728 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17729 { } /* end */
17730 };
17731
17732 static struct snd_kcontrol_new alc272_nc10_mixer[] = {
17733 /* Master Playback automatically created from Speaker and Headphone */
17734 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17735 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17736 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17737 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17738
17739 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17740 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17741 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
17742
17743 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17744 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17745 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
17746 { } /* end */
17747 };
17748
17749 #ifdef CONFIG_SND_HDA_POWER_SAVE
17750 #define alc662_loopbacks alc880_loopbacks
17751 #endif
17752
17753
17754 /* pcm configuration: identical with ALC880 */
17755 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
17756 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
17757 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
17758 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
17759
17760 /*
17761 * configuration and preset
17762 */
17763 static const char *alc662_models[ALC662_MODEL_LAST] = {
17764 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17765 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17766 [ALC662_3ST_6ch] = "3stack-6ch",
17767 [ALC662_5ST_DIG] = "6stack-dig",
17768 [ALC662_LENOVO_101E] = "lenovo-101e",
17769 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17770 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17771 [ALC662_ECS] = "ecs",
17772 [ALC663_ASUS_M51VA] = "m51va",
17773 [ALC663_ASUS_G71V] = "g71v",
17774 [ALC663_ASUS_H13] = "h13",
17775 [ALC663_ASUS_G50V] = "g50v",
17776 [ALC663_ASUS_MODE1] = "asus-mode1",
17777 [ALC662_ASUS_MODE2] = "asus-mode2",
17778 [ALC663_ASUS_MODE3] = "asus-mode3",
17779 [ALC663_ASUS_MODE4] = "asus-mode4",
17780 [ALC663_ASUS_MODE5] = "asus-mode5",
17781 [ALC663_ASUS_MODE6] = "asus-mode6",
17782 [ALC663_ASUS_MODE7] = "asus-mode7",
17783 [ALC663_ASUS_MODE8] = "asus-mode8",
17784 [ALC272_DELL] = "dell",
17785 [ALC272_DELL_ZM1] = "dell-zm1",
17786 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17787 [ALC662_AUTO] = "auto",
17788 };
17789
17790 static struct snd_pci_quirk alc662_cfg_tbl[] = {
17791 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17792 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17793 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17794 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17795 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17796 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17797 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17798 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17799 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17800 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17801 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17802 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17803 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17804 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17805 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17806 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17807 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17808 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17809 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17810 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17811 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17812 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17813 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17814 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17815 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17816 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17817 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17818 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17819 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17820 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17821 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17822 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17823 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17824 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17825 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17826 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17827 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17828 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17829 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17830 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17831 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17832 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17833 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17834 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17835 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17836 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17837 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17838 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17839 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17840 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17841 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17842 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17843 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17844 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17845 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17846 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17847 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17848 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17849 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17850 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17851 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17852 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17853 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17854 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17855 ALC662_3ST_6ch_DIG),
17856 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17857 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17858 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17859 ALC662_3ST_6ch_DIG),
17860 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17861 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17862 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17863 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17864 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17865 ALC662_3ST_6ch_DIG),
17866 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17867 ALC663_ASUS_H13),
17868 SND_PCI_QUIRK(0x8086, 0xd604, "Intel mobo", ALC662_3ST_2ch_DIG),
17869 {}
17870 };
17871
17872 static struct alc_config_preset alc662_presets[] = {
17873 [ALC662_3ST_2ch_DIG] = {
17874 .mixers = { alc662_3ST_2ch_mixer },
17875 .init_verbs = { alc662_init_verbs },
17876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17877 .dac_nids = alc662_dac_nids,
17878 .dig_out_nid = ALC662_DIGOUT_NID,
17879 .dig_in_nid = ALC662_DIGIN_NID,
17880 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17881 .channel_mode = alc662_3ST_2ch_modes,
17882 .input_mux = &alc662_capture_source,
17883 },
17884 [ALC662_3ST_6ch_DIG] = {
17885 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17886 .init_verbs = { alc662_init_verbs },
17887 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17888 .dac_nids = alc662_dac_nids,
17889 .dig_out_nid = ALC662_DIGOUT_NID,
17890 .dig_in_nid = ALC662_DIGIN_NID,
17891 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17892 .channel_mode = alc662_3ST_6ch_modes,
17893 .need_dac_fix = 1,
17894 .input_mux = &alc662_capture_source,
17895 },
17896 [ALC662_3ST_6ch] = {
17897 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17898 .init_verbs = { alc662_init_verbs },
17899 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17900 .dac_nids = alc662_dac_nids,
17901 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17902 .channel_mode = alc662_3ST_6ch_modes,
17903 .need_dac_fix = 1,
17904 .input_mux = &alc662_capture_source,
17905 },
17906 [ALC662_5ST_DIG] = {
17907 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17908 .init_verbs = { alc662_init_verbs },
17909 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17910 .dac_nids = alc662_dac_nids,
17911 .dig_out_nid = ALC662_DIGOUT_NID,
17912 .dig_in_nid = ALC662_DIGIN_NID,
17913 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17914 .channel_mode = alc662_5stack_modes,
17915 .input_mux = &alc662_capture_source,
17916 },
17917 [ALC662_LENOVO_101E] = {
17918 .mixers = { alc662_lenovo_101e_mixer },
17919 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
17920 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17921 .dac_nids = alc662_dac_nids,
17922 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17923 .channel_mode = alc662_3ST_2ch_modes,
17924 .input_mux = &alc662_lenovo_101e_capture_source,
17925 .unsol_event = alc662_lenovo_101e_unsol_event,
17926 .init_hook = alc662_lenovo_101e_all_automute,
17927 },
17928 [ALC662_ASUS_EEEPC_P701] = {
17929 .mixers = { alc662_eeepc_p701_mixer },
17930 .init_verbs = { alc662_init_verbs,
17931 alc662_eeepc_sue_init_verbs },
17932 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17933 .dac_nids = alc662_dac_nids,
17934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17935 .channel_mode = alc662_3ST_2ch_modes,
17936 .unsol_event = alc662_eeepc_unsol_event,
17937 .setup = alc662_eeepc_setup,
17938 .init_hook = alc662_eeepc_inithook,
17939 },
17940 [ALC662_ASUS_EEEPC_EP20] = {
17941 .mixers = { alc662_eeepc_ep20_mixer,
17942 alc662_chmode_mixer },
17943 .init_verbs = { alc662_init_verbs,
17944 alc662_eeepc_ep20_sue_init_verbs },
17945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17946 .dac_nids = alc662_dac_nids,
17947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17948 .channel_mode = alc662_3ST_6ch_modes,
17949 .input_mux = &alc662_lenovo_101e_capture_source,
17950 .unsol_event = alc662_eeepc_unsol_event,
17951 .setup = alc662_eeepc_ep20_setup,
17952 .init_hook = alc662_eeepc_ep20_inithook,
17953 },
17954 [ALC662_ECS] = {
17955 .mixers = { alc662_ecs_mixer },
17956 .init_verbs = { alc662_init_verbs,
17957 alc662_ecs_init_verbs },
17958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17959 .dac_nids = alc662_dac_nids,
17960 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17961 .channel_mode = alc662_3ST_2ch_modes,
17962 .unsol_event = alc662_eeepc_unsol_event,
17963 .setup = alc662_eeepc_setup,
17964 .init_hook = alc662_eeepc_inithook,
17965 },
17966 [ALC663_ASUS_M51VA] = {
17967 .mixers = { alc663_m51va_mixer },
17968 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17969 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17970 .dac_nids = alc662_dac_nids,
17971 .dig_out_nid = ALC662_DIGOUT_NID,
17972 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17973 .channel_mode = alc662_3ST_2ch_modes,
17974 .unsol_event = alc663_m51va_unsol_event,
17975 .setup = alc663_m51va_setup,
17976 .init_hook = alc663_m51va_inithook,
17977 },
17978 [ALC663_ASUS_G71V] = {
17979 .mixers = { alc663_g71v_mixer },
17980 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
17981 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17982 .dac_nids = alc662_dac_nids,
17983 .dig_out_nid = ALC662_DIGOUT_NID,
17984 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17985 .channel_mode = alc662_3ST_2ch_modes,
17986 .unsol_event = alc663_g71v_unsol_event,
17987 .setup = alc663_g71v_setup,
17988 .init_hook = alc663_g71v_inithook,
17989 },
17990 [ALC663_ASUS_H13] = {
17991 .mixers = { alc663_m51va_mixer },
17992 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
17993 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17994 .dac_nids = alc662_dac_nids,
17995 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17996 .channel_mode = alc662_3ST_2ch_modes,
17997 .unsol_event = alc663_m51va_unsol_event,
17998 .init_hook = alc663_m51va_inithook,
17999 },
18000 [ALC663_ASUS_G50V] = {
18001 .mixers = { alc663_g50v_mixer },
18002 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
18003 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18004 .dac_nids = alc662_dac_nids,
18005 .dig_out_nid = ALC662_DIGOUT_NID,
18006 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18007 .channel_mode = alc662_3ST_6ch_modes,
18008 .input_mux = &alc663_capture_source,
18009 .unsol_event = alc663_g50v_unsol_event,
18010 .setup = alc663_g50v_setup,
18011 .init_hook = alc663_g50v_inithook,
18012 },
18013 [ALC663_ASUS_MODE1] = {
18014 .mixers = { alc663_m51va_mixer },
18015 .cap_mixer = alc662_auto_capture_mixer,
18016 .init_verbs = { alc662_init_verbs,
18017 alc663_21jd_amic_init_verbs },
18018 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18019 .hp_nid = 0x03,
18020 .dac_nids = alc662_dac_nids,
18021 .dig_out_nid = ALC662_DIGOUT_NID,
18022 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18023 .channel_mode = alc662_3ST_2ch_modes,
18024 .unsol_event = alc663_mode1_unsol_event,
18025 .setup = alc663_mode1_setup,
18026 .init_hook = alc663_mode1_inithook,
18027 },
18028 [ALC662_ASUS_MODE2] = {
18029 .mixers = { alc662_1bjd_mixer },
18030 .cap_mixer = alc662_auto_capture_mixer,
18031 .init_verbs = { alc662_init_verbs,
18032 alc662_1bjd_amic_init_verbs },
18033 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18034 .dac_nids = alc662_dac_nids,
18035 .dig_out_nid = ALC662_DIGOUT_NID,
18036 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18037 .channel_mode = alc662_3ST_2ch_modes,
18038 .unsol_event = alc662_mode2_unsol_event,
18039 .setup = alc662_mode2_setup,
18040 .init_hook = alc662_mode2_inithook,
18041 },
18042 [ALC663_ASUS_MODE3] = {
18043 .mixers = { alc663_two_hp_m1_mixer },
18044 .cap_mixer = alc662_auto_capture_mixer,
18045 .init_verbs = { alc662_init_verbs,
18046 alc663_two_hp_amic_m1_init_verbs },
18047 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18048 .hp_nid = 0x03,
18049 .dac_nids = alc662_dac_nids,
18050 .dig_out_nid = ALC662_DIGOUT_NID,
18051 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18052 .channel_mode = alc662_3ST_2ch_modes,
18053 .unsol_event = alc663_mode3_unsol_event,
18054 .setup = alc663_mode3_setup,
18055 .init_hook = alc663_mode3_inithook,
18056 },
18057 [ALC663_ASUS_MODE4] = {
18058 .mixers = { alc663_asus_21jd_clfe_mixer },
18059 .cap_mixer = alc662_auto_capture_mixer,
18060 .init_verbs = { alc662_init_verbs,
18061 alc663_21jd_amic_init_verbs},
18062 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18063 .hp_nid = 0x03,
18064 .dac_nids = alc662_dac_nids,
18065 .dig_out_nid = ALC662_DIGOUT_NID,
18066 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18067 .channel_mode = alc662_3ST_2ch_modes,
18068 .unsol_event = alc663_mode4_unsol_event,
18069 .setup = alc663_mode4_setup,
18070 .init_hook = alc663_mode4_inithook,
18071 },
18072 [ALC663_ASUS_MODE5] = {
18073 .mixers = { alc663_asus_15jd_clfe_mixer },
18074 .cap_mixer = alc662_auto_capture_mixer,
18075 .init_verbs = { alc662_init_verbs,
18076 alc663_15jd_amic_init_verbs },
18077 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18078 .hp_nid = 0x03,
18079 .dac_nids = alc662_dac_nids,
18080 .dig_out_nid = ALC662_DIGOUT_NID,
18081 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18082 .channel_mode = alc662_3ST_2ch_modes,
18083 .unsol_event = alc663_mode5_unsol_event,
18084 .setup = alc663_mode5_setup,
18085 .init_hook = alc663_mode5_inithook,
18086 },
18087 [ALC663_ASUS_MODE6] = {
18088 .mixers = { alc663_two_hp_m2_mixer },
18089 .cap_mixer = alc662_auto_capture_mixer,
18090 .init_verbs = { alc662_init_verbs,
18091 alc663_two_hp_amic_m2_init_verbs },
18092 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18093 .hp_nid = 0x03,
18094 .dac_nids = alc662_dac_nids,
18095 .dig_out_nid = ALC662_DIGOUT_NID,
18096 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18097 .channel_mode = alc662_3ST_2ch_modes,
18098 .unsol_event = alc663_mode6_unsol_event,
18099 .setup = alc663_mode6_setup,
18100 .init_hook = alc663_mode6_inithook,
18101 },
18102 [ALC663_ASUS_MODE7] = {
18103 .mixers = { alc663_mode7_mixer },
18104 .cap_mixer = alc662_auto_capture_mixer,
18105 .init_verbs = { alc662_init_verbs,
18106 alc663_mode7_init_verbs },
18107 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18108 .hp_nid = 0x03,
18109 .dac_nids = alc662_dac_nids,
18110 .dig_out_nid = ALC662_DIGOUT_NID,
18111 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18112 .channel_mode = alc662_3ST_2ch_modes,
18113 .unsol_event = alc663_mode7_unsol_event,
18114 .setup = alc663_mode7_setup,
18115 .init_hook = alc663_mode7_inithook,
18116 },
18117 [ALC663_ASUS_MODE8] = {
18118 .mixers = { alc663_mode8_mixer },
18119 .cap_mixer = alc662_auto_capture_mixer,
18120 .init_verbs = { alc662_init_verbs,
18121 alc663_mode8_init_verbs },
18122 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18123 .hp_nid = 0x03,
18124 .dac_nids = alc662_dac_nids,
18125 .dig_out_nid = ALC662_DIGOUT_NID,
18126 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18127 .channel_mode = alc662_3ST_2ch_modes,
18128 .unsol_event = alc663_mode8_unsol_event,
18129 .setup = alc663_mode8_setup,
18130 .init_hook = alc663_mode8_inithook,
18131 },
18132 [ALC272_DELL] = {
18133 .mixers = { alc663_m51va_mixer },
18134 .cap_mixer = alc272_auto_capture_mixer,
18135 .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs },
18136 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18137 .dac_nids = alc662_dac_nids,
18138 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18139 .adc_nids = alc272_adc_nids,
18140 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18141 .capsrc_nids = alc272_capsrc_nids,
18142 .channel_mode = alc662_3ST_2ch_modes,
18143 .unsol_event = alc663_m51va_unsol_event,
18144 .setup = alc663_m51va_setup,
18145 .init_hook = alc663_m51va_inithook,
18146 },
18147 [ALC272_DELL_ZM1] = {
18148 .mixers = { alc663_m51va_mixer },
18149 .cap_mixer = alc662_auto_capture_mixer,
18150 .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs },
18151 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18152 .dac_nids = alc662_dac_nids,
18153 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18154 .adc_nids = alc662_adc_nids,
18155 .num_adc_nids = 1,
18156 .capsrc_nids = alc662_capsrc_nids,
18157 .channel_mode = alc662_3ST_2ch_modes,
18158 .unsol_event = alc663_m51va_unsol_event,
18159 .setup = alc663_m51va_setup,
18160 .init_hook = alc663_m51va_inithook,
18161 },
18162 [ALC272_SAMSUNG_NC10] = {
18163 .mixers = { alc272_nc10_mixer },
18164 .init_verbs = { alc662_init_verbs,
18165 alc663_21jd_amic_init_verbs },
18166 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18167 .dac_nids = alc272_dac_nids,
18168 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18169 .channel_mode = alc662_3ST_2ch_modes,
18170 /*.input_mux = &alc272_nc10_capture_source,*/
18171 .unsol_event = alc663_mode4_unsol_event,
18172 .setup = alc663_mode4_setup,
18173 .init_hook = alc663_mode4_inithook,
18174 },
18175 };
18176
18177
18178 /*
18179 * BIOS auto configuration
18180 */
18181
18182 /* convert from MIX nid to DAC */
18183 static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid)
18184 {
18185 if (nid == 0x0f)
18186 return 0x02;
18187 else if (nid >= 0x0c && nid <= 0x0e)
18188 return nid - 0x0c + 0x02;
18189 else
18190 return 0;
18191 }
18192
18193 /* get MIX nid connected to the given pin targeted to DAC */
18194 static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18195 hda_nid_t dac)
18196 {
18197 hda_nid_t mix[4];
18198 int i, num;
18199
18200 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18201 for (i = 0; i < num; i++) {
18202 if (alc662_mix_to_dac(mix[i]) == dac)
18203 return mix[i];
18204 }
18205 return 0;
18206 }
18207
18208 /* look for an empty DAC slot */
18209 static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18210 {
18211 struct alc_spec *spec = codec->spec;
18212 hda_nid_t srcs[5];
18213 int i, j, num;
18214
18215 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18216 if (num < 0)
18217 return 0;
18218 for (i = 0; i < num; i++) {
18219 hda_nid_t nid = alc662_mix_to_dac(srcs[i]);
18220 if (!nid)
18221 continue;
18222 for (j = 0; j < spec->multiout.num_dacs; j++)
18223 if (spec->multiout.dac_nids[j] == nid)
18224 break;
18225 if (j >= spec->multiout.num_dacs)
18226 return nid;
18227 }
18228 return 0;
18229 }
18230
18231 /* fill in the dac_nids table from the parsed pin configuration */
18232 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18233 const struct auto_pin_cfg *cfg)
18234 {
18235 struct alc_spec *spec = codec->spec;
18236 int i;
18237 hda_nid_t dac;
18238
18239 spec->multiout.dac_nids = spec->private_dac_nids;
18240 for (i = 0; i < cfg->line_outs; i++) {
18241 dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]);
18242 if (!dac)
18243 continue;
18244 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
18245 }
18246 return 0;
18247 }
18248
18249 static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18250 hda_nid_t nid, unsigned int chs)
18251 {
18252 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
18253 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18254 }
18255
18256 static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18257 hda_nid_t nid, unsigned int chs)
18258 {
18259 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18260 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18261 }
18262
18263 #define alc662_add_stereo_vol(spec, pfx, nid) \
18264 alc662_add_vol_ctl(spec, pfx, nid, 3)
18265 #define alc662_add_stereo_sw(spec, pfx, nid) \
18266 alc662_add_sw_ctl(spec, pfx, nid, 3)
18267
18268 /* add playback controls from the parsed DAC table */
18269 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
18270 const struct auto_pin_cfg *cfg)
18271 {
18272 struct alc_spec *spec = codec->spec;
18273 static const char *chname[4] = {
18274 "Front", "Surround", NULL /*CLFE*/, "Side"
18275 };
18276 hda_nid_t nid, mix;
18277 int i, err;
18278
18279 for (i = 0; i < cfg->line_outs; i++) {
18280 nid = spec->multiout.dac_nids[i];
18281 if (!nid)
18282 continue;
18283 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
18284 if (!mix)
18285 continue;
18286 if (i == 2) {
18287 /* Center/LFE */
18288 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
18289 if (err < 0)
18290 return err;
18291 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
18292 if (err < 0)
18293 return err;
18294 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
18295 if (err < 0)
18296 return err;
18297 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
18298 if (err < 0)
18299 return err;
18300 } else {
18301 const char *pfx;
18302 if (cfg->line_outs == 1 &&
18303 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
18304 if (cfg->hp_outs)
18305 pfx = "Speaker";
18306 else
18307 pfx = "PCM";
18308 } else
18309 pfx = chname[i];
18310 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18311 if (err < 0)
18312 return err;
18313 if (cfg->line_outs == 1 &&
18314 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18315 pfx = "Speaker";
18316 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18317 if (err < 0)
18318 return err;
18319 }
18320 }
18321 return 0;
18322 }
18323
18324 /* add playback controls for speaker and HP outputs */
18325 /* return DAC nid if any new DAC is assigned */
18326 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18327 const char *pfx)
18328 {
18329 struct alc_spec *spec = codec->spec;
18330 hda_nid_t nid, mix;
18331 int err;
18332
18333 if (!pin)
18334 return 0;
18335 nid = alc662_look_for_dac(codec, pin);
18336 if (!nid) {
18337 /* the corresponding DAC is already occupied */
18338 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18339 return 0; /* no way */
18340 /* create a switch only */
18341 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18342 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18343 }
18344
18345 mix = alc662_dac_to_mix(codec, pin, nid);
18346 if (!mix)
18347 return 0;
18348 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
18349 if (err < 0)
18350 return err;
18351 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18352 if (err < 0)
18353 return err;
18354 return nid;
18355 }
18356
18357 /* create playback/capture controls for input pins */
18358 #define alc662_auto_create_input_ctls \
18359 alc882_auto_create_input_ctls
18360
18361 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18362 hda_nid_t nid, int pin_type,
18363 hda_nid_t dac)
18364 {
18365 int i, num;
18366 hda_nid_t srcs[4];
18367
18368 alc_set_pin_output(codec, nid, pin_type);
18369 /* need the manual connection? */
18370 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18371 if (num <= 1)
18372 return;
18373 for (i = 0; i < num; i++) {
18374 if (alc662_mix_to_dac(srcs[i]) != dac)
18375 continue;
18376 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18377 return;
18378 }
18379 }
18380
18381 static void alc662_auto_init_multi_out(struct hda_codec *codec)
18382 {
18383 struct alc_spec *spec = codec->spec;
18384 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18385 int i;
18386
18387 for (i = 0; i <= HDA_SIDE; i++) {
18388 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18389 if (nid)
18390 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
18391 spec->multiout.dac_nids[i]);
18392 }
18393 }
18394
18395 static void alc662_auto_init_hp_out(struct hda_codec *codec)
18396 {
18397 struct alc_spec *spec = codec->spec;
18398 hda_nid_t pin;
18399
18400 pin = spec->autocfg.hp_pins[0];
18401 if (pin)
18402 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
18403 spec->multiout.hp_nid);
18404 pin = spec->autocfg.speaker_pins[0];
18405 if (pin)
18406 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18407 spec->multiout.extra_out_nid[0]);
18408 }
18409
18410 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
18411
18412 static void alc662_auto_init_analog_input(struct hda_codec *codec)
18413 {
18414 struct alc_spec *spec = codec->spec;
18415 int i;
18416
18417 for (i = 0; i < AUTO_PIN_LAST; i++) {
18418 hda_nid_t nid = spec->autocfg.input_pins[i];
18419 if (alc_is_input_pin(codec, nid)) {
18420 alc_set_input_pin(codec, nid, i);
18421 if (nid != ALC662_PIN_CD_NID &&
18422 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
18423 snd_hda_codec_write(codec, nid, 0,
18424 AC_VERB_SET_AMP_GAIN_MUTE,
18425 AMP_OUT_MUTE);
18426 }
18427 }
18428 }
18429
18430 #define alc662_auto_init_input_src alc882_auto_init_input_src
18431
18432 static int alc662_parse_auto_config(struct hda_codec *codec)
18433 {
18434 struct alc_spec *spec = codec->spec;
18435 int err;
18436 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
18437
18438 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18439 alc662_ignore);
18440 if (err < 0)
18441 return err;
18442 if (!spec->autocfg.line_outs)
18443 return 0; /* can't find valid BIOS pin config */
18444
18445 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
18446 if (err < 0)
18447 return err;
18448 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
18449 if (err < 0)
18450 return err;
18451 err = alc662_auto_create_extra_out(codec,
18452 spec->autocfg.speaker_pins[0],
18453 "Speaker");
18454 if (err < 0)
18455 return err;
18456 if (err)
18457 spec->multiout.extra_out_nid[0] = err;
18458 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18459 "Headphone");
18460 if (err < 0)
18461 return err;
18462 if (err)
18463 spec->multiout.hp_nid = err;
18464 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
18465 if (err < 0)
18466 return err;
18467
18468 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18469
18470 if (spec->autocfg.dig_outs)
18471 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
18472
18473 if (spec->kctls.list)
18474 add_mixer(spec, spec->kctls.list);
18475
18476 spec->num_mux_defs = 1;
18477 spec->input_mux = &spec->private_imux[0];
18478
18479 add_verb(spec, alc662_init_verbs);
18480 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18481 codec->vendor_id == 0x10ec0665)
18482 add_verb(spec, alc663_init_verbs);
18483
18484 if (codec->vendor_id == 0x10ec0272)
18485 add_verb(spec, alc272_init_verbs);
18486
18487 err = alc_auto_add_mic_boost(codec);
18488 if (err < 0)
18489 return err;
18490
18491 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18492 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18493 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18494 else
18495 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18496
18497 return 1;
18498 }
18499
18500 /* additional initialization for auto-configuration model */
18501 static void alc662_auto_init(struct hda_codec *codec)
18502 {
18503 struct alc_spec *spec = codec->spec;
18504 alc662_auto_init_multi_out(codec);
18505 alc662_auto_init_hp_out(codec);
18506 alc662_auto_init_analog_input(codec);
18507 alc662_auto_init_input_src(codec);
18508 if (spec->unsol_event)
18509 alc_inithook(codec);
18510 }
18511
18512 static int patch_alc662(struct hda_codec *codec)
18513 {
18514 struct alc_spec *spec;
18515 int err, board_config;
18516
18517 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18518 if (!spec)
18519 return -ENOMEM;
18520
18521 codec->spec = spec;
18522
18523 alc_auto_parse_customize_define(codec);
18524
18525 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18526
18527 if (alc_read_coef_idx(codec, 0) == 0x8020)
18528 alc_codec_rename(codec, "ALC661");
18529 else if ((alc_read_coef_idx(codec, 0) & (1 << 14)) &&
18530 codec->bus->pci->subsystem_vendor == 0x1025 &&
18531 spec->cdefine.platform_type == 1)
18532 alc_codec_rename(codec, "ALC272X");
18533
18534 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18535 alc662_models,
18536 alc662_cfg_tbl);
18537 if (board_config < 0) {
18538 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18539 codec->chip_name);
18540 board_config = ALC662_AUTO;
18541 }
18542
18543 if (board_config == ALC662_AUTO) {
18544 /* automatic parse from the BIOS config */
18545 err = alc662_parse_auto_config(codec);
18546 if (err < 0) {
18547 alc_free(codec);
18548 return err;
18549 } else if (!err) {
18550 printk(KERN_INFO
18551 "hda_codec: Cannot set up configuration "
18552 "from BIOS. Using base mode...\n");
18553 board_config = ALC662_3ST_2ch_DIG;
18554 }
18555 }
18556
18557 err = snd_hda_attach_beep_device(codec, 0x1);
18558 if (err < 0) {
18559 alc_free(codec);
18560 return err;
18561 }
18562
18563 if (board_config != ALC662_AUTO)
18564 setup_preset(codec, &alc662_presets[board_config]);
18565
18566 spec->stream_analog_playback = &alc662_pcm_analog_playback;
18567 spec->stream_analog_capture = &alc662_pcm_analog_capture;
18568
18569 spec->stream_digital_playback = &alc662_pcm_digital_playback;
18570 spec->stream_digital_capture = &alc662_pcm_digital_capture;
18571
18572 if (!spec->adc_nids) {
18573 spec->adc_nids = alc662_adc_nids;
18574 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
18575 }
18576 if (!spec->capsrc_nids)
18577 spec->capsrc_nids = alc662_capsrc_nids;
18578
18579 if (!spec->cap_mixer)
18580 set_capture_mixer(codec);
18581
18582 if (spec->cdefine.enable_pcbeep) {
18583 switch (codec->vendor_id) {
18584 case 0x10ec0662:
18585 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18586 break;
18587 case 0x10ec0272:
18588 case 0x10ec0663:
18589 case 0x10ec0665:
18590 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18591 break;
18592 case 0x10ec0273:
18593 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18594 break;
18595 }
18596 }
18597 spec->vmaster_nid = 0x02;
18598
18599 codec->patch_ops = alc_patch_ops;
18600 if (board_config == ALC662_AUTO)
18601 spec->init_hook = alc662_auto_init;
18602 #ifdef CONFIG_SND_HDA_POWER_SAVE
18603 if (!spec->loopback.amplist)
18604 spec->loopback.amplist = alc662_loopbacks;
18605 #endif
18606
18607 return 0;
18608 }
18609
18610 static int patch_alc888(struct hda_codec *codec)
18611 {
18612 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18613 kfree(codec->chip_name);
18614 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
18615 if (!codec->chip_name) {
18616 alc_free(codec);
18617 return -ENOMEM;
18618 }
18619 return patch_alc662(codec);
18620 }
18621 return patch_alc882(codec);
18622 }
18623
18624 /*
18625 * patch entries
18626 */
18627 static struct hda_codec_preset snd_hda_preset_realtek[] = {
18628 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
18629 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
18630 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
18631 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
18632 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
18633 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
18634 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
18635 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
18636 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
18637 .patch = patch_alc861 },
18638 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
18639 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
18640 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
18641 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
18642 .patch = patch_alc882 },
18643 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18644 .patch = patch_alc662 },
18645 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18646 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18647 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18648 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18649 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18650 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
18651 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
18652 .patch = patch_alc882 },
18653 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
18654 .patch = patch_alc882 },
18655 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
18656 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
18657 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
18658 .patch = patch_alc882 },
18659 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
18660 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
18661 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
18662 {} /* terminator */
18663 };
18664
18665 MODULE_ALIAS("snd-hda-codec-id:10ec*");
18666
18667 MODULE_LICENSE("GPL");
18668 MODULE_DESCRIPTION("Realtek HD-audio codec");
18669
18670 static struct hda_codec_preset_list realtek_list = {
18671 .preset = snd_hda_preset_realtek,
18672 .owner = THIS_MODULE,
18673 };
18674
18675 static int __init patch_realtek_init(void)
18676 {
18677 return snd_hda_add_codec_preset(&realtek_list);
18678 }
18679
18680 static void __exit patch_realtek_exit(void)
18681 {
18682 snd_hda_delete_codec_preset(&realtek_list);
18683 }
18684
18685 module_init(patch_realtek_init)
18686 module_exit(patch_realtek_exit)
This page took 0.434079 seconds and 5 git commands to generate.